|
1 | 1 | import sys |
| 2 | +from collections.abc import Callable, Set |
2 | 3 | from datetime import date, datetime, timezone |
3 | 4 | from enum import Enum, IntEnum, unique |
4 | 5 | from json import dumps as json_dumps |
|
31 | 32 | text, |
32 | 33 | ) |
33 | 34 |
|
| 35 | +from cattrs import Converter |
34 | 36 | from cattrs._compat import ( |
35 | | - AbstractSet, |
36 | 37 | Counter, |
37 | 38 | FrozenSet, |
38 | 39 | Mapping, |
39 | 40 | MutableMapping, |
40 | 41 | MutableSequence, |
41 | 42 | MutableSet, |
42 | 43 | Sequence, |
43 | | - Set, |
44 | 44 | TupleSubscriptable, |
45 | 45 | ) |
46 | 46 | from cattrs.fns import identity |
47 | 47 | from cattrs.preconf.bson import make_converter as bson_make_converter |
48 | 48 | from cattrs.preconf.cbor2 import make_converter as cbor2_make_converter |
49 | 49 | from cattrs.preconf.json import make_converter as json_make_converter |
50 | 50 | from cattrs.preconf.msgpack import make_converter as msgpack_make_converter |
| 51 | +from cattrs.preconf.pyyaml import make_converter as pyyaml_make_converter |
51 | 52 | from cattrs.preconf.tomlkit import make_converter as tomlkit_make_converter |
52 | 53 | from cattrs.preconf.ujson import make_converter as ujson_make_converter |
53 | 54 |
|
@@ -301,7 +302,7 @@ def test_stdlib_json_converter(everything: Everything): |
301 | 302 |
|
302 | 303 | @given(everythings()) |
303 | 304 | def test_stdlib_json_converter_unstruct_collection_overrides(everything: Everything): |
304 | | - converter = json_make_converter(unstruct_collection_overrides={AbstractSet: sorted}) |
| 305 | + converter = json_make_converter(unstruct_collection_overrides={Set: sorted}) |
305 | 306 | raw = converter.unstructure(everything) |
306 | 307 | assert raw["a_set"] == sorted(raw["a_set"]) |
307 | 308 | assert raw["a_mutable_set"] == sorted(raw["a_mutable_set"]) |
@@ -395,9 +396,7 @@ def test_ujson_converter(everything: Everything): |
395 | 396 | ) |
396 | 397 | ) |
397 | 398 | def test_ujson_converter_unstruct_collection_overrides(everything: Everything): |
398 | | - converter = ujson_make_converter( |
399 | | - unstruct_collection_overrides={AbstractSet: sorted} |
400 | | - ) |
| 399 | + converter = ujson_make_converter(unstruct_collection_overrides={Set: sorted}) |
401 | 400 | raw = converter.unstructure(everything) |
402 | 401 | assert raw["a_set"] == sorted(raw["a_set"]) |
403 | 402 | assert raw["a_mutable_set"] == sorted(raw["a_mutable_set"]) |
@@ -484,9 +483,7 @@ def test_orjson_converter(everything: Everything, detailed_validation: bool): |
484 | 483 | def test_orjson_converter_unstruct_collection_overrides(everything: Everything): |
485 | 484 | from cattrs.preconf.orjson import make_converter as orjson_make_converter |
486 | 485 |
|
487 | | - converter = orjson_make_converter( |
488 | | - unstruct_collection_overrides={AbstractSet: sorted} |
489 | | - ) |
| 486 | + converter = orjson_make_converter(unstruct_collection_overrides={Set: sorted}) |
490 | 487 | raw = converter.unstructure(everything) |
491 | 488 | assert raw["a_set"] == sorted(raw["a_set"]) |
492 | 489 | assert raw["a_mutable_set"] == sorted(raw["a_mutable_set"]) |
@@ -568,9 +565,7 @@ def test_msgpack_converter(everything: Everything): |
568 | 565 |
|
569 | 566 | @given(everythings(min_int=-9223372036854775808, max_int=18446744073709551615)) |
570 | 567 | def test_msgpack_converter_unstruct_collection_overrides(everything: Everything): |
571 | | - converter = msgpack_make_converter( |
572 | | - unstruct_collection_overrides={AbstractSet: sorted} |
573 | | - ) |
| 568 | + converter = msgpack_make_converter(unstruct_collection_overrides={Set: sorted}) |
574 | 569 | raw = converter.unstructure(everything) |
575 | 570 | assert raw["a_set"] == sorted(raw["a_set"]) |
576 | 571 | assert raw["a_mutable_set"] == sorted(raw["a_mutable_set"]) |
@@ -663,7 +658,7 @@ def test_bson_converter(everything: Everything, detailed_validation: bool): |
663 | 658 | ) |
664 | 659 | ) |
665 | 660 | def test_bson_converter_unstruct_collection_overrides(everything: Everything): |
666 | | - converter = bson_make_converter(unstruct_collection_overrides={AbstractSet: sorted}) |
| 661 | + converter = bson_make_converter(unstruct_collection_overrides={Set: sorted}) |
667 | 662 | raw = converter.unstructure(everything) |
668 | 663 | assert raw["a_set"] == sorted(raw["a_set"]) |
669 | 664 | assert raw["a_mutable_set"] == sorted(raw["a_mutable_set"]) |
@@ -755,9 +750,7 @@ def test_tomlkit_converter(everything: Everything, detailed_validation: bool): |
755 | 750 | ) |
756 | 751 | ) |
757 | 752 | def test_tomlkit_converter_unstruct_collection_overrides(everything: Everything): |
758 | | - converter = tomlkit_make_converter( |
759 | | - unstruct_collection_overrides={AbstractSet: sorted} |
760 | | - ) |
| 753 | + converter = tomlkit_make_converter(unstruct_collection_overrides={Set: sorted}) |
761 | 754 | raw = converter.unstructure(everything) |
762 | 755 | assert raw["a_set"] == sorted(raw["a_set"]) |
763 | 756 | assert raw["a_mutable_set"] == sorted(raw["a_mutable_set"]) |
@@ -797,9 +790,7 @@ def test_cbor2_converter(everything: Everything): |
797 | 790 |
|
798 | 791 | @given(everythings(min_int=-9223372036854775808, max_int=18446744073709551615)) |
799 | 792 | def test_cbor2_converter_unstruct_collection_overrides(everything: Everything): |
800 | | - converter = cbor2_make_converter( |
801 | | - unstruct_collection_overrides={AbstractSet: sorted} |
802 | | - ) |
| 793 | + converter = cbor2_make_converter(unstruct_collection_overrides={Set: sorted}) |
803 | 794 | raw = converter.unstructure(everything) |
804 | 795 | assert raw["a_set"] == sorted(raw["a_set"]) |
805 | 796 | assert raw["a_mutable_set"] == sorted(raw["a_mutable_set"]) |
@@ -856,9 +847,7 @@ def test_msgspec_json_unstruct_collection_overrides(everything: Everything): |
856 | 847 | """Ensure collection overrides work.""" |
857 | 848 | from cattrs.preconf.msgspec import make_converter as msgspec_make_converter |
858 | 849 |
|
859 | | - converter = msgspec_make_converter( |
860 | | - unstruct_collection_overrides={AbstractSet: sorted} |
861 | | - ) |
| 850 | + converter = msgspec_make_converter(unstruct_collection_overrides={Set: sorted}) |
862 | 851 | raw = converter.unstructure(everything) |
863 | 852 | assert raw["a_set"] == sorted(raw["a_set"]) |
864 | 853 | assert raw["a_mutable_set"] == sorted(raw["a_mutable_set"]) |
@@ -913,3 +902,39 @@ def test_msgspec_efficient_enum(): |
913 | 902 | converter.get_unstructure_hook(fields(Everything).a_literal_with_bare.type) |
914 | 903 | == identity |
915 | 904 | ) |
| 905 | + |
| 906 | + |
| 907 | +@pytest.mark.parametrize( |
| 908 | + "converter_factory", |
| 909 | + [ |
| 910 | + bson_make_converter, |
| 911 | + cbor2_make_converter, |
| 912 | + json_make_converter, |
| 913 | + msgpack_make_converter, |
| 914 | + tomlkit_make_converter, |
| 915 | + ujson_make_converter, |
| 916 | + pyyaml_make_converter, |
| 917 | + ], |
| 918 | +) |
| 919 | +def test_literal_dicts(converter_factory: Callable[[], Converter]): |
| 920 | + """Dicts with keys that aren't subclasses of `type` work.""" |
| 921 | + converter = converter_factory() |
| 922 | + |
| 923 | + assert converter.structure({"a": 1}, Dict[Literal["a"], int]) == {"a": 1} |
| 924 | + assert converter.unstructure({"a": 1}, Dict[Literal["a"], int]) == {"a": 1} |
| 925 | + |
| 926 | + |
| 927 | +@pytest.mark.skipif(NO_ORJSON, reason="orjson not available") |
| 928 | +def test_literal_dicts_orjson(): |
| 929 | + """Dicts with keys that aren't subclasses of `type` work.""" |
| 930 | + from cattrs.preconf.orjson import make_converter as orjson_make_converter |
| 931 | + |
| 932 | + test_literal_dicts(orjson_make_converter) |
| 933 | + |
| 934 | + |
| 935 | +@pytest.mark.skipif(NO_MSGSPEC, reason="msgspec not available") |
| 936 | +def test_literal_dicts_msgspec(): |
| 937 | + """Dicts with keys that aren't subclasses of `type` work.""" |
| 938 | + from cattrs.preconf.msgspec import make_converter as msgspec_make_converter |
| 939 | + |
| 940 | + test_literal_dicts(msgspec_make_converter) |
0 commit comments