1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
From: =?utf-8?q?Sebasti=C3=A1n_Ram=C3=ADrez?= <tiangolo@gmail.com>
Date: Sun, 25 Jan 2026 17:09:50 +0100
Subject: =?utf-8?q?=E2=99=BB=EF=B8=8F_Fix_compatibility_with_Python_3=2E8?=
Origin: https://github.com/art049/odmantic/pull/546/commits/ed3b316f8e17cb7d27b896aa3002138da22b186c
Forwarded: not-needed
---
odmantic/typing.py | 38 ++++++++++++++++++++++++++++----------
1 file changed, 28 insertions(+), 10 deletions(-)
diff --git a/odmantic/typing.py b/odmantic/typing.py
index 61a715d..5641b75 100644
--- a/odmantic/typing.py
+++ b/odmantic/typing.py
@@ -18,15 +18,29 @@ import typing
import types
from typing import Callable as TypingCallable
-# Copy from Pydantic: pydantic/_internal/_typing_extra.py
+# Copy from Pydantic: pydantic/v1/typing.py
+# This can probably be replaced by the logic in: pydantic/_internal/_typing_extra.py
+# after dropping support for Python 3.8 and 3.9
+try:
+ from typing import GenericAlias as TypingGenericAlias # type: ignore
+except ImportError:
+ # python < 3.9 does not have GenericAlias (list[int], tuple[str, ...] and so on)
+ TypingGenericAlias = ()
if sys.version_info < (3, 10):
- WithArgsTypes: tuple[Any, ...] = (typing._GenericAlias, types.GenericAlias) # type: ignore[attr-defined]
+
+ def is_union(tp: Union[Type[Any], None]) -> bool:
+ return tp is Union
+
+ WithArgsTypes = (TypingGenericAlias,)
+
else:
- WithArgsTypes: tuple[Any, ...] = (
- typing._GenericAlias,
- types.GenericAlias,
- types.UnionType,
- )
+ import types
+ import typing
+
+ def is_union(tp: Union[Type[Any], None]) -> bool:
+ return tp is Union or tp is types.UnionType # noqa: E721
+
+ WithArgsTypes = (typing._GenericAlias, types.GenericAlias, types.UnionType)
if sys.version_info < (3, 11):
@@ -60,7 +74,7 @@ if TYPE_CHECKING:
def lenient_issubclass(
- cls: Any, class_or_tuple: Union[type[Any], tuple[type[Any], ...], None]
+ cls: Any, class_or_tuple: Union[Type[Any], Tuple[Type[Any], ...], None]
) -> bool:
# Copy of Pydantic: pydantic/_internal/_utils.py
try:
@@ -70,6 +84,7 @@ def lenient_issubclass(
return False
raise # pragma: no cover
+
def _check_classvar(v: Union[Type[Any], None]) -> bool:
# Copy of Pydantic: pydantic/v1/typing.py
# This can probably be replaced by the logic in: pydantic/_internal/_typing_extra.py
@@ -77,7 +92,8 @@ def _check_classvar(v: Union[Type[Any], None]) -> bool:
if v is None:
return False
- return v.__class__ == ClassVar.__class__ and getattr(v, '_name', None) == 'ClassVar'
+ return v.__class__ == ClassVar.__class__ and getattr(v, "_name", None) == "ClassVar"
+
def is_classvar(ann_type: Type[Any]) -> bool:
# Copy of Pydantic: pydantic/v1/typing.py
@@ -88,7 +104,9 @@ def is_classvar(ann_type: Type[Any]) -> bool:
# this is an ugly workaround for class vars that contain forward references and are therefore themselves
# forward references, see #3679
- if ann_type.__class__ == ForwardRef and ann_type.__forward_arg__.startswith('ClassVar['):
+ if ann_type.__class__ == ForwardRef and ann_type.__forward_arg__.startswith(
+ "ClassVar["
+ ):
return True
return False
|