From 501942b89dbb93aca16f149b2036589fdc69bcbd Mon Sep 17 00:00:00 2001 From: kraktus Date: Sat, 25 Jan 2025 22:54:06 +0100 Subject: [PATCH 01/28] Initial commit: Add dataclass_csv2 fork --- README.md | 6 +++--- {dataclass_csv => dataclass_csv2}/__init__.py | 0 {dataclass_csv => dataclass_csv2}/__init__.pyi | 0 {dataclass_csv => dataclass_csv2}/dataclass_reader.py | 0 {dataclass_csv => dataclass_csv2}/dataclass_reader.pyi | 0 {dataclass_csv => dataclass_csv2}/dataclass_writer.py | 0 {dataclass_csv => dataclass_csv2}/dataclass_writer.pyi | 0 {dataclass_csv => dataclass_csv2}/decorators.py | 0 {dataclass_csv => dataclass_csv2}/decorators.pyi | 0 {dataclass_csv => dataclass_csv2}/exceptions.py | 0 {dataclass_csv => dataclass_csv2}/exceptions.pyi | 0 {dataclass_csv => dataclass_csv2}/field_mapper.py | 0 {dataclass_csv => dataclass_csv2}/field_mapper.pyi | 0 {dataclass_csv => dataclass_csv2}/header_mapper.py | 0 {dataclass_csv => dataclass_csv2}/header_mapper.pyi | 0 {dataclass_csv => dataclass_csv2}/py.typed | 0 16 files changed, 3 insertions(+), 3 deletions(-) rename {dataclass_csv => dataclass_csv2}/__init__.py (100%) rename {dataclass_csv => dataclass_csv2}/__init__.pyi (100%) rename {dataclass_csv => dataclass_csv2}/dataclass_reader.py (100%) rename {dataclass_csv => dataclass_csv2}/dataclass_reader.pyi (100%) rename {dataclass_csv => dataclass_csv2}/dataclass_writer.py (100%) rename {dataclass_csv => dataclass_csv2}/dataclass_writer.pyi (100%) rename {dataclass_csv => dataclass_csv2}/decorators.py (100%) rename {dataclass_csv => dataclass_csv2}/decorators.pyi (100%) rename {dataclass_csv => dataclass_csv2}/exceptions.py (100%) rename {dataclass_csv => dataclass_csv2}/exceptions.pyi (100%) rename {dataclass_csv => dataclass_csv2}/field_mapper.py (100%) rename {dataclass_csv => dataclass_csv2}/field_mapper.pyi (100%) rename {dataclass_csv => dataclass_csv2}/header_mapper.py (100%) rename {dataclass_csv => dataclass_csv2}/header_mapper.pyi (100%) rename {dataclass_csv => dataclass_csv2}/py.typed (100%) diff --git a/README.md b/README.md index aa06511..0d12946 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ -# Dataclass CSV +# Dataclass CSV 2 -Dataclass CSV makes working with CSV files easier and much better than working with Dicts. It uses Python's Dataclasses to store data of every row on the CSV file and also uses type annotations which enables proper type checking and validation. +Dataclass CSV 2 is a fork of [dataclass-csv](https://github.com/dfurtado/dataclass-csv) with downstream bug fixes that makes working with CSV files easier and much better than working with Dicts. It uses Python's Dataclasses to store data of every row on the CSV file and also uses type annotations which enables proper type checking and validation. ## Main features @@ -26,7 +26,7 @@ using a list of instances of a dataclass. ## Installation ```shell -pipenv install dataclass-csv +pip install dataclass-csv2 ``` ## Getting started diff --git a/dataclass_csv/__init__.py b/dataclass_csv2/__init__.py similarity index 100% rename from dataclass_csv/__init__.py rename to dataclass_csv2/__init__.py diff --git a/dataclass_csv/__init__.pyi b/dataclass_csv2/__init__.pyi similarity index 100% rename from dataclass_csv/__init__.pyi rename to dataclass_csv2/__init__.pyi diff --git a/dataclass_csv/dataclass_reader.py b/dataclass_csv2/dataclass_reader.py similarity index 100% rename from dataclass_csv/dataclass_reader.py rename to dataclass_csv2/dataclass_reader.py diff --git a/dataclass_csv/dataclass_reader.pyi b/dataclass_csv2/dataclass_reader.pyi similarity index 100% rename from dataclass_csv/dataclass_reader.pyi rename to dataclass_csv2/dataclass_reader.pyi diff --git a/dataclass_csv/dataclass_writer.py b/dataclass_csv2/dataclass_writer.py similarity index 100% rename from dataclass_csv/dataclass_writer.py rename to dataclass_csv2/dataclass_writer.py diff --git a/dataclass_csv/dataclass_writer.pyi b/dataclass_csv2/dataclass_writer.pyi similarity index 100% rename from dataclass_csv/dataclass_writer.pyi rename to dataclass_csv2/dataclass_writer.pyi diff --git a/dataclass_csv/decorators.py b/dataclass_csv2/decorators.py similarity index 100% rename from dataclass_csv/decorators.py rename to dataclass_csv2/decorators.py diff --git a/dataclass_csv/decorators.pyi b/dataclass_csv2/decorators.pyi similarity index 100% rename from dataclass_csv/decorators.pyi rename to dataclass_csv2/decorators.pyi diff --git a/dataclass_csv/exceptions.py b/dataclass_csv2/exceptions.py similarity index 100% rename from dataclass_csv/exceptions.py rename to dataclass_csv2/exceptions.py diff --git a/dataclass_csv/exceptions.pyi b/dataclass_csv2/exceptions.pyi similarity index 100% rename from dataclass_csv/exceptions.pyi rename to dataclass_csv2/exceptions.pyi diff --git a/dataclass_csv/field_mapper.py b/dataclass_csv2/field_mapper.py similarity index 100% rename from dataclass_csv/field_mapper.py rename to dataclass_csv2/field_mapper.py diff --git a/dataclass_csv/field_mapper.pyi b/dataclass_csv2/field_mapper.pyi similarity index 100% rename from dataclass_csv/field_mapper.pyi rename to dataclass_csv2/field_mapper.pyi diff --git a/dataclass_csv/header_mapper.py b/dataclass_csv2/header_mapper.py similarity index 100% rename from dataclass_csv/header_mapper.py rename to dataclass_csv2/header_mapper.py diff --git a/dataclass_csv/header_mapper.pyi b/dataclass_csv2/header_mapper.pyi similarity index 100% rename from dataclass_csv/header_mapper.pyi rename to dataclass_csv2/header_mapper.pyi diff --git a/dataclass_csv/py.typed b/dataclass_csv2/py.typed similarity index 100% rename from dataclass_csv/py.typed rename to dataclass_csv2/py.typed From 228fb65908c855d71e1820512a2cb47364fce690 Mon Sep 17 00:00:00 2001 From: kraktus Date: Sat, 25 Jan 2025 22:59:46 +0100 Subject: [PATCH 02/28] Remove stub files, should not longer be necessary as files are typed --- dataclass_csv2/__init__.pyi | 7 ------- dataclass_csv2/dataclass_reader.pyi | 18 ------------------ dataclass_csv2/dataclass_writer.pyi | 14 -------------- dataclass_csv2/decorators.pyi | 6 ------ dataclass_csv2/exceptions.pyi | 6 ------ dataclass_csv2/field_mapper.pyi | 5 ----- dataclass_csv2/header_mapper.pyi | 5 ----- dataclass_csv2/py.typed | 0 8 files changed, 61 deletions(-) delete mode 100644 dataclass_csv2/__init__.pyi delete mode 100644 dataclass_csv2/dataclass_reader.pyi delete mode 100644 dataclass_csv2/dataclass_writer.pyi delete mode 100644 dataclass_csv2/decorators.pyi delete mode 100644 dataclass_csv2/exceptions.pyi delete mode 100644 dataclass_csv2/field_mapper.pyi delete mode 100644 dataclass_csv2/header_mapper.pyi delete mode 100644 dataclass_csv2/py.typed diff --git a/dataclass_csv2/__init__.pyi b/dataclass_csv2/__init__.pyi deleted file mode 100644 index 973174a..0000000 --- a/dataclass_csv2/__init__.pyi +++ /dev/null @@ -1,7 +0,0 @@ -from .dataclass_reader import DataclassReader as DataclassReader -from .dataclass_writer import DataclassWriter as DataclassWriter -from .decorators import ( - accept_whitespaces as accept_whitespaces, - dateformat as dateformat, -) -from .exceptions import CsvValueError as CsvValueError diff --git a/dataclass_csv2/dataclass_reader.pyi b/dataclass_csv2/dataclass_reader.pyi deleted file mode 100644 index 155bd11..0000000 --- a/dataclass_csv2/dataclass_reader.pyi +++ /dev/null @@ -1,18 +0,0 @@ -from .field_mapper import FieldMapper as FieldMapper -from typing import Any, Optional, Sequence, Type - -class DataclassReader: - def __init__( - self, - f: Any, - cls: Type[object], - fieldnames: Optional[Sequence[str]] = ..., - restkey: Optional[str] = ..., - restval: Optional[Any] = ..., - dialect: str = ..., - *args: Any, - **kwds: Any - ) -> None: ... - def __next__(self) -> None: ... - def __iter__(self) -> Any: ... - def map(self, csv_fieldname: str) -> FieldMapper: ... diff --git a/dataclass_csv2/dataclass_writer.pyi b/dataclass_csv2/dataclass_writer.pyi deleted file mode 100644 index 9c0d76f..0000000 --- a/dataclass_csv2/dataclass_writer.pyi +++ /dev/null @@ -1,14 +0,0 @@ -from .header_mapper import HeaderMapper as HeaderMapper -from typing import Any, Dict, List, Type - -class DataclassWriter: - def __init__( - self, - f: Any, - data: List[Any], - cls: Type[object], - dialect: str = ..., - **fmtparams: Dict[str, Any], - ) -> None: ... - def write(self, skip_header: bool = ...) -> Any: ... - def map(self, propname: str) -> HeaderMapper: ... diff --git a/dataclass_csv2/decorators.pyi b/dataclass_csv2/decorators.pyi deleted file mode 100644 index 3f0a372..0000000 --- a/dataclass_csv2/decorators.pyi +++ /dev/null @@ -1,6 +0,0 @@ -from typing import Any, Callable, Type, TypeVar - -F = TypeVar("F", bound=Callable[..., Any]) - -def dateformat(date_format: str) -> Callable[[F], F]: ... -def accept_whitespaces(_cls: Type[Any] = ...) -> Callable[[F], F]: ... diff --git a/dataclass_csv2/exceptions.pyi b/dataclass_csv2/exceptions.pyi deleted file mode 100644 index 7040a34..0000000 --- a/dataclass_csv2/exceptions.pyi +++ /dev/null @@ -1,6 +0,0 @@ -from typing import Any - -class CsvValueError(Exception): - error: Any = ... - line_number: Any = ... - def __init__(self, error: Any, line_number: int) -> None: ... diff --git a/dataclass_csv2/field_mapper.pyi b/dataclass_csv2/field_mapper.pyi deleted file mode 100644 index 66a04a9..0000000 --- a/dataclass_csv2/field_mapper.pyi +++ /dev/null @@ -1,5 +0,0 @@ -from typing import Any, Callable - -class FieldMapper: - to: Any = ... - def __init__(self, callback: Callable[[str], None]) -> None: ... diff --git a/dataclass_csv2/header_mapper.pyi b/dataclass_csv2/header_mapper.pyi deleted file mode 100644 index c2cc1b3..0000000 --- a/dataclass_csv2/header_mapper.pyi +++ /dev/null @@ -1,5 +0,0 @@ -from typing import Any, Callable - -class HeaderMapper: - to: Any = ... - def __init__(self, callback: Callable[[str], None]) -> None: ... diff --git a/dataclass_csv2/py.typed b/dataclass_csv2/py.typed deleted file mode 100644 index e69de29..0000000 From 2ea9ae0d7d086d85ced1cb722d315040089a31ab Mon Sep 17 00:00:00 2001 From: kraktus Date: Sat, 25 Jan 2025 23:09:05 +0100 Subject: [PATCH 03/28] build: Add pyproject.toml with project configuration and dev dependencies --- pyproject.toml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..a91ad78 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,13 @@ +[project] +name = "dataclass-csv2" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.13" +dependencies = [] + +[dependency-groups] +dev = [ + "pyright>=1.1.392.post0", + "pytest>=8.3.4", +] From faa39cbc4112391b214620635373787fe47b8ce4 Mon Sep 17 00:00:00 2001 From: "kraktus (aider)" Date: Sat, 25 Jan 2025 23:09:06 +0100 Subject: [PATCH 04/28] refactor: Migrate setup.py configuration to uv-compatible pyproject.toml --- pyproject.toml | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index a91ad78..349f30e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,3 +11,45 @@ dev = [ "pyright>=1.1.392.post0", "pytest>=8.3.4", ] +[project] +name = "dataclass-csv" +version = "1.4.0" +description = "Map CSV data into dataclasses" +authors = [ + {name = "Daniel Furtado", email = "daniel@dfurtado.com"}, +] +dependencies = [] +requires-python = ">=3.7" +readme = "README.md" +license = {text = "BSD license"} +keywords = ["dataclass", "dataclasses", "csv", "dataclass-csv"] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "License :: OSI Approved :: BSD License", + "Natural Language :: English", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.7", + "Operating System :: Microsoft :: Windows", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Unix", + "Operating System :: POSIX", + "Environment :: Console", +] + +[project.urls] +Homepage = "https://github.com/dfurtado/dataclass-csv" + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build] +include = [ + "dataclass_csv/**/*.py", + "dataclass_csv/**/*.pyi", + "dataclass_csv/py.typed", +] + +[tool.pytest.ini_options] +testpaths = ["tests"] From 15575beda98fd216eedd794fc1168a4c0de9149b Mon Sep 17 00:00:00 2001 From: "kraktus (aider)" Date: Sat, 25 Jan 2025 23:09:27 +0100 Subject: [PATCH 05/28] refactor: Remove duplicate project section and setup.py --- pyproject.toml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 349f30e..a49618b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,11 +1,3 @@ -[project] -name = "dataclass-csv2" -version = "0.1.0" -description = "Add your description here" -readme = "README.md" -requires-python = ">=3.13" -dependencies = [] - [dependency-groups] dev = [ "pyright>=1.1.392.post0", From 4eee06fa81d5828f6d544d11ea9ce931ae3751b7 Mon Sep 17 00:00:00 2001 From: kraktus Date: Sat, 25 Jan 2025 23:16:44 +0100 Subject: [PATCH 06/28] wip continue merging pyproject.toml from old setup.py --- .gitignore | 42 ++++---- .python-version | 1 + Pipfile | 14 --- Pipfile.lock | 194 ----------------------------------- hello.py | 6 ++ pyproject.toml | 39 +++---- uv.lock | 268 ++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 311 insertions(+), 253 deletions(-) create mode 100644 .python-version delete mode 100644 Pipfile delete mode 100644 Pipfile.lock create mode 100644 hello.py create mode 100644 uv.lock diff --git a/.gitignore b/.gitignore index bc8e7d8..0a57ec5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,21 +1,21 @@ -__pycache__ -*.pyc -.idea -env/ -*.swo -*.swp -*.*~ -*.egg -*.egg-info -.#*.* -TAGS -docs -.mypy_cache -.pytest_cache -build -dist -.eggs -.vscode -gmon.out -.vim -pyproject.toml +__pycache__ +*.pyc +.idea +env/ +*.swo +*.swp +*.*~ +*.egg +*.egg-info +.#*.* +TAGS +docs +.mypy_cache +.pytest_cache +build +dist +.eggs +.vscode +gmon.out +.vim +.aider* diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..24ee5b1 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.13 diff --git a/Pipfile b/Pipfile deleted file mode 100644 index a8e5493..0000000 --- a/Pipfile +++ /dev/null @@ -1,14 +0,0 @@ -[[source]] -url = "https://pypi.org/simple" -verify_ssl = true -name = "pypi" - -[dev-packages] -pytest = "*" -mypy = "*" -flake8 = "*" - -[packages] - -[requires] -python_version = "3.7" diff --git a/Pipfile.lock b/Pipfile.lock deleted file mode 100644 index 602f200..0000000 --- a/Pipfile.lock +++ /dev/null @@ -1,194 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "ff9642fcfefdd196731283041b11231f54200352dd42071a89fc5dbe84ce128b" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.7" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": {}, - "develop": { - "attrs": { - "hashes": [ - "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", - "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.3.0" - }, - "flake8": { - "hashes": [ - "sha256:12d05ab02614b6aee8df7c36b97d1a3b2372761222b19b58621355e82acddcff", - "sha256:78873e372b12b093da7b5e5ed302e8ad9e988b38b063b61ad937f26ca58fc5f0" - ], - "index": "pypi", - "version": "==3.9.0" - }, - "iniconfig": { - "hashes": [ - "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", - "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32" - ], - "version": "==1.1.1" - }, - "mccabe": { - "hashes": [ - "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", - "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" - ], - "version": "==0.6.1" - }, - "mypy": { - "hashes": [ - "sha256:0d0a87c0e7e3a9becdfbe936c981d32e5ee0ccda3e0f07e1ef2c3d1a817cf73e", - "sha256:25adde9b862f8f9aac9d2d11971f226bd4c8fbaa89fb76bdadb267ef22d10064", - "sha256:28fb5479c494b1bab244620685e2eb3c3f988d71fd5d64cc753195e8ed53df7c", - "sha256:2f9b3407c58347a452fc0736861593e105139b905cca7d097e413453a1d650b4", - "sha256:33f159443db0829d16f0a8d83d94df3109bb6dd801975fe86bacb9bf71628e97", - "sha256:3f2aca7f68580dc2508289c729bd49ee929a436208d2b2b6aab15745a70a57df", - "sha256:499c798053cdebcaa916eef8cd733e5584b5909f789de856b482cd7d069bdad8", - "sha256:4eec37370483331d13514c3f55f446fc5248d6373e7029a29ecb7b7494851e7a", - "sha256:552a815579aa1e995f39fd05dde6cd378e191b063f031f2acfe73ce9fb7f9e56", - "sha256:5873888fff1c7cf5b71efbe80e0e73153fe9212fafdf8e44adfe4c20ec9f82d7", - "sha256:61a3d5b97955422964be6b3baf05ff2ce7f26f52c85dd88db11d5e03e146a3a6", - "sha256:674e822aa665b9fd75130c6c5f5ed9564a38c6cea6a6432ce47eafb68ee578c5", - "sha256:7ce3175801d0ae5fdfa79b4f0cfed08807af4d075b402b7e294e6aa72af9aa2a", - "sha256:9743c91088d396c1a5a3c9978354b61b0382b4e3c440ce83cf77994a43e8c521", - "sha256:9f94aac67a2045ec719ffe6111df543bac7874cee01f41928f6969756e030564", - "sha256:a26f8ec704e5a7423c8824d425086705e381b4f1dfdef6e3a1edab7ba174ec49", - "sha256:abf7e0c3cf117c44d9285cc6128856106183938c68fd4944763003decdcfeb66", - "sha256:b09669bcda124e83708f34a94606e01b614fa71931d356c1f1a5297ba11f110a", - "sha256:cd07039aa5df222037005b08fbbfd69b3ab0b0bd7a07d7906de75ae52c4e3119", - "sha256:d23e0ea196702d918b60c8288561e722bf437d82cb7ef2edcd98cfa38905d506", - "sha256:d65cc1df038ef55a99e617431f0553cd77763869eebdf9042403e16089fe746c", - "sha256:d7da2e1d5f558c37d6e8c1246f1aec1e7349e4913d8fb3cb289a35de573fe2eb" - ], - "index": "pypi", - "version": "==0.812" - }, - "mypy-extensions": { - "hashes": [ - "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", - "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8" - ], - "version": "==0.4.3" - }, - "packaging": { - "hashes": [ - "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5", - "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.9" - }, - "pluggy": { - "hashes": [ - "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0", - "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.13.1" - }, - "py": { - "hashes": [ - "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3", - "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.10.0" - }, - "pycodestyle": { - "hashes": [ - "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068", - "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.7.0" - }, - "pyflakes": { - "hashes": [ - "sha256:910208209dcea632721cb58363d0f72913d9e8cf64dc6f8ae2e02a3609aba40d", - "sha256:e59fd8e750e588358f1b8885e5a4751203a0516e0ee6d34811089ac294c8806f" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.3.0" - }, - "pyparsing": { - "hashes": [ - "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", - "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.4.7" - }, - "pytest": { - "hashes": [ - "sha256:9d1edf9e7d0b84d72ea3dbcdfd22b35fb543a5e8f2a60092dd578936bf63d7f9", - "sha256:b574b57423e818210672e07ca1fa90aaf194a4f63f3ab909a2c67ebb22913839" - ], - "index": "pypi", - "version": "==6.2.2" - }, - "toml": { - "hashes": [ - "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", - "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.10.2" - }, - "typed-ast": { - "hashes": [ - "sha256:07d49388d5bf7e863f7fa2f124b1b1d89d8aa0e2f7812faff0a5658c01c59aa1", - "sha256:14bf1522cdee369e8f5581238edac09150c765ec1cb33615855889cf33dcb92d", - "sha256:240296b27397e4e37874abb1df2a608a92df85cf3e2a04d0d4d61055c8305ba6", - "sha256:36d829b31ab67d6fcb30e185ec996e1f72b892255a745d3a82138c97d21ed1cd", - "sha256:37f48d46d733d57cc70fd5f30572d11ab8ed92da6e6b28e024e4a3edfb456e37", - "sha256:4c790331247081ea7c632a76d5b2a265e6d325ecd3179d06e9cf8d46d90dd151", - "sha256:5dcfc2e264bd8a1db8b11a892bd1647154ce03eeba94b461effe68790d8b8e07", - "sha256:7147e2a76c75f0f64c4319886e7639e490fee87c9d25cb1d4faef1d8cf83a440", - "sha256:7703620125e4fb79b64aa52427ec192822e9f45d37d4b6625ab37ef403e1df70", - "sha256:8368f83e93c7156ccd40e49a783a6a6850ca25b556c0fa0240ed0f659d2fe496", - "sha256:84aa6223d71012c68d577c83f4e7db50d11d6b1399a9c779046d75e24bed74ea", - "sha256:85f95aa97a35bdb2f2f7d10ec5bbdac0aeb9dafdaf88e17492da0504de2e6400", - "sha256:8db0e856712f79c45956da0c9a40ca4246abc3485ae0d7ecc86a20f5e4c09abc", - "sha256:9044ef2df88d7f33692ae3f18d3be63dec69c4fb1b5a4a9ac950f9b4ba571606", - "sha256:963c80b583b0661918718b095e02303d8078950b26cc00b5e5ea9ababe0de1fc", - "sha256:987f15737aba2ab5f3928c617ccf1ce412e2e321c77ab16ca5a293e7bbffd581", - "sha256:9ec45db0c766f196ae629e509f059ff05fc3148f9ffd28f3cfe75d4afb485412", - "sha256:9fc0b3cb5d1720e7141d103cf4819aea239f7d136acf9ee4a69b047b7986175a", - "sha256:a2c927c49f2029291fbabd673d51a2180038f8cd5a5b2f290f78c4516be48be2", - "sha256:a38878a223bdd37c9709d07cd357bb79f4c760b29210e14ad0fb395294583787", - "sha256:b4fcdcfa302538f70929eb7b392f536a237cbe2ed9cba88e3bf5027b39f5f77f", - "sha256:c0c74e5579af4b977c8b932f40a5464764b2f86681327410aa028a22d2f54937", - "sha256:c1c876fd795b36126f773db9cbb393f19808edd2637e00fd6caba0e25f2c7b64", - "sha256:c9aadc4924d4b5799112837b226160428524a9a45f830e0d0f184b19e4090487", - "sha256:cc7b98bf58167b7f2db91a4327da24fb93368838eb84a44c472283778fc2446b", - "sha256:cf54cfa843f297991b7388c281cb3855d911137223c6b6d2dd82a47ae5125a41", - "sha256:d003156bb6a59cda9050e983441b7fa2487f7800d76bdc065566b7d728b4581a", - "sha256:d175297e9533d8d37437abc14e8a83cbc68af93cc9c1c59c2c292ec59a0697a3", - "sha256:d746a437cdbca200622385305aedd9aef68e8a645e385cc483bdc5e488f07166", - "sha256:e683e409e5c45d5c9082dc1daf13f6374300806240719f95dc783d1fc942af10" - ], - "version": "==1.4.2" - }, - "typing-extensions": { - "hashes": [ - "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918", - "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c", - "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f" - ], - "markers": "python_version < '3.8'", - "version": "==3.7.4.3" - } - } -} diff --git a/hello.py b/hello.py new file mode 100644 index 0000000..83e51e9 --- /dev/null +++ b/hello.py @@ -0,0 +1,6 @@ +def main(): + print("Hello from dataclass-csv2!") + + +if __name__ == "__main__": + main() diff --git a/pyproject.toml b/pyproject.toml index a49618b..a10ad75 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,19 +1,16 @@ -[dependency-groups] -dev = [ - "pyright>=1.1.392.post0", - "pytest>=8.3.4", -] [project] -name = "dataclass-csv" -version = "1.4.0" +name = "dataclass-csv2" +version = "0.1.0" description = "Map CSV data into dataclasses" +readme = "README.md" +license = "BSD-3-Clause" +requires-python = ">=3.7" +dependencies = [] authors = [ + # TODO, check if only active maintainer should be set + {name = "Kraktus", email = "kraktus@users.noreply.github.com"}, {name = "Daniel Furtado", email = "daniel@dfurtado.com"}, ] -dependencies = [] -requires-python = ">=3.7" -readme = "README.md" -license = {text = "BSD license"} keywords = ["dataclass", "dataclasses", "csv", "dataclass-csv"] classifiers = [ "Development Status :: 5 - Production/Stable", @@ -29,19 +26,13 @@ classifiers = [ "Environment :: Console", ] -[project.urls] -Homepage = "https://github.com/dfurtado/dataclass-csv" -[build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" +[project.urls] +Homepage = "https://github.com/kraktus/dataclass-csv2" +"Issue Tracker" = "https://github.com/kraktus/dataclass-csv2/issues" -[tool.hatch.build] -include = [ - "dataclass_csv/**/*.py", - "dataclass_csv/**/*.pyi", - "dataclass_csv/py.typed", +[dependency-groups] +dev = [ + "pyright>=1.1.392.post0", + "pytest>=7.4.4", ] - -[tool.pytest.ini_options] -testpaths = ["tests"] diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..0d334f4 --- /dev/null +++ b/uv.lock @@ -0,0 +1,268 @@ +version = 1 +requires-python = ">=3.7" +resolution-markers = [ + "python_full_version >= '3.8'", + "python_full_version < '3.8'", +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, +] + +[[package]] +name = "dataclass-csv2" +version = "0.1.0" +source = { virtual = "." } + +[package.dev-dependencies] +dev = [ + { name = "pyright" }, + { name = "pytest", version = "7.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.8'" }, + { name = "pytest", version = "8.3.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.8'" }, +] + +[package.metadata] + +[package.metadata.requires-dev] +dev = [ + { name = "pyright", specifier = ">=1.1.392.post0" }, + { name = "pytest", specifier = ">=7.4.4" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 }, +] + +[[package]] +name = "importlib-metadata" +version = "6.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", version = "4.7.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.8'" }, + { name = "zipp", marker = "python_full_version < '3.8'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/82/f6e29c8d5c098b6be61460371c2c5591f4a335923639edec43b3830650a4/importlib_metadata-6.7.0.tar.gz", hash = "sha256:1aaf550d4f73e5d6783e7acb77aec43d49da8017410afae93822cc9cca98c4d4", size = 53569 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ff/94/64287b38c7de4c90683630338cf28f129decbba0a44f0c6db35a873c73c4/importlib_metadata-6.7.0-py3-none-any.whl", hash = "sha256:cb52082e659e97afc5dac71e79de97d8681de3aa07ff18578330904a9d18e5b5", size = 22934 }, +] + +[[package]] +name = "iniconfig" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, +] + +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, +] + +[[package]] +name = "packaging" +version = "24.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.8'", +] +sdist = { url = "https://files.pythonhosted.org/packages/ee/b5/b43a27ac7472e1818c4bafd44430e69605baefe1f34440593e0332ec8b4d/packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9", size = 147882 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", size = 53488 }, +] + +[[package]] +name = "packaging" +version = "24.2" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.8'", +] +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, +] + +[[package]] +name = "pluggy" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.8'", +] +dependencies = [ + { name = "importlib-metadata", marker = "python_full_version < '3.8'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8a/42/8f2833655a29c4e9cb52ee8a2be04ceac61bcff4a680fb338cbd3d1e322d/pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3", size = 61613 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/32/4a79112b8b87b21450b066e102d6608907f4c885ed7b04c3fdb085d4d6ae/pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849", size = 17695 }, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.8'", +] +sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, +] + +[[package]] +name = "pyright" +version = "1.1.392.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nodeenv" }, + { name = "typing-extensions", version = "4.7.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.8'" }, + { name = "typing-extensions", version = "4.12.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.8'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/df/3c6f6b08fba7ccf49b114dfc4bb33e25c299883fd763f93fad47ef8bc58d/pyright-1.1.392.post0.tar.gz", hash = "sha256:3b7f88de74a28dcfa90c7d90c782b6569a48c2be5f9d4add38472bdaac247ebd", size = 3789911 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/b1/a18de17f40e4f61ca58856b9ef9b0febf74ff88978c3f7776f910071f567/pyright-1.1.392.post0-py3-none-any.whl", hash = "sha256:252f84458a46fa2f0fd4e2f91fc74f50b9ca52c757062e93f6c250c0d8329eb2", size = 5595487 }, +] + +[[package]] +name = "pytest" +version = "7.4.4" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.8'", +] +dependencies = [ + { name = "colorama", marker = "python_full_version < '3.8' and sys_platform == 'win32'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.8'" }, + { name = "importlib-metadata", marker = "python_full_version < '3.8'" }, + { name = "iniconfig", marker = "python_full_version < '3.8'" }, + { name = "packaging", version = "24.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.8'" }, + { name = "pluggy", version = "1.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.8'" }, + { name = "tomli", version = "2.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.8'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/80/1f/9d8e98e4133ffb16c90f3b405c43e38d3abb715bb5d7a63a5a684f7e46a3/pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280", size = 1357116 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/ff/f6e8b8f39e08547faece4bd80f89d5a8de68a38b2d179cc1c4490ffa3286/pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8", size = 325287 }, +] + +[[package]] +name = "pytest" +version = "8.3.4" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.8'", +] +dependencies = [ + { name = "colorama", marker = "python_full_version >= '3.8' and sys_platform == 'win32'" }, + { name = "exceptiongroup", marker = "python_full_version >= '3.8' and python_full_version < '3.11'" }, + { name = "iniconfig", marker = "python_full_version >= '3.8'" }, + { name = "packaging", version = "24.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.8'" }, + { name = "pluggy", version = "1.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.8'" }, + { name = "tomli", version = "2.2.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.8' and python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/05/35/30e0d83068951d90a01852cb1cef56e5d8a09d20c7f511634cc2f7e0372a/pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761", size = 1445919 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/92/76a1c94d3afee238333bc0a42b82935dd8f9cf8ce9e336ff87ee14d9e1cf/pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", size = 343083 }, +] + +[[package]] +name = "tomli" +version = "2.0.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.8'", +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/3f/d7af728f075fb08564c5949a9c95e44352e23dee646869fa104a3b2060a3/tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f", size = 15164 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", size = 12757 }, +] + +[[package]] +name = "tomli" +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.8'", +] +sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077 }, + { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429 }, + { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067 }, + { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030 }, + { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898 }, + { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894 }, + { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319 }, + { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273 }, + { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310 }, + { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309 }, + { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762 }, + { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453 }, + { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486 }, + { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349 }, + { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159 }, + { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243 }, + { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645 }, + { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584 }, + { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875 }, + { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418 }, + { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708 }, + { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582 }, + { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543 }, + { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691 }, + { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170 }, + { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530 }, + { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666 }, + { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954 }, + { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724 }, + { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383 }, + { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 }, +] + +[[package]] +name = "typing-extensions" +version = "4.7.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.8'", +] +sdist = { url = "https://files.pythonhosted.org/packages/3c/8b/0111dd7d6c1478bf83baa1cab85c686426c7a6274119aceb2bd9d35395ad/typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2", size = 72876 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/6b/63cc3df74987c36fe26157ee12e09e8f9db4de771e0f3404263117e75b95/typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36", size = 33232 }, +] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.8'", +] +sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, +] + +[[package]] +name = "zipp" +version = "3.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/00/27/f0ac6b846684cecce1ee93d32450c45ab607f65c2e0255f0092032d91f07/zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b", size = 18454 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/fa/c9e82bbe1af6266adf08afb563905eb87cab83fde00a0a08963510621047/zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556", size = 6758 }, +] From 7c9bf71cfc7210c04d9ca6359da2ea9d769871ff Mon Sep 17 00:00:00 2001 From: kraktus Date: Sat, 25 Jan 2025 23:17:54 +0100 Subject: [PATCH 07/28] remove old setup.py and setup.cfg files --- setup.cfg | 26 -------------------------- setup.py | 56 ------------------------------------------------------- 2 files changed, 82 deletions(-) delete mode 100644 setup.cfg delete mode 100644 setup.py diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 43bd1f6..0000000 --- a/setup.cfg +++ /dev/null @@ -1,26 +0,0 @@ -[bumpversion] -current_version = 1.4.0 -commit = True -tag = True - -[bumpversion:file:setup.py] -search = version='{current_version}' -replace = version='{new_version}' - -[bumpversion:file:easycsv/__init__.py] -search = __version__ = '{current_version}' -replace = __version__ = '{new_version}' - -[bdist_wheel] -universal = 1 - -[flake8] -exclude = docs -max-line-length = 88 - -[aliases] -# Define setup.py command aliases here -test = pytest - -[tool:pytest] -collect_ignore = ['setup.py'] diff --git a/setup.py b/setup.py deleted file mode 100644 index b998ace..0000000 --- a/setup.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -"""The setup script.""" - -from setuptools import setup, find_packages - -with open("README.md") as readme_file: - readme = readme_file.read() - -with open("HISTORY.md") as history_file: - history = history_file.read() - -requirements = [] - -setup_requirements = [ - "pytest-runner", -] - -test_requirements = [ - "pytest", -] - -setup( - author="Daniel Furtado", - author_email="daniel@dfurtado.com", - classifiers=[ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "License :: OSI Approved :: BSD License", - "Natural Language :: English", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.7", - "Operating System :: Microsoft :: Windows", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Unix", - "Operating System :: POSIX", - "Environment :: Console", - ], - description="Map CSV data into dataclasses", - install_requires=requirements, - license="BSD license", - long_description=readme + "\n\n" + history, - long_description_content_type="text/markdown", - include_package_data=True, - keywords="dataclass dataclasses csv dataclass-csv", - name="dataclass-csv", - packages=find_packages(include=["dataclass_csv"]), - package_data={"dataclass_csv": ["py.typed", "*.pyi"]}, - setup_requires=setup_requirements, - test_suite="tests", - tests_require=test_requirements, - url="https://github.com/dfurtado/dataclass-csv", - version="1.4.0", - zip_safe=False, -) From 53ccf40f7e2f97c93a32d492f50c78b08bd905ee Mon Sep 17 00:00:00 2001 From: kraktus Date: Sat, 25 Jan 2025 23:18:41 +0100 Subject: [PATCH 08/28] remove hello.py file that slipped in while initiating with uv --- AUTHORS.md | 1 + hello.py | 6 ------ 2 files changed, 1 insertion(+), 6 deletions(-) delete mode 100644 hello.py diff --git a/AUTHORS.md b/AUTHORS.md index 96f9dc0..9a69bbd 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -2,6 +2,7 @@ ## Development Lead +* Kraktus * Daniel Furtado ## Contributors diff --git a/hello.py b/hello.py deleted file mode 100644 index 83e51e9..0000000 --- a/hello.py +++ /dev/null @@ -1,6 +0,0 @@ -def main(): - print("Hello from dataclass-csv2!") - - -if __name__ == "__main__": - main() From cc60adffe25167172b9bcba81b8ac1d2463de42d Mon Sep 17 00:00:00 2001 From: kraktus Date: Sat, 25 Jan 2025 23:21:09 +0100 Subject: [PATCH 09/28] re-remove `2` from package name We want `dataclass_csv2` on pypi but keep `dataclass_csv` to be a drop-in replacement. --- {dataclass_csv2 => dataclass_csv}/__init__.py | 0 {dataclass_csv2 => dataclass_csv}/dataclass_reader.py | 0 {dataclass_csv2 => dataclass_csv}/dataclass_writer.py | 0 {dataclass_csv2 => dataclass_csv}/decorators.py | 0 {dataclass_csv2 => dataclass_csv}/exceptions.py | 0 {dataclass_csv2 => dataclass_csv}/field_mapper.py | 0 {dataclass_csv2 => dataclass_csv}/header_mapper.py | 0 pyproject.toml | 7 +++++++ 8 files changed, 7 insertions(+) rename {dataclass_csv2 => dataclass_csv}/__init__.py (100%) rename {dataclass_csv2 => dataclass_csv}/dataclass_reader.py (100%) rename {dataclass_csv2 => dataclass_csv}/dataclass_writer.py (100%) rename {dataclass_csv2 => dataclass_csv}/decorators.py (100%) rename {dataclass_csv2 => dataclass_csv}/exceptions.py (100%) rename {dataclass_csv2 => dataclass_csv}/field_mapper.py (100%) rename {dataclass_csv2 => dataclass_csv}/header_mapper.py (100%) diff --git a/dataclass_csv2/__init__.py b/dataclass_csv/__init__.py similarity index 100% rename from dataclass_csv2/__init__.py rename to dataclass_csv/__init__.py diff --git a/dataclass_csv2/dataclass_reader.py b/dataclass_csv/dataclass_reader.py similarity index 100% rename from dataclass_csv2/dataclass_reader.py rename to dataclass_csv/dataclass_reader.py diff --git a/dataclass_csv2/dataclass_writer.py b/dataclass_csv/dataclass_writer.py similarity index 100% rename from dataclass_csv2/dataclass_writer.py rename to dataclass_csv/dataclass_writer.py diff --git a/dataclass_csv2/decorators.py b/dataclass_csv/decorators.py similarity index 100% rename from dataclass_csv2/decorators.py rename to dataclass_csv/decorators.py diff --git a/dataclass_csv2/exceptions.py b/dataclass_csv/exceptions.py similarity index 100% rename from dataclass_csv2/exceptions.py rename to dataclass_csv/exceptions.py diff --git a/dataclass_csv2/field_mapper.py b/dataclass_csv/field_mapper.py similarity index 100% rename from dataclass_csv2/field_mapper.py rename to dataclass_csv/field_mapper.py diff --git a/dataclass_csv2/header_mapper.py b/dataclass_csv/header_mapper.py similarity index 100% rename from dataclass_csv2/header_mapper.py rename to dataclass_csv/header_mapper.py diff --git a/pyproject.toml b/pyproject.toml index a10ad75..63221fb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,3 +36,10 @@ dev = [ "pyright>=1.1.392.post0", "pytest>=7.4.4", ] + + +# pyproject.toml +[tool.pytest.ini_options] +testpaths = [ + "tests" +] \ No newline at end of file From 5080b4269dbf9b1b4de7ce72b32b5b6941999c78 Mon Sep 17 00:00:00 2001 From: kraktus Date: Sat, 25 Jan 2025 23:25:00 +0100 Subject: [PATCH 10/28] Extract `strtobool` function from `distutils.util` module taken from https://github.com/pypa/distutils/blob/ff11eed0c36b35bd68615a8ebf36763b7c8a6f28/distutils/util.py#L321 Fix https://github.com/dfurtado/dataclass-csv/issues/52 Note that the utility of the use of this function has not been checked, a better refactor may be possible. --- dataclass_csv/dataclass_reader.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/dataclass_csv/dataclass_reader.py b/dataclass_csv/dataclass_reader.py index 6467c21..174ce09 100644 --- a/dataclass_csv/dataclass_reader.py +++ b/dataclass_csv/dataclass_reader.py @@ -2,7 +2,6 @@ import csv from datetime import date, datetime -from distutils.util import strtobool from typing import Union, Type, Optional, Sequence, Dict, Any, List import typing @@ -30,6 +29,22 @@ def _verify_duplicate_header_items(header): ) ) +# Identical to the one found in `distutils.util` +# taken from https://github.com/pypa/distutils/blob/ff11eed0c36b35bd68615a8ebf36763b7c8a6f28/distutils/util.py#L321 +def strtobool(val: str) -> bool: + """Convert a string representation of truth to true (1) or false (0). + + True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values + are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if + 'val' is anything else. + """ + val = val.lower() + if val in ('y', 'yes', 't', 'true', 'on', '1'): + return True + elif val in ('n', 'no', 'f', 'false', 'off', '0'): + return False + else: + raise ValueError(f"invalid truth value {val!r}") def is_union_type(t): if hasattr(t, "__origin__") and t.__origin__ is Union: From 6bbf50a34f3bb4ce302ed60e40a92faf47fd8c29 Mon Sep 17 00:00:00 2001 From: kraktus Date: Sat, 25 Jan 2025 23:38:35 +0100 Subject: [PATCH 11/28] Add return type to dataclassreader reimplement https://github.com/dfurtado/dataclass-csv/pull/57 --- dataclass_csv/dataclass_reader.py | 12 +++++++----- dataclass_csv/dataclass_writer.py | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/dataclass_csv/dataclass_reader.py b/dataclass_csv/dataclass_reader.py index 174ce09..8d72f0c 100644 --- a/dataclass_csv/dataclass_reader.py +++ b/dataclass_csv/dataclass_reader.py @@ -2,7 +2,7 @@ import csv from datetime import date, datetime -from typing import Union, Type, Optional, Sequence, Dict, Any, List +from typing import Union, Type, Optional, Sequence, Dict, Any, List, Generic, TypeVar import typing @@ -12,6 +12,8 @@ from collections import Counter +T = TypeVar("T") + def _verify_duplicate_header_items(header): if header is not None and len(header) == 0: return @@ -60,11 +62,11 @@ def get_args(t): return tuple() -class DataclassReader: +class DataclassReader(Generic[T]): def __init__( self, f: Any, - cls: Type[object], + cls: Type[T], fieldnames: Optional[Sequence[str]] = None, restkey: Optional[str] = None, restval: Optional[Any] = None, @@ -198,7 +200,7 @@ def _parse_date_value(self, field, date_value, field_type): else: return datetime_obj - def _process_row(self, row): + def _process_row(self, row) -> T: values = dict() for field in dataclasses.fields(self._cls): @@ -257,7 +259,7 @@ def _process_row(self, row): values[field.name] = transformed_value return self._cls(**values) - def __next__(self): + def __next__(self) -> T: row = next(self._reader) return self._process_row(row) diff --git a/dataclass_csv/dataclass_writer.py b/dataclass_csv/dataclass_writer.py index fdcbb52..4e8f27c 100644 --- a/dataclass_csv/dataclass_writer.py +++ b/dataclass_csv/dataclass_writer.py @@ -11,7 +11,7 @@ def __init__( data: List[Any], cls: Type[object], dialect: str = "excel", - **fmtparams: Dict[str, Any], + **fmtparams: Any, ): if not f: raise ValueError("The f argument is required") From d9f21d8a930b3b57037dc63629a6e09044755cf3 Mon Sep 17 00:00:00 2001 From: kraktus Date: Sat, 25 Jan 2025 23:43:07 +0100 Subject: [PATCH 12/28] rename `cls` to `klass` to avoid name collusion with the real `cls` arg used in classmethods --- dataclass_csv/dataclass_reader.py | 10 +++++----- dataclass_csv/dataclass_writer.py | 10 +++++----- dataclass_csv/decorators.py | 12 ++++++------ 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/dataclass_csv/dataclass_reader.py b/dataclass_csv/dataclass_reader.py index 8d72f0c..586e928 100644 --- a/dataclass_csv/dataclass_reader.py +++ b/dataclass_csv/dataclass_reader.py @@ -66,7 +66,7 @@ class DataclassReader(Generic[T]): def __init__( self, f: Any, - cls: Type[T], + klass: Type[T], fieldnames: Optional[Sequence[str]] = None, restkey: Optional[str] = None, restval: Optional[Any] = None, @@ -78,10 +78,10 @@ def __init__( if not f: raise ValueError("The f argument is required.") - if cls is None or not dataclasses.is_dataclass(cls): - raise ValueError("cls argument needs to be a dataclass.") + if klass is None or not dataclasses.is_dataclass(klass): + raise ValueError("klass argument needs to be a dataclass.") - self._cls = cls + self._cls = klass self._optional_fields = self._get_optional_fields() self._field_mapping: Dict[str, Dict[str, Any]] = {} @@ -94,7 +94,7 @@ def __init__( if validate_header: _verify_duplicate_header_items(self._reader.fieldnames) - self.type_hints = typing.get_type_hints(cls) + self.type_hints = typing.get_type_hints(klass) def _get_optional_fields(self): return [ diff --git a/dataclass_csv/dataclass_writer.py b/dataclass_csv/dataclass_writer.py index 4e8f27c..093a925 100644 --- a/dataclass_csv/dataclass_writer.py +++ b/dataclass_csv/dataclass_writer.py @@ -9,7 +9,7 @@ def __init__( self, f: Any, data: List[Any], - cls: Type[object], + klass: Type[object], dialect: str = "excel", **fmtparams: Any, ): @@ -19,14 +19,14 @@ def __init__( if not isinstance(data, list): raise ValueError("Invalid 'data' argument. It must be a list") - if not dataclasses.is_dataclass(cls): - raise ValueError("Invalid 'cls' argument. It must be a dataclass") + if not dataclasses.is_dataclass(klass): + raise ValueError("Invalid 'klass' argument. It must be a dataclass") self._data = data - self._cls = cls + self._cls = klass self._field_mapping: Dict[str, str] = dict() - self._fieldnames = [x.name for x in dataclasses.fields(cls)] + self._fieldnames = [x.name for x in dataclasses.fields(klass)] self._writer = csv.writer(f, dialect=dialect, **fmtparams) diff --git a/dataclass_csv/decorators.py b/dataclass_csv/decorators.py index 67f4255..b9ae0ff 100644 --- a/dataclass_csv/decorators.py +++ b/dataclass_csv/decorators.py @@ -23,9 +23,9 @@ def dateformat(date_format: str) -> Callable[[F], F]: if not date_format or not isinstance(date_format, str): raise ValueError("Invalid value for the date_format argument") - def func(cls): - cls.__dateformat__ = date_format - return cls + def func(klass): + klass.__dateformat__ = date_format + return klass return func @@ -47,9 +47,9 @@ def accept_whitespaces(_cls: Type[Any] = None) -> Callable[[F], F]: >>> brithday: datetime """ - def func(cls): - cls.__accept_whitespaces__ = True - return cls + def func(klass): + klass.__accept_whitespaces__ = True + return klass if _cls: return func(_cls) From 83f95092cf8227e0d86c4dd12219f85c18f37f98 Mon Sep 17 00:00:00 2001 From: kraktus Date: Sun, 26 Jan 2025 00:06:32 +0100 Subject: [PATCH 13/28] Support non-list iterable as input to DataclassWriter reimplement and close https://github.com/dfurtado/dataclass-csv/pull/61 --- dataclass_csv/dataclass_writer.py | 16 ++++++++-------- tests/test_dataclass_writer.py | 16 ++++++++++------ 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/dataclass_csv/dataclass_writer.py b/dataclass_csv/dataclass_writer.py index 093a925..4525257 100644 --- a/dataclass_csv/dataclass_writer.py +++ b/dataclass_csv/dataclass_writer.py @@ -1,24 +1,25 @@ import csv import dataclasses -from typing import Type, Dict, Any, List +from typing import Type, Dict, Any, List, Iterable, Generic, TypeVar from .header_mapper import HeaderMapper -class DataclassWriter: + +T = TypeVar("T") + + +class DataclassWriter(Generic[T]): def __init__( self, f: Any, - data: List[Any], - klass: Type[object], + data: Iterable[T], + klass: Type[T], dialect: str = "excel", **fmtparams: Any, ): if not f: raise ValueError("The f argument is required") - if not isinstance(data, list): - raise ValueError("Invalid 'data' argument. It must be a list") - if not dataclasses.is_dataclass(klass): raise ValueError("Invalid 'klass' argument. It must be a dataclass") @@ -48,7 +49,6 @@ def write(self, skip_header: bool = False): self._fieldnames = self._apply_mapping() self._writer.writerow(self._fieldnames) - for item in self._data: if not isinstance(item, self._cls): raise TypeError( diff --git a/tests/test_dataclass_writer.py b/tests/test_dataclass_writer.py index 4b54517..32e258b 100644 --- a/tests/test_dataclass_writer.py +++ b/tests/test_dataclass_writer.py @@ -61,12 +61,16 @@ def test_invalid_file_value(tmpdir_factory): with pytest.raises(ValueError): DataclassWriter(None, users, User) - -def test_with_data_not_a_list(tmpdir_factory): +def test_with_iterable(tmpdir_factory): tempfile = tmpdir_factory.mktemp("data").join("user_001.csv") - - users = User(name="test", age=40) + users_dict = {"test": User(name="test", age=40)} with tempfile.open("w") as f: - with pytest.raises(ValueError): - DataclassWriter(f, users, User) + DataclassWriter(f, users_dict.values(), User).write() + + with tempfile.open() as f: + reader = DataclassReader(f, User) + saved_users = list(reader) + + assert len(saved_users) > 0 + assert saved_users[0].name == users_dict["test"].name From 1bf20b6119f66b1c51d0b9261beeec0680fccefa Mon Sep 17 00:00:00 2001 From: kraktus Date: Sun, 26 Jan 2025 00:09:02 +0100 Subject: [PATCH 14/28] strtobool return bool already --- dataclass_csv/dataclass_reader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dataclass_csv/dataclass_reader.py b/dataclass_csv/dataclass_reader.py index 586e928..c825223 100644 --- a/dataclass_csv/dataclass_reader.py +++ b/dataclass_csv/dataclass_reader.py @@ -237,7 +237,7 @@ def _process_row(self, row) -> T: transformed_value = ( value if isinstance(value, bool) - else strtobool(str(value).strip()) == 1 + else strtobool(str(value).strip()) ) except ValueError as ex: raise CsvValueError(ex, line_number=self._reader.line_num) from None From 6a67da7c683044d03bc8d29ca2c7c97e132c0e70 Mon Sep 17 00:00:00 2001 From: kraktus Date: Sun, 26 Jan 2025 10:47:22 +0100 Subject: [PATCH 15/28] Fix type error about `key` being unbounded in error message The whole code would probably need to be refactored but it should works for now ``` dataclass-csv2/dataclass_csv/dataclass_reader.py:149:76 - error: "key" is possibly unbound (reportPossiblyUnboundVariable) ``` --- dataclass_csv/dataclass_reader.py | 83 +++++++++++++++---------------- 1 file changed, 41 insertions(+), 42 deletions(-) diff --git a/dataclass_csv/dataclass_reader.py b/dataclass_csv/dataclass_reader.py index c825223..969ee4b 100644 --- a/dataclass_csv/dataclass_reader.py +++ b/dataclass_csv/dataclass_reader.py @@ -126,53 +126,52 @@ def _get_possible_keys(self, fieldname, row): def _get_value(self, row, field): is_field_mapped = False - try: - if field.name in self._field_mapping.keys(): - is_field_mapped = True - key = self._field_mapping.get(field.name) - else: - key = field.name + if field.name in self._field_mapping.keys(): + is_field_mapped = True + key = self._field_mapping.get(field.name) + else: + key = field.name - if key in row.keys(): - value = row[key] - else: + if key in row.keys(): + value = row[key] + else: + try: possible_key = self._get_possible_keys(field.name, row) key = possible_key if possible_key else key value = row[key] - - except KeyError: - if field.name in self._optional_fields: - return self._get_default_value(field) - else: - keyerror_message = f"The value for the column `{field.name}`" - if is_field_mapped: - keyerror_message = f"The value for the mapped column `{key}`" - raise KeyError(f"{keyerror_message} is missing in the CSV file") - else: - if not value and field.name in self._optional_fields: - return self._get_default_value(field) - elif not value and field.name not in self._optional_fields: - raise ValueError(f"The field `{field.name}` is required.") - elif ( - value - and field.type is str - and not len(value.strip()) - and not self._get_metadata_option(field, "accept_whitespaces") - ): - raise ValueError( - ( - f"It seems like the value of `{field.name}` contains " - "only white spaces. To allow white spaces to all " - "string fields, use the @accept_whitespaces " - "decorator. " - "To allow white spaces specifically for the field " - f"`{field.name}` change its definition to: " - f"`{field.name}: str = field(metadata=" - "{'accept_whitespaces': True})`." - ) + except KeyError: + if field.name in self._optional_fields: + return self._get_default_value(field) + else: + keyerror_message = f"The value for the column `{field.name}`" + if is_field_mapped: + keyerror_message = f"The value for the mapped column `{key}`" + raise KeyError(f"{keyerror_message} is missing in the CSV file") + + if not value and field.name in self._optional_fields: + return self._get_default_value(field) + elif not value and field.name not in self._optional_fields: + raise ValueError(f"The field `{field.name}` is required.") + elif ( + value + and field.type is str + and not len(value.strip()) + and not self._get_metadata_option(field, "accept_whitespaces") + ): + raise ValueError( + ( + f"It seems like the value of `{field.name}` contains " + "only white spaces. To allow white spaces to all " + "string fields, use the @accept_whitespaces " + "decorator. " + "To allow white spaces specifically for the field " + f"`{field.name}` change its definition to: " + f"`{field.name}: str = field(metadata=" + "{'accept_whitespaces': True})`." ) - else: - return value + ) + else: + return value def _parse_date_value(self, field, date_value, field_type): dateformat = self._get_metadata_option(field, "dateformat") From 94f604e23a4881860c2d4c91b06bd529080f4d09 Mon Sep 17 00:00:00 2001 From: kraktus Date: Sun, 26 Jan 2025 10:53:34 +0100 Subject: [PATCH 16/28] fix `accept_whitespaces` decorator typing --- dataclass_csv/decorators.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/dataclass_csv/decorators.py b/dataclass_csv/decorators.py index b9ae0ff..5b97835 100644 --- a/dataclass_csv/decorators.py +++ b/dataclass_csv/decorators.py @@ -29,8 +29,9 @@ def func(klass): return func +KLASS = TypeVar("KLASS", bound=Type[Any]) -def accept_whitespaces(_cls: Type[Any] = None) -> Callable[[F], F]: +def accept_whitespaces(klass: KLASS) -> Callable[[KLASS], KLASS]: """The accept_whitespaces decorator tells the `DataclassReader` that `str` fields defined in the `dataclass` should accept values containing only white spaces. @@ -47,11 +48,5 @@ def accept_whitespaces(_cls: Type[Any] = None) -> Callable[[F], F]: >>> brithday: datetime """ - def func(klass): - klass.__accept_whitespaces__ = True - return klass - - if _cls: - return func(_cls) - - return func + klass.__accept_whitespaces__ = True + return klass From 5a2f55c49a7cd7eebbb160929165148759302a65 Mon Sep 17 00:00:00 2001 From: kraktus Date: Sun, 26 Jan 2025 11:07:55 +0100 Subject: [PATCH 17/28] Corrected type hint for accept_whitespaces decorator --- dataclass_csv/decorators.py | 2 +- tests/test_dataclass_reader.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dataclass_csv/decorators.py b/dataclass_csv/decorators.py index 5b97835..0137c5b 100644 --- a/dataclass_csv/decorators.py +++ b/dataclass_csv/decorators.py @@ -31,7 +31,7 @@ def func(klass): KLASS = TypeVar("KLASS", bound=Type[Any]) -def accept_whitespaces(klass: KLASS) -> Callable[[KLASS], KLASS]: +def accept_whitespaces(klass: KLASS) -> KLASS: """The accept_whitespaces decorator tells the `DataclassReader` that `str` fields defined in the `dataclass` should accept values containing only white spaces. diff --git a/tests/test_dataclass_reader.py b/tests/test_dataclass_reader.py index 2c3df49..dc4c559 100644 --- a/tests/test_dataclass_reader.py +++ b/tests/test_dataclass_reader.py @@ -36,7 +36,7 @@ def test_reader_with_none_class(create_csv): with csv_file.open() as f: with pytest.raises(ValueError): - DataclassReader(f, None) + DataclassReader(f, None) # type: ignore def test_reader_with_none_file(): From b176b64c423e5b514860940797cbbf2fe9d19e9d Mon Sep 17 00:00:00 2001 From: kraktus Date: Sun, 26 Jan 2025 11:13:45 +0100 Subject: [PATCH 18/28] finish fixing type issues in test --- tests/conftest.py | 9 ++++++--- tests/test_dataclass_writer.py | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 6190666..fc049df 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,11 +1,12 @@ from csv import DictWriter +from typing import Any, Dict, List, Union import pytest @pytest.fixture() def create_csv(tmpdir_factory): - def func(data, fieldnames=None, filename="user.csv", factory=tmpdir_factory): + def func(data: Union[Dict[str, Any], List[Dict[str, Any]]], fieldnames=None, filename="user.csv", factory=tmpdir_factory): assert data @@ -18,8 +19,10 @@ def func(data, fieldnames=None, filename="user.csv", factory=tmpdir_factory): with file.open("w") as f: writer = DictWriter(f, fieldnames=header) writer.writeheader() - addrow = writer.writerows if isinstance(data, list) else writer.writerow - addrow(data) + if isinstance(data, list): + writer.writerows(data) + else: + writer.writerow(data) return file diff --git a/tests/test_dataclass_writer.py b/tests/test_dataclass_writer.py index 32e258b..3c874e5 100644 --- a/tests/test_dataclass_writer.py +++ b/tests/test_dataclass_writer.py @@ -50,7 +50,7 @@ def test_with_a_empty_cls_value(tmpdir_factory): with tempfile.open("w") as f: with pytest.raises(ValueError): - DataclassWriter(f, users, None) + DataclassWriter(f, users, None) # type: ignore def test_invalid_file_value(tmpdir_factory): From 1e084beedad3d0d863730a602069439a2bbcadd3 Mon Sep 17 00:00:00 2001 From: kraktus Date: Sun, 26 Jan 2025 11:26:00 +0100 Subject: [PATCH 19/28] try to build the package --- MANIFEST.in | 11 ----------- pyproject.toml | 2 +- 2 files changed, 1 insertion(+), 12 deletions(-) delete mode 100644 MANIFEST.in diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 68e47f0..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,11 +0,0 @@ -include AUTHORS.md -include CONTRIBUTING.md -include HISTORY.md -include LICENSE -include README.md - -recursive-include tests * -recursive-exclude * __pycache__ -recursive-exclude * *.py[co] - -recursive-include docs *.md conf.py Makefile make.bat *.jpg *.png *.gif diff --git a/pyproject.toml b/pyproject.toml index 63221fb..7c2309d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ name = "dataclass-csv2" version = "0.1.0" description = "Map CSV data into dataclasses" readme = "README.md" -license = "BSD-3-Clause" +license-expression = "BSD-3-Clause" requires-python = ">=3.7" dependencies = [] authors = [ From 08656147f4181d78ffb86d4424f6bbd2384a3a0f Mon Sep 17 00:00:00 2001 From: kraktus Date: Sun, 26 Jan 2025 11:37:13 +0100 Subject: [PATCH 20/28] fix pyproject.toml to allow building --- pyproject.toml | 9 ++++++++- uv.lock | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 7c2309d..895d63f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,4 +42,11 @@ dev = [ [tool.pytest.ini_options] testpaths = [ "tests" -] \ No newline at end of file +] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build.targets.wheel] +packages = ["dataclass_csv"] \ No newline at end of file diff --git a/uv.lock b/uv.lock index 0d334f4..378ce43 100644 --- a/uv.lock +++ b/uv.lock @@ -17,7 +17,7 @@ wheels = [ [[package]] name = "dataclass-csv2" version = "0.1.0" -source = { virtual = "." } +source = { editable = "." } [package.dev-dependencies] dev = [ From 3aa80e2a51f083a1510e53ac7fd761097e34b2cc Mon Sep 17 00:00:00 2001 From: kraktus Date: Sun, 26 Jan 2025 11:47:45 +0100 Subject: [PATCH 21/28] update readme and compatible python versions --- README.md | 5 ++--- pyproject.toml | 6 ++++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0d12946..37b2571 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ -[![Build Status](https://travis-ci.org/dfurtado/dataclass-csv.svg?branch=master)](https://travis-ci.org/dfurtado/dataclass-csv) -[![pypi](https://img.shields.io/pypi/v/dataclass-csv.svg)](https://pypi.python.org/pypi/dataclass-csv) -[![Downloads](https://pepy.tech/badge/dataclass-csv)](https://pepy.tech/project/dataclass-csv) +[![pypi](https://img.shields.io/pypi/v/dataclass-csv2.svg)](https://pypi.python.org/pypi/dataclass-csv2) +[![Downloads](https://pepy.tech/badge/dataclass-csv2)](https://pepy.tech/project/dataclass-csv2) diff --git a/pyproject.toml b/pyproject.toml index 895d63f..4941f13 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,6 +19,12 @@ classifiers = [ "Natural Language :: English", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Operating System :: Microsoft :: Windows", "Operating System :: MacOS :: MacOS X", "Operating System :: Unix", From fae7639573285b167594f6806a504f025b03e841 Mon Sep 17 00:00:00 2001 From: kraktus Date: Sun, 26 Jan 2025 11:49:45 +0100 Subject: [PATCH 22/28] delete FUNCING.yml --- .github/FUNDING.yml | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 9691dc0..0000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,12 +0,0 @@ -# These are supported funding model platforms - -github: [dfurtado] -patreon: # Replace with a single Patreon username -open_collective: # Replace with a single Open Collective username -ko_fi: # Replace with a single Ko-fi username -tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel -community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry -liberapay: # Replace with a single Liberapay username -issuehunt: # Replace with a single IssueHunt username -otechie: # Replace with a single Otechie username -custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] From 706f22c5fdc67493a7160156e00e4e423fd9c839 Mon Sep 17 00:00:00 2001 From: kraktus Date: Sun, 26 Jan 2025 12:00:29 +0100 Subject: [PATCH 23/28] Add test in CI --- .github/workflows/test.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..689a392 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,36 @@ +name: Test + +on: + push: + branches: ["master"] + paths: + - ".github/workflows/test.yml" + - "**.py" + - "uv.lock" + - "pyproject.toml" + pull_request: + paths: + - ".github/workflows/test.yml" + - "**.py" + - "uv.lock" + - "pyproject.toml" + +jobs: + test: + strategy: + fail-fast: false + matrix: + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + os: [ubuntu-latest, macos-latest, windows-latest] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + - name: Install uv and set the python version + uses: astral-sh/setup-uv@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install the project + run: uv sync --all-extras --dev + - name: Run tests + run: uv run pytest From 93dc96bcffbe8f006f9bc404f812883f609da6e3 Mon Sep 17 00:00:00 2001 From: kraktus Date: Sun, 26 Jan 2025 12:08:19 +0100 Subject: [PATCH 24/28] Update release --- HISTORY.md | 83 ++++-------------------------------------------------- 1 file changed, 5 insertions(+), 78 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 72efb7b..6ba9764 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,81 +1,8 @@ # History -### 0.1.0 (2018-11-25) +### 0.1.0 (2025-01-26) -* First release on PyPI. - -### 0.1.1 (2018-11-25) - -* Documentation fixes. - -### 0.1.2 (2018-11-25) - -* Documentation fixes. - -### 0.1.3 (2018-11-26) - -* Bug fixes -* Removed the requirement of setting the dataclass init to `True` - -### 0.1.5 (2018-11-29) - -* Support for parsing datetime values. -* Better handling when default values are set to `None` - -### 0.1.6 (2018-12-01) - -* Added support for reader default values from the default property of the `dataclasses.field`. -* Added support for allowing string values with only white spaces in a class level using the `@accept_whitespaces` decorator or through the `dataclasses.field` metadata. -* Added support for specifying date format using the `dataclasses.field` metadata. - -### 0.1.7 (2018-12-01) - -* Added support for default values from `default_factory` in the field's metadata. This allows adding mutable default values to the dataclass properties. - -### 1.0.0 (2018-12-16) - -* When a data does not pass validation it shows the line number in the CSV file where the data contain errors. -* Improved error handling. -* Changed the usage of the `@accept_whitespaces` decorator. -* Updated documentation. - -### 1.0.1 (2019-01-29) - -* Fixed issue when parsing headers on a CSV file with trailing white spaces. - -### 1.1.0 (2019-02-17) - -* Added support for boolean values. -* Docstrings - -### 1.1.1 (2019-02-17) - -* Documentation fixes. - -### 1.1.2 (2019-02-17) - -* Documentation fixes. - -### 1.1.3 (2020-03-01) - -* Handle properties with init set to False -* Handle Option type annotation - -### 1.2.0 (2021-03-02) - -* Introduction of a DataclassWriter -* Added type hinting to external API -* Documentation updates -* Bug fixes - -## 1.3.0 (2021-04-10) - -* Included stub files -* check if the CSV file has duplicated header values -* Fixed issues #22 and #33 -* code cleanup - -## 1.4.0 (2021-12-13) - -* Bug fixes -* Support for date types \ No newline at end of file +* First release on PyPI, based on version 1.4.0 of [dataclass-csv](https://github.com/dfurtado/dataclass-csv). +* Remove dependency on `distutils` which is longer bundled with python starting from 3.12. +* Support all iterables instead of just List as input to `DataclassWriter`. +* Add return type hints `DataclassReader` methods. \ No newline at end of file From 916c9e0d9799e9a24a8d33f95f4704264c9685bc Mon Sep 17 00:00:00 2001 From: kraktus Date: Sun, 26 Jan 2025 12:47:51 +0100 Subject: [PATCH 25/28] Update Dependabot configuration for GitHub Actions --- .github/dependabot.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..dfd0e30 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +# Set update schedule for GitHub Actions + +version: 2 +updates: + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + # Check for updates to GitHub Actions every week + interval: "weekly" From e731532a0580af17f331ed17b510a3da657e6fea Mon Sep 17 00:00:00 2001 From: Daniel Furtado Date: Wed, 19 Nov 2025 09:43:28 +0100 Subject: [PATCH 26/28] Review fixes --- .github/FUNDING.yml | 12 +++ AUTHORS.md | 4 +- HISTORY.md | 83 +++++++++++++++++-- README.md | 11 +-- dataclass_csv/dataclass_reader.py | 27 +++--- pyproject.toml | 10 +-- uv.lock | 133 +++++++++++++++--------------- 7 files changed, 180 insertions(+), 100 deletions(-) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..9691dc0 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [dfurtado] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/AUTHORS.md b/AUTHORS.md index 9a69bbd..204dac4 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -2,11 +2,11 @@ ## Development Lead -* Kraktus -* Daniel Furtado +* Daniel Furtado ## Contributors +* Kraktus * Nick Schober * Zoltan Ivanfi * Alec Benzer diff --git a/HISTORY.md b/HISTORY.md index 6ba9764..72efb7b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,8 +1,81 @@ # History -### 0.1.0 (2025-01-26) +### 0.1.0 (2018-11-25) -* First release on PyPI, based on version 1.4.0 of [dataclass-csv](https://github.com/dfurtado/dataclass-csv). -* Remove dependency on `distutils` which is longer bundled with python starting from 3.12. -* Support all iterables instead of just List as input to `DataclassWriter`. -* Add return type hints `DataclassReader` methods. \ No newline at end of file +* First release on PyPI. + +### 0.1.1 (2018-11-25) + +* Documentation fixes. + +### 0.1.2 (2018-11-25) + +* Documentation fixes. + +### 0.1.3 (2018-11-26) + +* Bug fixes +* Removed the requirement of setting the dataclass init to `True` + +### 0.1.5 (2018-11-29) + +* Support for parsing datetime values. +* Better handling when default values are set to `None` + +### 0.1.6 (2018-12-01) + +* Added support for reader default values from the default property of the `dataclasses.field`. +* Added support for allowing string values with only white spaces in a class level using the `@accept_whitespaces` decorator or through the `dataclasses.field` metadata. +* Added support for specifying date format using the `dataclasses.field` metadata. + +### 0.1.7 (2018-12-01) + +* Added support for default values from `default_factory` in the field's metadata. This allows adding mutable default values to the dataclass properties. + +### 1.0.0 (2018-12-16) + +* When a data does not pass validation it shows the line number in the CSV file where the data contain errors. +* Improved error handling. +* Changed the usage of the `@accept_whitespaces` decorator. +* Updated documentation. + +### 1.0.1 (2019-01-29) + +* Fixed issue when parsing headers on a CSV file with trailing white spaces. + +### 1.1.0 (2019-02-17) + +* Added support for boolean values. +* Docstrings + +### 1.1.1 (2019-02-17) + +* Documentation fixes. + +### 1.1.2 (2019-02-17) + +* Documentation fixes. + +### 1.1.3 (2020-03-01) + +* Handle properties with init set to False +* Handle Option type annotation + +### 1.2.0 (2021-03-02) + +* Introduction of a DataclassWriter +* Added type hinting to external API +* Documentation updates +* Bug fixes + +## 1.3.0 (2021-04-10) + +* Included stub files +* check if the CSV file has duplicated header values +* Fixed issues #22 and #33 +* code cleanup + +## 1.4.0 (2021-12-13) + +* Bug fixes +* Support for date types \ No newline at end of file diff --git a/README.md b/README.md index 37b2571..c5ca538 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,12 @@ -[![pypi](https://img.shields.io/pypi/v/dataclass-csv2.svg)](https://pypi.python.org/pypi/dataclass-csv2) -[![Downloads](https://pepy.tech/badge/dataclass-csv2)](https://pepy.tech/project/dataclass-csv2) +[![Unit testing](https://github.com/dfurtado/dataclass-csv/actions/workflows/unit-test.yml/badge.svg)](https://github.com/dfurtado/dataclass-csv/actions/workflows/unit-test.yml) +[![pypi](https://img.shields.io/pypi/v/dataclass-csv.svg)](https://pypi.python.org/pypi/dataclass-csv) +[![Downloads](https://pepy.tech/badge/dataclass-csv)](https://pepy.tech/project/dataclass-csv) -# Dataclass CSV 2 +# Dataclass CSV -Dataclass CSV 2 is a fork of [dataclass-csv](https://github.com/dfurtado/dataclass-csv) with downstream bug fixes that makes working with CSV files easier and much better than working with Dicts. It uses Python's Dataclasses to store data of every row on the CSV file and also uses type annotations which enables proper type checking and validation. +Dataclass CSV makes working with CSV files easier and much better than working with Dicts. It uses Python's Dataclasses to store data of every row on the CSV file and also uses type annotations which enables proper type checking and validation. ## Main features @@ -25,7 +26,7 @@ using a list of instances of a dataclass. ## Installation ```shell -pip install dataclass-csv2 +pipenv install dataclass-csv ``` ## Getting started diff --git a/dataclass_csv/dataclass_reader.py b/dataclass_csv/dataclass_reader.py index 969ee4b..01012d7 100644 --- a/dataclass_csv/dataclass_reader.py +++ b/dataclass_csv/dataclass_reader.py @@ -31,22 +31,17 @@ def _verify_duplicate_header_items(header): ) ) -# Identical to the one found in `distutils.util` -# taken from https://github.com/pypa/distutils/blob/ff11eed0c36b35bd68615a8ebf36763b7c8a6f28/distutils/util.py#L321 -def strtobool(val: str) -> bool: - """Convert a string representation of truth to true (1) or false (0). - - True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values - are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if - 'val' is anything else. - """ - val = val.lower() - if val in ('y', 'yes', 't', 'true', 'on', '1'): - return True - elif val in ('n', 'no', 'f', 'false', 'off', '0'): - return False - else: - raise ValueError(f"invalid truth value {val!r}") + +def strtobool(value: str) -> bool: + trueValues = ["true", "yes", "t", "y", "on", "1"] + + validValues = ["false", "no", "f", "n", "off", "0", *trueValues] + + if value.lower() not in validValues: + raise ValueError(f"invalid boolean value {value}") + + return value.lower() in trueValues + def is_union_type(t): if hasattr(t, "__origin__") and t.__origin__ is Union: diff --git a/pyproject.toml b/pyproject.toml index 4941f13..1490a69 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,14 +1,12 @@ [project] -name = "dataclass-csv2" -version = "0.1.0" +name = "dataclass-csv" +version = "1.4.0" description = "Map CSV data into dataclasses" readme = "README.md" license-expression = "BSD-3-Clause" requires-python = ">=3.7" dependencies = [] authors = [ - # TODO, check if only active maintainer should be set - {name = "Kraktus", email = "kraktus@users.noreply.github.com"}, {name = "Daniel Furtado", email = "daniel@dfurtado.com"}, ] keywords = ["dataclass", "dataclasses", "csv", "dataclass-csv"] @@ -34,8 +32,8 @@ classifiers = [ [project.urls] -Homepage = "https://github.com/kraktus/dataclass-csv2" -"Issue Tracker" = "https://github.com/kraktus/dataclass-csv2/issues" +Homepage = "https://github.com/dfurtado/dataclass-csv" +"Issue Tracker" = "https://github.com/dfurtado/dataclass-csv/issues" [dependency-groups] dev = [ diff --git a/uv.lock b/uv.lock index 378ce43..eb4b8ba 100644 --- a/uv.lock +++ b/uv.lock @@ -1,4 +1,5 @@ version = 1 +revision = 3 requires-python = ">=3.7" resolution-markers = [ "python_full_version >= '3.8'", @@ -9,14 +10,14 @@ resolution-markers = [ name = "colorama" version = "0.4.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] [[package]] -name = "dataclass-csv2" -version = "0.1.0" +name = "dataclass-csv" +version = "1.4.0" source = { editable = "." } [package.dev-dependencies] @@ -38,9 +39,9 @@ dev = [ name = "exceptiongroup" version = "1.2.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 } +sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883, upload-time = "2024-07-12T22:26:00.161Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 }, + { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453, upload-time = "2024-07-12T22:25:58.476Z" }, ] [[package]] @@ -51,27 +52,27 @@ dependencies = [ { name = "typing-extensions", version = "4.7.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.8'" }, { name = "zipp", marker = "python_full_version < '3.8'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a3/82/f6e29c8d5c098b6be61460371c2c5591f4a335923639edec43b3830650a4/importlib_metadata-6.7.0.tar.gz", hash = "sha256:1aaf550d4f73e5d6783e7acb77aec43d49da8017410afae93822cc9cca98c4d4", size = 53569 } +sdist = { url = "https://files.pythonhosted.org/packages/a3/82/f6e29c8d5c098b6be61460371c2c5591f4a335923639edec43b3830650a4/importlib_metadata-6.7.0.tar.gz", hash = "sha256:1aaf550d4f73e5d6783e7acb77aec43d49da8017410afae93822cc9cca98c4d4", size = 53569, upload-time = "2023-06-18T21:44:35.024Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ff/94/64287b38c7de4c90683630338cf28f129decbba0a44f0c6db35a873c73c4/importlib_metadata-6.7.0-py3-none-any.whl", hash = "sha256:cb52082e659e97afc5dac71e79de97d8681de3aa07ff18578330904a9d18e5b5", size = 22934 }, + { url = "https://files.pythonhosted.org/packages/ff/94/64287b38c7de4c90683630338cf28f129decbba0a44f0c6db35a873c73c4/importlib_metadata-6.7.0-py3-none-any.whl", hash = "sha256:cb52082e659e97afc5dac71e79de97d8681de3aa07ff18578330904a9d18e5b5", size = 22934, upload-time = "2023-06-18T21:44:33.441Z" }, ] [[package]] name = "iniconfig" version = "2.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } +sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646, upload-time = "2023-01-07T11:08:11.254Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, + { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892, upload-time = "2023-01-07T11:08:09.864Z" }, ] [[package]] name = "nodeenv" version = "1.9.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload-time = "2024-06-04T18:44:11.171Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, ] [[package]] @@ -81,9 +82,9 @@ source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.8'", ] -sdist = { url = "https://files.pythonhosted.org/packages/ee/b5/b43a27ac7472e1818c4bafd44430e69605baefe1f34440593e0332ec8b4d/packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9", size = 147882 } +sdist = { url = "https://files.pythonhosted.org/packages/ee/b5/b43a27ac7472e1818c4bafd44430e69605baefe1f34440593e0332ec8b4d/packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9", size = 147882, upload-time = "2024-03-10T09:39:28.33Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", size = 53488 }, + { url = "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", size = 53488, upload-time = "2024-03-10T09:39:25.947Z" }, ] [[package]] @@ -93,9 +94,9 @@ source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.8'", ] -sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950, upload-time = "2024-11-08T09:47:47.202Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451, upload-time = "2024-11-08T09:47:44.722Z" }, ] [[package]] @@ -108,9 +109,9 @@ resolution-markers = [ dependencies = [ { name = "importlib-metadata", marker = "python_full_version < '3.8'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8a/42/8f2833655a29c4e9cb52ee8a2be04ceac61bcff4a680fb338cbd3d1e322d/pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3", size = 61613 } +sdist = { url = "https://files.pythonhosted.org/packages/8a/42/8f2833655a29c4e9cb52ee8a2be04ceac61bcff4a680fb338cbd3d1e322d/pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3", size = 61613, upload-time = "2023-06-21T09:12:28.745Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/51/32/4a79112b8b87b21450b066e102d6608907f4c885ed7b04c3fdb085d4d6ae/pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849", size = 17695 }, + { url = "https://files.pythonhosted.org/packages/51/32/4a79112b8b87b21450b066e102d6608907f4c885ed7b04c3fdb085d4d6ae/pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849", size = 17695, upload-time = "2023-06-21T09:12:27.397Z" }, ] [[package]] @@ -120,9 +121,9 @@ source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.8'", ] -sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } +sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955, upload-time = "2024-04-20T21:34:42.531Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, + { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556, upload-time = "2024-04-20T21:34:40.434Z" }, ] [[package]] @@ -134,9 +135,9 @@ dependencies = [ { name = "typing-extensions", version = "4.7.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.8'" }, { name = "typing-extensions", version = "4.12.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.8'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/df/3c6f6b08fba7ccf49b114dfc4bb33e25c299883fd763f93fad47ef8bc58d/pyright-1.1.392.post0.tar.gz", hash = "sha256:3b7f88de74a28dcfa90c7d90c782b6569a48c2be5f9d4add38472bdaac247ebd", size = 3789911 } +sdist = { url = "https://files.pythonhosted.org/packages/66/df/3c6f6b08fba7ccf49b114dfc4bb33e25c299883fd763f93fad47ef8bc58d/pyright-1.1.392.post0.tar.gz", hash = "sha256:3b7f88de74a28dcfa90c7d90c782b6569a48c2be5f9d4add38472bdaac247ebd", size = 3789911, upload-time = "2025-01-15T15:01:20.913Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/b1/a18de17f40e4f61ca58856b9ef9b0febf74ff88978c3f7776f910071f567/pyright-1.1.392.post0-py3-none-any.whl", hash = "sha256:252f84458a46fa2f0fd4e2f91fc74f50b9ca52c757062e93f6c250c0d8329eb2", size = 5595487 }, + { url = "https://files.pythonhosted.org/packages/e7/b1/a18de17f40e4f61ca58856b9ef9b0febf74ff88978c3f7776f910071f567/pyright-1.1.392.post0-py3-none-any.whl", hash = "sha256:252f84458a46fa2f0fd4e2f91fc74f50b9ca52c757062e93f6c250c0d8329eb2", size = 5595487, upload-time = "2025-01-15T15:01:17.775Z" }, ] [[package]] @@ -155,9 +156,9 @@ dependencies = [ { name = "pluggy", version = "1.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.8'" }, { name = "tomli", version = "2.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.8'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/80/1f/9d8e98e4133ffb16c90f3b405c43e38d3abb715bb5d7a63a5a684f7e46a3/pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280", size = 1357116 } +sdist = { url = "https://files.pythonhosted.org/packages/80/1f/9d8e98e4133ffb16c90f3b405c43e38d3abb715bb5d7a63a5a684f7e46a3/pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280", size = 1357116, upload-time = "2023-12-31T12:00:18.035Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/51/ff/f6e8b8f39e08547faece4bd80f89d5a8de68a38b2d179cc1c4490ffa3286/pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8", size = 325287 }, + { url = "https://files.pythonhosted.org/packages/51/ff/f6e8b8f39e08547faece4bd80f89d5a8de68a38b2d179cc1c4490ffa3286/pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8", size = 325287, upload-time = "2023-12-31T12:00:13.963Z" }, ] [[package]] @@ -175,9 +176,9 @@ dependencies = [ { name = "pluggy", version = "1.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.8'" }, { name = "tomli", version = "2.2.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.8' and python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/05/35/30e0d83068951d90a01852cb1cef56e5d8a09d20c7f511634cc2f7e0372a/pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761", size = 1445919 } +sdist = { url = "https://files.pythonhosted.org/packages/05/35/30e0d83068951d90a01852cb1cef56e5d8a09d20c7f511634cc2f7e0372a/pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761", size = 1445919, upload-time = "2024-12-01T12:54:25.98Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/11/92/76a1c94d3afee238333bc0a42b82935dd8f9cf8ce9e336ff87ee14d9e1cf/pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", size = 343083 }, + { url = "https://files.pythonhosted.org/packages/11/92/76a1c94d3afee238333bc0a42b82935dd8f9cf8ce9e336ff87ee14d9e1cf/pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", size = 343083, upload-time = "2024-12-01T12:54:19.735Z" }, ] [[package]] @@ -187,9 +188,9 @@ source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.8'", ] -sdist = { url = "https://files.pythonhosted.org/packages/c0/3f/d7af728f075fb08564c5949a9c95e44352e23dee646869fa104a3b2060a3/tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f", size = 15164 } +sdist = { url = "https://files.pythonhosted.org/packages/c0/3f/d7af728f075fb08564c5949a9c95e44352e23dee646869fa104a3b2060a3/tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f", size = 15164, upload-time = "2022-02-08T10:54:04.006Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", size = 12757 }, + { url = "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", size = 12757, upload-time = "2022-02-08T10:54:02.017Z" }, ] [[package]] @@ -199,39 +200,39 @@ source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.8'", ] -sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175 } +sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175, upload-time = "2024-11-27T22:38:36.873Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077 }, - { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429 }, - { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067 }, - { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030 }, - { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898 }, - { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894 }, - { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319 }, - { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273 }, - { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310 }, - { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309 }, - { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762 }, - { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453 }, - { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486 }, - { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349 }, - { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159 }, - { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243 }, - { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645 }, - { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584 }, - { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875 }, - { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418 }, - { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708 }, - { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582 }, - { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543 }, - { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691 }, - { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170 }, - { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530 }, - { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666 }, - { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954 }, - { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724 }, - { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383 }, - { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 }, + { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077, upload-time = "2024-11-27T22:37:54.956Z" }, + { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429, upload-time = "2024-11-27T22:37:56.698Z" }, + { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067, upload-time = "2024-11-27T22:37:57.63Z" }, + { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030, upload-time = "2024-11-27T22:37:59.344Z" }, + { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898, upload-time = "2024-11-27T22:38:00.429Z" }, + { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894, upload-time = "2024-11-27T22:38:02.094Z" }, + { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319, upload-time = "2024-11-27T22:38:03.206Z" }, + { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273, upload-time = "2024-11-27T22:38:04.217Z" }, + { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310, upload-time = "2024-11-27T22:38:05.908Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309, upload-time = "2024-11-27T22:38:06.812Z" }, + { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762, upload-time = "2024-11-27T22:38:07.731Z" }, + { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453, upload-time = "2024-11-27T22:38:09.384Z" }, + { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486, upload-time = "2024-11-27T22:38:10.329Z" }, + { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349, upload-time = "2024-11-27T22:38:11.443Z" }, + { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159, upload-time = "2024-11-27T22:38:13.099Z" }, + { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243, upload-time = "2024-11-27T22:38:14.766Z" }, + { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645, upload-time = "2024-11-27T22:38:15.843Z" }, + { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584, upload-time = "2024-11-27T22:38:17.645Z" }, + { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875, upload-time = "2024-11-27T22:38:19.159Z" }, + { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418, upload-time = "2024-11-27T22:38:20.064Z" }, + { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708, upload-time = "2024-11-27T22:38:21.659Z" }, + { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582, upload-time = "2024-11-27T22:38:22.693Z" }, + { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543, upload-time = "2024-11-27T22:38:24.367Z" }, + { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691, upload-time = "2024-11-27T22:38:26.081Z" }, + { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170, upload-time = "2024-11-27T22:38:27.921Z" }, + { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530, upload-time = "2024-11-27T22:38:29.591Z" }, + { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666, upload-time = "2024-11-27T22:38:30.639Z" }, + { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954, upload-time = "2024-11-27T22:38:31.702Z" }, + { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724, upload-time = "2024-11-27T22:38:32.837Z" }, + { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383, upload-time = "2024-11-27T22:38:34.455Z" }, + { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257, upload-time = "2024-11-27T22:38:35.385Z" }, ] [[package]] @@ -241,9 +242,9 @@ source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.8'", ] -sdist = { url = "https://files.pythonhosted.org/packages/3c/8b/0111dd7d6c1478bf83baa1cab85c686426c7a6274119aceb2bd9d35395ad/typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2", size = 72876 } +sdist = { url = "https://files.pythonhosted.org/packages/3c/8b/0111dd7d6c1478bf83baa1cab85c686426c7a6274119aceb2bd9d35395ad/typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2", size = 72876, upload-time = "2023-07-02T14:20:55.045Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/6b/63cc3df74987c36fe26157ee12e09e8f9db4de771e0f3404263117e75b95/typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36", size = 33232 }, + { url = "https://files.pythonhosted.org/packages/ec/6b/63cc3df74987c36fe26157ee12e09e8f9db4de771e0f3404263117e75b95/typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36", size = 33232, upload-time = "2023-07-02T14:20:53.275Z" }, ] [[package]] @@ -253,16 +254,16 @@ source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.8'", ] -sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } +sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321, upload-time = "2024-06-07T18:52:15.995Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, + { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438, upload-time = "2024-06-07T18:52:13.582Z" }, ] [[package]] name = "zipp" version = "3.15.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/00/27/f0ac6b846684cecce1ee93d32450c45ab607f65c2e0255f0092032d91f07/zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b", size = 18454 } +sdist = { url = "https://files.pythonhosted.org/packages/00/27/f0ac6b846684cecce1ee93d32450c45ab607f65c2e0255f0092032d91f07/zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b", size = 18454, upload-time = "2023-02-25T02:17:22.503Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5b/fa/c9e82bbe1af6266adf08afb563905eb87cab83fde00a0a08963510621047/zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556", size = 6758 }, + { url = "https://files.pythonhosted.org/packages/5b/fa/c9e82bbe1af6266adf08afb563905eb87cab83fde00a0a08963510621047/zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556", size = 6758, upload-time = "2023-02-25T02:17:20.807Z" }, ] From a6b5c5d9494ede462fdf5b793f1a7bed1058559d Mon Sep 17 00:00:00 2001 From: Daniel Furtado Date: Wed, 19 Nov 2025 10:30:46 +0100 Subject: [PATCH 27/28] Added new section in the readme --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index c5ca538..ca8b757 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,11 @@ Dataclass CSV makes working with CSV files easier and much better than working w using a list of instances of a dataclass. +## Thanks + +Thank you to all the amazing contributors who have supported this project over the years, with special thanks to [@kraktus](https://github.com/kraktus) for setting up GitHub Actions, improving automation for package creation, and making numerous code enhancements. + + ## Installation ```shell From 02e60b4419314efde7e57cd1fc72e5ddc1e83296 Mon Sep 17 00:00:00 2001 From: Daniel Furtado Date: Wed, 19 Nov 2025 17:35:54 +0100 Subject: [PATCH 28/28] Fix workflow --- .github/workflows/test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 689a392..14ad007 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -24,9 +24,9 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - - name: Install uv and set the python version + - name: Checkout code + uses: actions/checkout@v4 + - name: Install uv and set the python version ${{ matrix.python-version }} uses: astral-sh/setup-uv@v5 with: python-version: ${{ matrix.python-version }}