Skip to content

Commit e3da9a8

Browse files
committed
Added proposal to allow less strict TypedDicts.
1 parent dd71b87 commit e3da9a8

1 file changed

Lines changed: 20 additions & 17 deletions

File tree

src/quart_schema/conversion.py

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import sys
44
from dataclasses import fields, is_dataclass
55
from inspect import isclass
6-
from typing import Any, Literal, TypeGuard, TypeVar
6+
from typing import Any, get_origin, Literal, TypeGuard, TypeVar
77

88
import humps
99
from quart import current_app
@@ -255,31 +255,34 @@ def _is_list_or_dict(type_: type) -> bool:
255255
return origin in (dict, dict, list, list)
256256

257257

258+
def _valid_model_class(model_class: type) -> bool:
259+
"""Validate if a type can be used as a schema class.
260+
261+
Returns True for types that don't require conversion:
262+
- TypedDict, dataclasses, and attrs classes
263+
- Built-in dict/list and their generic aliases (e.g., dict[str, int])
264+
"""
265+
if (
266+
_is_list_or_dict(model_class)
267+
or is_dataclass(model_class)
268+
or is_typeddict(model_class)
269+
or dict in getattr(get_origin(model_class), "__mro__", ())
270+
):
271+
return True
272+
return False
273+
274+
258275
def _use_pydantic(model_class: type, preference: str | None) -> bool:
259276
return PYDANTIC_INSTALLED and (
260277
is_pydantic_dataclass(model_class)
261278
or (isclass(model_class) and issubclass(model_class, BaseModel))
262-
or (
263-
(
264-
_is_list_or_dict(model_class)
265-
or is_dataclass(model_class)
266-
or is_typeddict(model_class)
267-
)
268-
and preference != "msgspec"
269-
)
279+
or (_valid_model_class(model_class) and preference != "msgspec")
270280
)
271281

272282

273283
def _use_msgspec(model_class: type, preference: str | None) -> bool:
274284
return MSGSPEC_INSTALLED and (
275285
(isclass(model_class) and issubclass(model_class, Struct))
276286
or is_attrs(model_class)
277-
or (
278-
(
279-
_is_list_or_dict(model_class)
280-
or is_dataclass(model_class)
281-
or is_typeddict(model_class)
282-
)
283-
and preference != "pydantic"
284-
)
287+
or (_valid_model_class(model_class) and preference != "pydantic")
285288
)

0 commit comments

Comments
 (0)