Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ jobs:
steps:
- uses: actions/checkout@v3

# We use Python 3.7 here because it's the minimum Python version supported by this library.
- name: Setup Python 3.7
# We use Python 3.8 here because it's the minimum Python version supported by this library.
- name: Setup Python 3.8
uses: actions/setup-python@v4
with:
python-version: 3.7
python-version: 3.8

- name: Install dependencies
run: pip install --upgrade pip build
Expand All @@ -42,10 +42,10 @@ jobs:
steps:
- uses: actions/checkout@v3

- name: Setup Python 3.7
- name: Setup Python 3.8
uses: actions/setup-python@v4
with:
python-version: 3.7
python-version: 3.8

- name: Download build artifacts
uses: actions/download-artifact@v3
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ jobs:
fail-fast: false
matrix:
python-version:
- '3.7'
- '3.8'
- '3.9'
- '3.10'
Expand Down
5 changes: 1 addition & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ docker-tox:
tox run --workdir .tox_docker $(TOX_ARGS)

# Run partial tox test suites in Docker
.PHONY: docker-tox-py312 docker-tox-py311 docker-tox-py310 docker-tox-py39 docker-tox-py38 docker-tox-py37
.PHONY: docker-tox-py312 docker-tox-py311 docker-tox-py310 docker-tox-py39 docker-tox-py38
docker-tox-py312: TOX_ARGS="-e clean,py312,py312-report"
docker-tox-py312: docker-tox
docker-tox-py311: TOX_ARGS="-e clean,py311,py311-report"
Expand All @@ -72,13 +72,10 @@ docker-tox-py39: TOX_ARGS="-e clean,py39,py39-report"
docker-tox-py39: docker-tox
docker-tox-py38: TOX_ARGS="-e clean,py38,py38-report"
docker-tox-py38: docker-tox
docker-tox-py37: TOX_ARGS="-e clean,py37,py37-report"
docker-tox-py37: docker-tox

# Run all tox test suites, but separately to check code coverage individually
.PHONY: docker-tox-all
docker-tox-all:
make docker-tox-py37
make docker-tox-py38
make docker-tox-py39
make docker-tox-py310
Expand Down
6 changes: 0 additions & 6 deletions docs/05-dataclasses.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,9 +368,6 @@ class ExampleDataclass:
To set a default value for a field using the `@validataclass` decorator, you have to define the field as a **tuple**
consisting of the validator and a `Default` object, e.g. `IntegerValidator(), Default(42)`.

Please note that in Python 3.7 for some reason these tuples require parentheses (see example). Unless you're writing
code for Python 3.7, it is recommended to omit the parentheses for a more consistent look, though.

**Example:**

```python
Expand All @@ -381,9 +378,6 @@ from validataclass.validators import IntegerValidator
class ExampleDataclass:
example_field: int = IntegerValidator()
optional_field: int = IntegerValidator(), Default(42)

# Compatibility note: In Python 3.7 parentheses are required when using the tuple notation:
optional_field2: int = (IntegerValidator(), Default(42))
```


Expand Down
3 changes: 1 addition & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ classifiers =
License :: OSI Approved :: MIT License
Operating System :: OS Independent
Programming Language :: Python :: 3
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Expand All @@ -31,7 +30,7 @@ classifiers =
package_dir =
= src
packages = find:
python_requires = >=3.7
python_requires = >=3.8
install_requires =
typing-extensions ~= 4.3
python-dateutil
Expand Down
11 changes: 6 additions & 5 deletions src/validataclass/dataclasses/validataclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,19 @@ def validataclass(cls: Type[_T]) -> Type[_T]:


@overload
def validataclass(cls: None = None, **kwargs) -> Callable[[Type[_T]], Type[_T]]:
def validataclass(cls: None = None, /, **kwargs) -> Callable[[Type[_T]], Type[_T]]:
...


@dataclass_transform(
kw_only_default=True,
field_specifiers=(dataclasses.field, dataclasses.Field, validataclass_field),
)
def validataclass(cls: Optional[Type[_T]] = None, **kwargs) -> Union[Type[_T], Callable[[Type[_T]], Type[_T]]]:
def validataclass(
cls: Optional[Type[_T]] = None,
/,
**kwargs,
) -> Union[Type[_T], Callable[[Type[_T]], Type[_T]]]:
"""
Decorator that turns a normal class into a DataclassValidator-compatible dataclass.

Expand Down Expand Up @@ -67,9 +71,6 @@ class ExampleDataclass:
example_field3: str = validataclass_field(StringValidator()) # Same as example_field1
example_field4: str = validataclass_field(StringValidator(), default='not set') # Same as example_field2
post_init_field: int = field(init=False, default=0) # Post-init field without validator

# COMPATIBILITY NOTE: In Python 3.7 parentheses are required when setting a Default using the tuple notation:
# field_with_default: str = (StringValidator(), Default('not set'))
```

Note: As of now, InitVars are not supported because they are not recognized as proper fields. This might change in a
Expand Down
3 changes: 0 additions & 3 deletions src/validataclass/validators/dataclass_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,6 @@ class ExampleDataclass:
example_field: str = StringValidator()
optional_field: str = StringValidator(), Default('')

# Compatibility note: In Python 3.7 parentheses are required when setting a Default using the tuple notation:
# optional_field: str = (StringValidator(), Default(''))

# Equivalent definition using validataclass_field():
# example_field: str = validataclass_field(StringValidator())
# optional_field: str = validataclass_field(StringValidator(), default='')
Expand Down
12 changes: 6 additions & 6 deletions tests/dataclasses/validataclass_mixin_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
@validataclass
class UnitTestDataclass(ValidataclassMixin):
foo: int = IntegerValidator() # required field
bar: str = (StringValidator(), Default('bloop'))
baz: OptionalUnset[Decimal] = (DecimalValidator(), DefaultUnset)
bar: str = StringValidator(), Default('bloop')
baz: OptionalUnset[Decimal] = DecimalValidator(), DefaultUnset


class ValidataclassMixinTest:
Expand All @@ -27,7 +27,7 @@ class ValidataclassMixinTest:

@staticmethod
def test_validataclass_to_dict():
""" Tests the to_dict() method of the ValidataclassMixin class using the regular constructor. """
""" Tests ValidataclassMixin.to_dict() using the regular constructor. """
obj = UnitTestDataclass(foo=42, bar='meep', baz=Decimal('-1.23'))
assert obj.to_dict() == {
'foo': 42,
Expand All @@ -37,7 +37,7 @@ def test_validataclass_to_dict():

@staticmethod
def test_validataclass_to_dict_validated():
""" Tests the to_dict() method of the ValidataclassMixin class using a DataclassValidator. """
""" Tests ValidataclassMixin.to_dict() using a DataclassValidator. """
validator = DataclassValidator(UnitTestDataclass)
obj: UnitTestDataclass = validator.validate({'foo': 42, 'bar': 'meep', 'baz': '-1.23'})
assert obj.to_dict() == {
Expand All @@ -48,7 +48,7 @@ def test_validataclass_to_dict_validated():

@staticmethod
def test_validataclass_to_dict_validated_with_defaults():
""" Tests the to_dict() method of the ValidataclassMixin class using a DataclassValidator, with default values. """
""" Tests ValidataclassMixin.to_dict() using a DataclassValidator, with default values. """
validator = DataclassValidator(UnitTestDataclass)
obj: UnitTestDataclass = validator.validate({'foo': 42})
assert obj.to_dict() == {
Expand All @@ -58,7 +58,7 @@ def test_validataclass_to_dict_validated_with_defaults():

@staticmethod
def test_validataclass_to_dict_validated_keep_unset_values():
""" Tests the to_dict() method of the ValidataclassMixin class with the parameter keep_unset_value=True. """
""" Tests ValidataclassMixin.to_dict() with the parameter keep_unset_value=True. """
validator = DataclassValidator(UnitTestDataclass)
obj: UnitTestDataclass = validator.validate({'foo': 42})
obj_as_dict = obj.to_dict(keep_unset_values=True)
Expand Down
Loading