diff --git a/odmantic/model.py b/odmantic/model.py index 08308f29..87c0bec2 100644 --- a/odmantic/model.py +++ b/odmantic/model.py @@ -4,6 +4,7 @@ import decimal import enum import pathlib +import types import uuid from abc import ABCMeta from collections.abc import Callable as abcCallable @@ -193,7 +194,7 @@ def validate_type(type_: Type) -> Type: # FIXME: remove this hack when a better solution to handle dynamic # generics is found # https://github.com/pydantic/pydantic/issues/8354 - if type_origin is Union: + if type_origin is Union or type_origin is getattr(types, "UnionType", Union): # as new_arg_types is a tuple, we can directly create a matching Union # instance, instead of hacking our way around it: # https://stackoverflow.com/a/72884529/3784643 diff --git a/tests/unit/test_model_definition.py b/tests/unit/test_model_definition.py index 698090f3..8b69089f 100644 --- a/tests/unit/test_model_definition.py +++ b/tests/unit/test_model_definition.py @@ -528,3 +528,15 @@ class Person(Model): "hashed_password": "hashed_password", } Person(**user) + + +@pytest.mark.skipif( + sys.version_info[:3] < (3, 10, 0), + reason="Union syntax not supported by python < 3.10", +) +def test_model_with_p310_union_syntax(): + class M(Model): + f: int | str # type: ignore[syntax] + + assert M(f=1).f == 1 + assert M(f="hello").f == "hello"