aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Lib/typing.py
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.com>2023-12-13 02:43:57 +0300
committershadchin <shadchin@yandex-team.com>2023-12-13 03:08:48 +0300
commit5b48aabc614c6d407f885f3b228dc484ad4c5ba9 (patch)
tree602eb5cc5d85bf730c1de1fa50a13c2ee552830d /contrib/tools/python3/src/Lib/typing.py
parent35d7049b38602e8cbfcd3f96257329a1abce947e (diff)
downloadydb-5b48aabc614c6d407f885f3b228dc484ad4c5ba9.tar.gz
Update Python 3 to 3.11.7
Diffstat (limited to 'contrib/tools/python3/src/Lib/typing.py')
-rw-r--r--contrib/tools/python3/src/Lib/typing.py108
1 files changed, 70 insertions, 38 deletions
diff --git a/contrib/tools/python3/src/Lib/typing.py b/contrib/tools/python3/src/Lib/typing.py
index 977e37d623..85166dfd94 100644
--- a/contrib/tools/python3/src/Lib/typing.py
+++ b/contrib/tools/python3/src/Lib/typing.py
@@ -211,8 +211,12 @@ def _should_unflatten_callable_args(typ, args):
For example::
- assert collections.abc.Callable[[int, int], str].__args__ == (int, int, str)
- assert collections.abc.Callable[ParamSpec, str].__args__ == (ParamSpec, str)
+ >>> import collections.abc
+ >>> P = ParamSpec('P')
+ >>> collections.abc.Callable[[int, int], str].__args__ == (int, int, str)
+ True
+ >>> collections.abc.Callable[P, str].__args__ == (P, str)
+ True
As a result, if we need to reconstruct the Callable from its __args__,
we need to unflatten it.
@@ -250,7 +254,10 @@ def _collect_parameters(args):
For example::
- assert _collect_parameters((T, Callable[P, T])) == (T, P)
+ >>> P = ParamSpec('P')
+ >>> T = TypeVar('T')
+ >>> _collect_parameters((T, Callable[P, T]))
+ (~T, ~P)
"""
parameters = []
for t in args:
@@ -2207,9 +2214,14 @@ class Annotated:
def __new__(cls, *args, **kwargs):
raise TypeError("Type Annotated cannot be instantiated.")
- @_tp_cache
def __class_getitem__(cls, params):
- if not isinstance(params, tuple) or len(params) < 2:
+ if not isinstance(params, tuple):
+ params = (params,)
+ return cls._class_getitem_inner(cls, *params)
+
+ @_tp_cache(typed=True)
+ def _class_getitem_inner(cls, *params):
+ if len(params) < 2:
raise TypeError("Annotated[...] should be used "
"with at least two arguments (a type and an "
"annotation).")
@@ -2417,14 +2429,15 @@ def get_origin(tp):
Examples::
- assert get_origin(Literal[42]) is Literal
- assert get_origin(int) is None
- assert get_origin(ClassVar[int]) is ClassVar
- assert get_origin(Generic) is Generic
- assert get_origin(Generic[T]) is Generic
- assert get_origin(Union[T, int]) is Union
- assert get_origin(List[Tuple[T, T]][int]) is list
- assert get_origin(P.args) is P
+ >>> P = ParamSpec('P')
+ >>> assert get_origin(Literal[42]) is Literal
+ >>> assert get_origin(int) is None
+ >>> assert get_origin(ClassVar[int]) is ClassVar
+ >>> assert get_origin(Generic) is Generic
+ >>> assert get_origin(Generic[T]) is Generic
+ >>> assert get_origin(Union[T, int]) is Union
+ >>> assert get_origin(List[Tuple[T, T]][int]) is list
+ >>> assert get_origin(P.args) is P
"""
if isinstance(tp, _AnnotatedAlias):
return Annotated
@@ -2445,11 +2458,12 @@ def get_args(tp):
Examples::
- assert get_args(Dict[str, int]) == (str, int)
- assert get_args(int) == ()
- assert get_args(Union[int, Union[T, int], str][int]) == (int, str)
- assert get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int])
- assert get_args(Callable[[], T][int]) == ([], int)
+ >>> T = TypeVar('T')
+ >>> assert get_args(Dict[str, int]) == (str, int)
+ >>> assert get_args(int) == ()
+ >>> assert get_args(Union[int, Union[T, int], str][int]) == (int, str)
+ >>> assert get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int])
+ >>> assert get_args(Callable[[], T][int]) == ([], int)
"""
if isinstance(tp, _AnnotatedAlias):
return (tp.__origin__,) + tp.__metadata__
@@ -2468,12 +2482,15 @@ def is_typeddict(tp):
For example::
- class Film(TypedDict):
- title: str
- year: int
-
- is_typeddict(Film) # => True
- is_typeddict(Union[list, str]) # => False
+ >>> from typing import TypedDict
+ >>> class Film(TypedDict):
+ ... title: str
+ ... year: int
+ ...
+ >>> is_typeddict(Film)
+ True
+ >>> is_typeddict(dict)
+ False
"""
return isinstance(tp, _TypedDictMeta)
@@ -2975,8 +2992,14 @@ class _TypedDictMeta(type):
for base in bases:
annotations.update(base.__dict__.get('__annotations__', {}))
- required_keys.update(base.__dict__.get('__required_keys__', ()))
- optional_keys.update(base.__dict__.get('__optional_keys__', ()))
+
+ base_required = base.__dict__.get('__required_keys__', set())
+ required_keys |= base_required
+ optional_keys -= base_required
+
+ base_optional = base.__dict__.get('__optional_keys__', set())
+ required_keys -= base_optional
+ optional_keys |= base_optional
annotations.update(own_annotations)
for annotation_key, annotation_type in own_annotations.items():
@@ -2988,14 +3011,23 @@ class _TypedDictMeta(type):
annotation_origin = get_origin(annotation_type)
if annotation_origin is Required:
- required_keys.add(annotation_key)
+ is_required = True
elif annotation_origin is NotRequired:
- optional_keys.add(annotation_key)
- elif total:
+ is_required = False
+ else:
+ is_required = total
+
+ if is_required:
required_keys.add(annotation_key)
+ optional_keys.discard(annotation_key)
else:
optional_keys.add(annotation_key)
+ required_keys.discard(annotation_key)
+ assert required_keys.isdisjoint(optional_keys), (
+ f"Required keys overlap with optional keys in {name}:"
+ f" {required_keys=}, {optional_keys=}"
+ )
tp_dict.__annotations__ = annotations
tp_dict.__required_keys__ = frozenset(required_keys)
tp_dict.__optional_keys__ = frozenset(optional_keys)
@@ -3022,15 +3054,15 @@ def TypedDict(typename, fields=None, /, *, total=True, **kwargs):
Usage::
- class Point2D(TypedDict):
- x: int
- y: int
- label: str
-
- a: Point2D = {'x': 1, 'y': 2, 'label': 'good'} # OK
- b: Point2D = {'z': 3, 'label': 'bad'} # Fails type check
-
- assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')
+ >>> class Point2D(TypedDict):
+ ... x: int
+ ... y: int
+ ... label: str
+ ...
+ >>> a: Point2D = {'x': 1, 'y': 2, 'label': 'good'} # OK
+ >>> b: Point2D = {'z': 3, 'label': 'bad'} # Fails type check
+ >>> Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')
+ True
The type info can be accessed via the Point2D.__annotations__ dict, and
the Point2D.__required_keys__ and Point2D.__optional_keys__ frozensets.