Skip to content

Commit

Permalink
Support TypedDict field as Dict[str, Any]
Browse files Browse the repository at this point in the history
  • Loading branch information
isra17 committed Nov 11, 2022
1 parent 95117b0 commit 267e659
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 2 deletions.
1 change: 1 addition & 0 deletions changelog.d/237.change.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add `TypedDict` subclass support to fields. These are treated the same as `Dict[str, Any]`.
10 changes: 9 additions & 1 deletion src/desert/_make.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,11 +305,19 @@ def field_for_schema(
field = field_for_schema(newtype_supertype, default=default)

# enumerations
if type(typ) is enum.EnumMeta:
elif type(typ) is enum.EnumMeta:
import marshmallow_enum

field = marshmallow_enum.EnumField(typ, metadata=metadata)

# TypedDict
# TODO(python3.10) use t.is_typeddict
elif isinstance(typ, t._TypedDictMeta):
field = marshmallow.fields.Dict(
keys=marshmallow.fields.String,
values=marshmallow.fields.Raw,
)

# Nested dataclasses
forward_reference = getattr(typ, "__forward_arg__", None)

Expand Down
21 changes: 20 additions & 1 deletion tests/test_make.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,26 @@ class A:
assert_dump_load(schema=schema, loaded=loaded, dumped=dumped)


def test_typed_dict(
module: DataclassModule,
assert_dump_load: AssertLoadDumpProtocol,
) -> None:
"""Test dataclasses with basic TypedDict support"""

class B(t.TypedDict):
x: int

@module.dataclass
class A:
x: B

schema = desert.schema_class(A)()
dumped = {"x": {"x": 1}}
loaded = A(x={"x": 1})

assert_dump_load(schema=schema, loaded=loaded, dumped=dumped)


@pytest.mark.xfail(
strict=True,
reason=(
Expand Down Expand Up @@ -568,7 +588,6 @@ class A:
assert schema.loads(schema.dumps(loaded)) == loaded
assert schema.dump(schema.load(actually_dumped)) == actually_dumped


def test_only() -> None:
"""only() extracts the only item in an iterable."""
assert desert._make.only([1]) == 1
Expand Down

0 comments on commit 267e659

Please sign in to comment.