You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
175 lines
5.3 KiB
175 lines
5.3 KiB
From: PrettyWood <em.jolibois@gmail.com>
|
|
Date: Tue, 10 Aug 2021 18:00:16 +0200
|
|
Subject: [PATCH 1/2] refactor: rename `is_union` into `is_union_origin`
|
|
https://github.com/samuelcolvin/pydantic/pull/3085
|
|
|
|
--- a/pydantic/fields.py
|
|
+++ b/pydantic/fields.py
|
|
@@ -41,7 +41,7 @@
|
|
is_literal_type,
|
|
is_new_type,
|
|
is_typeddict,
|
|
- is_union,
|
|
+ is_union_origin,
|
|
new_type_supertype,
|
|
)
|
|
from .utils import PyObjectStr, Representation, ValueItems, lenient_issubclass, sequence_like, smart_deepcopy
|
|
@@ -557,7 +557,7 @@ def _type_analysis(self) -> None: # noqa: C901 (ignore complexity)
|
|
return
|
|
if origin is Callable:
|
|
return
|
|
- if is_union(origin):
|
|
+ if is_union_origin(origin):
|
|
types_ = []
|
|
for type_ in get_args(self.type_):
|
|
if type_ is NoneType:
|
|
--- a/pydantic/main.py
|
|
+++ b/pydantic/main.py
|
|
@@ -38,7 +38,7 @@
|
|
get_origin,
|
|
is_classvar,
|
|
is_namedtuple,
|
|
- is_union,
|
|
+ is_union_origin,
|
|
resolve_annotations,
|
|
update_field_forward_refs,
|
|
)
|
|
@@ -176,7 +176,7 @@ def is_untouched(v: Any) -> bool:
|
|
elif is_valid_field(ann_name):
|
|
validate_field_name(bases, ann_name)
|
|
value = namespace.get(ann_name, Undefined)
|
|
- allowed_types = get_args(ann_type) if is_union(get_origin(ann_type)) else (ann_type,)
|
|
+ allowed_types = get_args(ann_type) if is_union_origin(get_origin(ann_type)) else (ann_type,)
|
|
if (
|
|
is_untouched(value)
|
|
and ann_type != PyObject
|
|
--- a/pydantic/schema.py
|
|
+++ b/pydantic/schema.py
|
|
@@ -71,7 +71,7 @@
|
|
is_callable_type,
|
|
is_literal_type,
|
|
is_namedtuple,
|
|
- is_union,
|
|
+ is_union_origin,
|
|
)
|
|
from .utils import ROOT_KEY, get_model, lenient_issubclass, sequence_like
|
|
|
|
@@ -966,7 +966,7 @@ def go(type_: Any) -> Type[Any]:
|
|
|
|
if origin is Annotated:
|
|
return go(args[0])
|
|
- if is_union(origin):
|
|
+ if is_union_origin(origin):
|
|
return Union[tuple(go(a) for a in args)] # type: ignore
|
|
|
|
if issubclass(origin, List) and (field_info.min_items is not None or field_info.max_items is not None):
|
|
--- a/pydantic/typing.py
|
|
+++ b/pydantic/typing.py
|
|
@@ -191,14 +191,14 @@ def get_args(tp: Type[Any]) -> Tuple[Any, ...]:
|
|
|
|
if sys.version_info < (3, 10):
|
|
|
|
- def is_union(tp: Type[Any]) -> bool:
|
|
+ def is_union_origin(tp: Type[Any]) -> bool:
|
|
return tp is Union
|
|
|
|
|
|
else:
|
|
import types
|
|
|
|
- def is_union(tp: Type[Any]) -> bool:
|
|
+ def is_union_origin(tp: Type[Any]) -> bool:
|
|
return tp is Union or tp is types.Union
|
|
|
|
|
|
@@ -251,7 +251,7 @@ def is_union(tp: Type[Any]) -> bool:
|
|
'get_origin',
|
|
'typing_base',
|
|
'get_all_type_hints',
|
|
- 'is_union',
|
|
+ 'is_union_origin',
|
|
)
|
|
|
|
|
|
|
|
From: PrettyWood <em.jolibois@gmail.com>
|
|
Date: Tue, 10 Aug 2021 18:02:57 +0200
|
|
Subject: [PATCH 2/2] fix: "new" union and generic types are not the same as
|
|
`typing.GenericAlias`
|
|
|
|
--- a/pydantic/typing.py
|
|
+++ b/pydantic/typing.py
|
|
@@ -28,10 +28,10 @@
|
|
from typing import _Final as typing_base # type: ignore
|
|
|
|
try:
|
|
- from typing import GenericAlias # type: ignore
|
|
+ from typing import GenericAlias as TypingGenericAlias # type: ignore
|
|
except ImportError:
|
|
# python < 3.9 does not have GenericAlias (list[int], tuple[str, ...] and so on)
|
|
- GenericAlias = ()
|
|
+ TypingGenericAlias = ()
|
|
|
|
|
|
if sys.version_info < (3, 7):
|
|
@@ -194,12 +194,16 @@ def get_args(tp: Type[Any]) -> Tuple[Any, ...]:
|
|
def is_union_origin(tp: Type[Any]) -> bool:
|
|
return tp is Union
|
|
|
|
+ WithArgsTypes = (TypingGenericAlias,)
|
|
|
|
else:
|
|
import types
|
|
+ import typing
|
|
|
|
def is_union_origin(tp: Type[Any]) -> bool:
|
|
- return tp is Union or tp is types.Union
|
|
+ return tp is Union or tp is types.UnionType # type: ignore # noqa: E721
|
|
+
|
|
+ WithArgsTypes = (typing._GenericAlias, types.GenericAlias, types.UnionType) # type: ignore
|
|
|
|
|
|
if TYPE_CHECKING:
|
|
@@ -246,7 +250,7 @@ def is_union_origin(tp: Type[Any]) -> bool:
|
|
'CallableGenerator',
|
|
'ReprArgs',
|
|
'CallableGenerator',
|
|
- 'GenericAlias',
|
|
+ 'WithArgsTypes',
|
|
'get_args',
|
|
'get_origin',
|
|
'typing_base',
|
|
@@ -260,10 +264,10 @@ def is_union_origin(tp: Type[Any]) -> bool:
|
|
|
|
|
|
def display_as_type(v: Type[Any]) -> str:
|
|
- if not isinstance(v, typing_base) and not isinstance(v, GenericAlias) and not isinstance(v, type):
|
|
+ if not isinstance(v, typing_base) and not isinstance(v, WithArgsTypes) and not isinstance(v, type):
|
|
v = v.__class__
|
|
|
|
- if isinstance(v, GenericAlias):
|
|
+ if isinstance(v, WithArgsTypes):
|
|
# Generic alias are constructs like `list[int]`
|
|
return str(v).replace('typing.', '')
|
|
|
|
--- a/pydantic/utils.py
|
|
+++ b/pydantic/utils.py
|
|
@@ -23,7 +23,7 @@
|
|
Union,
|
|
)
|
|
|
|
-from .typing import GenericAlias, NoneType, display_as_type
|
|
+from .typing import NoneType, WithArgsTypes, display_as_type
|
|
from .version import version_info
|
|
|
|
if TYPE_CHECKING:
|
|
@@ -152,7 +152,7 @@ def lenient_issubclass(cls: Any, class_or_tuple: Union[Type[Any], Tuple[Type[Any
|
|
try:
|
|
return isinstance(cls, type) and issubclass(cls, class_or_tuple)
|
|
except TypeError:
|
|
- if isinstance(cls, GenericAlias):
|
|
+ if isinstance(cls, WithArgsTypes):
|
|
return False
|
|
raise # pragma: no cover
|
|
|