Skip to content

Commit

Permalink
fix _generic_type_add_any
Browse files Browse the repository at this point in the history
do not use equality check to support `collections.abc.xxx` types
  • Loading branch information
anis-campos committed Sep 5, 2023
1 parent 06f0660 commit 96758bf
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 15 deletions.
46 changes: 31 additions & 15 deletions marshmallow_dataclass/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -478,23 +478,39 @@ def _field_by_supertype(
base_schema=base_schema,
typ_frame=typ_frame,
)


def _generic_type_add_any(typ: type) -> type:
"""if typ is generic type without arguments, replace them by Any."""
if typ is list or typ is List:
typ = List[Any]
elif typ is dict or typ is Dict:
typ = Dict[Any, Any]
elif typ is Mapping:
typ = Mapping[Any, Any]
elif typ is Sequence:
typ = Sequence[Any]
elif typ is set or typ is Set:
typ = Set[Any]
elif typ is frozenset or typ is FrozenSet:
typ = FrozenSet[Any]
return typ
if sys.version_info >= (3, 9):
# supports the collections.abc generic type
if not typing_inspect.get_args(typ):
if issubclass(typ, List):
typ = List[Any]
elif issubclass(typ, Dict):
typ = Dict[Any, Any]
elif issubclass(typ, Mapping):
typ = Mapping[Any, Any]
elif issubclass(typ, Sequence):
typ = Sequence[Any]
elif issubclass(typ, Set):
typ = Set[Any]
elif issubclass(typ, FrozenSet):
typ = FrozenSet[Any]
return typ
else:
if typ is list or typ is List:
typ = List[Any]
elif typ is dict or typ is Dict:
typ = Dict[Any, Any]
elif typ is Mapping:
typ = Mapping[Any, Any]
elif typ is Sequence:
typ = Sequence[Any]
elif typ is set or typ is Set:
typ = Set[Any]
elif typ is frozenset or typ is FrozenSet:
typ = FrozenSet[Any]
return typ



def _field_for_generic_type(
Expand Down
33 changes: 33 additions & 0 deletions tests/test_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,39 @@ class AnyMapping:
)
self.assertEqual(schema.dump(loaded), data_in)

@unittest.skipIf(sys.version_info < (3, 9), "PEP 585 unsupported")
def test_collections_mapping_no_arg(self):
import collections.abc

@dataclass
class AnyMapping:
value: collections.abc.Mapping

schema = AnyMapping.Schema()

# can load a sequence of mixed kind
data_in = {
"value": {
1: "a number key a str value",
"a str key a number value": 2,
None: "this is still valid",
"even this": None,
}
}
loaded = schema.load(data_in)
self.assertEqual(
loaded,
AnyMapping(
value={
1: "a number key a str value",
"a str key a number value": 2,
None: "this is still valid",
"even this": None,
}
),
)
self.assertEqual(schema.dump(loaded), data_in)

def test_mapping_of_frozen_dataclass(self):
@dataclass(frozen=True)
class Elm:
Expand Down

0 comments on commit 96758bf

Please sign in to comment.