Skip to content

Commit c4ab066

Browse files
authored
More tests (#613)
* Improve cols coverage * Test the tests * Improve typeddict coverage * Improve disambiguators coverage * preconf: test bare dicts * test_preconf: always include bools and ints * More factories with `takes_self` * Fix return type annotations
1 parent a67ebd0 commit c4ab066

19 files changed

+157
-88
lines changed

src/cattrs/preconf/bson.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def configure_converter(converter: BaseConverter):
6161
* a deserialization hook is registered for bson.ObjectId by default
6262
* string and int enums are passed through when unstructuring
6363
64-
.. versionchanged: 24.2.0
64+
.. versionchanged:: 24.2.0
6565
Enums are left to the library to unstructure, speeding them up.
6666
"""
6767

src/cattrs/preconf/json.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def configure_converter(converter: BaseConverter):
3636
* union passthrough is configured for unions of strings, bools, ints,
3737
floats and None
3838
39-
.. versionchanged: 24.2.0
39+
.. versionchanged:: 24.2.0
4040
Enums are left to the library to unstructure, speeding them up.
4141
"""
4242
converter.register_unstructure_hook(

src/cattrs/preconf/msgpack.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def configure_converter(converter: BaseConverter):
3131
* sets are serialized as lists
3232
* string and int enums are passed through when unstructuring
3333
34-
.. versionchanged: 24.2.0
34+
.. versionchanged:: 24.2.0
3535
Enums are left to the library to unstructure, speeding them up.
3636
"""
3737
converter.register_unstructure_hook(datetime, lambda v: v.timestamp())

src/cattrs/preconf/msgspec.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def configure_converter(converter: Converter) -> None:
7575
* union passthrough configured for str, bool, int, float and None
7676
* bare, string and int enums are passed through when unstructuring
7777
78-
.. versionchanged: 24.2.0
78+
.. versionchanged:: 24.2.0
7979
Enums are left to the library to unstructure, speeding them up.
8080
"""
8181
configure_passthroughs(converter)

src/cattrs/preconf/orjson.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
from .._compat import is_subclass
1313
from ..cols import is_mapping, is_namedtuple, namedtuple_unstructure_factory
14-
from ..converters import BaseConverter, Converter
14+
from ..converters import Converter
1515
from ..fns import identity
1616
from ..literals import is_literal_containing_enums
1717
from ..strategies import configure_union_passthrough
@@ -28,7 +28,7 @@ def loads(self, data: Union[bytes, bytearray, memoryview, str], cl: type[T]) ->
2828
return self.structure(loads(data), cl)
2929

3030

31-
def configure_converter(converter: BaseConverter):
31+
def configure_converter(converter: Converter):
3232
"""
3333
Configure the converter for use with the orjson library.
3434
@@ -40,9 +40,9 @@ def configure_converter(converter: BaseConverter):
4040
* mapping keys are coerced into strings when unstructuring
4141
* bare, string and int enums are passed through when unstructuring
4242
43-
.. versionchanged: 24.1.0
43+
.. versionchanged:: 24.1.0
4444
Add support for typed namedtuples.
45-
.. versionchanged: 24.2.0
45+
.. versionchanged:: 24.2.0
4646
Enums are left to the library to unstructure, speeding them up.
4747
"""
4848
converter.register_unstructure_hook(
@@ -53,7 +53,7 @@ def configure_converter(converter: BaseConverter):
5353
converter.register_structure_hook(datetime, lambda v, _: datetime.fromisoformat(v))
5454
converter.register_structure_hook(date, lambda v, _: date.fromisoformat(v))
5555

56-
def gen_unstructure_mapping(cl: Any, unstructure_to=None):
56+
def unstructure_mapping_factory(cl: Any, unstructure_to=None):
5757
key_handler = str
5858
args = getattr(cl, "__args__", None)
5959
if args:
@@ -77,7 +77,7 @@ def key_handler(v):
7777

7878
converter._unstructure_func.register_func_list(
7979
[
80-
(is_mapping, gen_unstructure_mapping, True),
80+
(is_mapping, unstructure_mapping_factory, True),
8181
(
8282
is_namedtuple,
8383
partial(namedtuple_unstructure_factory, unstructure_to=tuple),

src/cattrs/preconf/pyyaml.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def configure_converter(converter: BaseConverter):
3838
* datetimes and dates are validated
3939
* typed namedtuples are serialized as lists
4040
41-
.. versionchanged: 24.1.0
41+
.. versionchanged:: 24.1.0
4242
Add support for typed namedtuples.
4343
"""
4444
converter.register_unstructure_hook(

src/cattrs/preconf/ujson.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def configure_converter(converter: BaseConverter):
3333
* sets are serialized as lists
3434
* string and int enums are passed through when unstructuring
3535
36-
.. versionchanged: 24.2.0
36+
.. versionchanged:: 24.2.0
3737
Enums are left to the library to unstructure, speeding them up.
3838
"""
3939
converter.register_unstructure_hook(

tests/__init__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
import os
2+
from typing import Literal
23

34
from hypothesis import HealthCheck, settings
45
from hypothesis.strategies import just, one_of
6+
from typing_extensions import TypeAlias
57

68
from cattrs import UnstructureStrategy
79

810
settings.register_profile(
911
"CI", settings(suppress_health_check=[HealthCheck.too_slow]), deadline=None
1012
)
1113

12-
if "CI" in os.environ:
14+
if "CI" in os.environ: # pragma: nocover
1315
settings.load_profile("CI")
1416

1517
unstructure_strats = one_of(just(s) for s in UnstructureStrategy)
18+
19+
FeatureFlag: TypeAlias = Literal["always", "never", "sometimes"]

tests/test_defaultdicts.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing import DefaultDict
55

66
from cattrs import Converter
7+
from cattrs.cols import defaultdict_structure_factory
78

89

910
def test_typing_defaultdicts(genconverter: Converter):
@@ -30,3 +31,16 @@ def test_collection_defaultdicts(genconverter: Converter):
3031
genconverter.register_unstructure_hook(int, str)
3132

3233
assert genconverter.unstructure(res) == {"a": "1", "b": "0"}
34+
35+
36+
def test_factory(genconverter: Converter):
37+
"""Explicit factories work."""
38+
genconverter.register_structure_hook_func(
39+
lambda t: t == defaultdict[str, int],
40+
defaultdict_structure_factory(defaultdict[str, int], genconverter, lambda: 2),
41+
)
42+
res = genconverter.structure({"a": 1}, defaultdict[str, int])
43+
44+
assert isinstance(res, defaultdict)
45+
assert res["a"] == 1
46+
assert res["b"] == 2

tests/test_disambiguators.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,7 @@ class A:
130130
assert fn({}) is A
131131
assert fn(asdict(cl(*vals, **kwargs))) is cl
132132

133-
attr_names = {a.name for a in fields(cl)}
134-
135-
if "xyz" not in attr_names:
136-
assert fn({"xyz": 1}) is A # Uses the fallback.
133+
assert fn({"xyz": 1}) is A # Uses the fallback.
137134

138135

139136
@settings(suppress_health_check=[HealthCheck.filter_too_much, HealthCheck.too_slow])

0 commit comments

Comments
 (0)