Skip to content

Commit 62f510a

Browse files
committed
Support TypedDict field as Dict[str, Any]
1 parent 95117b0 commit 62f510a

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

changelog.d/237.change.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add `TypedDict` subclass support to fields. These are treated the same as `Dict[str, Any]`.

src/desert/_make.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,11 +305,18 @@ def field_for_schema(
305305
field = field_for_schema(newtype_supertype, default=default)
306306

307307
# enumerations
308-
if type(typ) is enum.EnumMeta:
308+
elif type(typ) is enum.EnumMeta:
309309
import marshmallow_enum
310310

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

313+
# TypedDict
314+
elif typing_inspect.typed_dict_keys(typ) is not None:
315+
field = marshmallow.fields.Dict(
316+
keys=marshmallow.fields.String,
317+
values=marshmallow.fields.Raw,
318+
)
319+
313320
# Nested dataclasses
314321
forward_reference = getattr(typ, "__forward_arg__", None)
315322

tests/test_make.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ def dataclass_param(request: _pytest.fixtures.SubRequest) -> DataclassModule:
4545
return module
4646

4747

48+
@pytest.fixture
49+
def typeddict() -> None:
50+
try:
51+
from typing import TypedDict
52+
except ImportError:
53+
raise pytest.skip("No TypedDict support")
54+
55+
4856
class AssertLoadDumpProtocol(typing_extensions.Protocol):
4957
def __call__(
5058
self, schema: marshmallow.Schema, loaded: t.Any, dumped: t.Dict[t.Any, t.Any]
@@ -437,6 +445,27 @@ class A:
437445
assert_dump_load(schema=schema, loaded=loaded, dumped=dumped)
438446

439447

448+
def test_typeddict(
449+
module: DataclassModule,
450+
assert_dump_load: AssertLoadDumpProtocol,
451+
typeddict: None,
452+
) -> None:
453+
"""Test dataclasses with basic TypedDict support"""
454+
455+
class B(t.TypedDict):
456+
x: int
457+
458+
@module.dataclass
459+
class A:
460+
x: B
461+
462+
schema = desert.schema_class(A)()
463+
dumped = {"x": {"x": 1}}
464+
loaded = A(x={"x": 1}) # type: ignore[call-arg]
465+
466+
assert_dump_load(schema=schema, loaded=loaded, dumped=dumped)
467+
468+
440469
@pytest.mark.xfail(
441470
strict=True,
442471
reason=(

0 commit comments

Comments
 (0)