|
|
|
@ -100,16 +100,16 @@ def _trim_name(nm): |
|
|
|
|
|
|
|
|
|
|
|
class TypingMeta(type): |
|
|
|
"""Metaclass for every type defined below. |
|
|
|
"""Metaclass for most types defined in typing module |
|
|
|
(not a part of public API). |
|
|
|
|
|
|
|
This overrides __new__() to require an extra keyword parameter |
|
|
|
'_root', which serves as a guard against naive subclassing of the |
|
|
|
typing classes. Any legitimate class defined using a metaclass |
|
|
|
derived from TypingMeta (including internal subclasses created by |
|
|
|
e.g. Union[X, Y]) must pass _root=True. |
|
|
|
derived from TypingMeta must pass _root=True. |
|
|
|
|
|
|
|
This also defines a dummy constructor (all the work is done in |
|
|
|
__new__) and a nicer repr(). |
|
|
|
This also defines a dummy constructor (all the work for most typing |
|
|
|
constructs is done in __new__) and a nicer repr(). |
|
|
|
""" |
|
|
|
|
|
|
|
_is_protocol = False |
|
|
|
@ -126,8 +126,8 @@ class TypingMeta(type): |
|
|
|
def _eval_type(self, globalns, localns): |
|
|
|
"""Override this in subclasses to interpret forward references. |
|
|
|
|
|
|
|
For example, Union['C'] is internally stored as |
|
|
|
Union[_ForwardRef('C')], which should evaluate to _Union[C], |
|
|
|
For example, List['C'] is internally stored as |
|
|
|
List[_ForwardRef('C')], which should evaluate to List[C], |
|
|
|
where C is an object found in globalns or localns (searching |
|
|
|
localns first, of course). |
|
|
|
""" |
|
|
|
@ -142,7 +142,7 @@ class TypingMeta(type): |
|
|
|
|
|
|
|
|
|
|
|
class _TypingBase(metaclass=TypingMeta, _root=True): |
|
|
|
"""Indicator of special typing constructs.""" |
|
|
|
"""Internal indicator of special typing constructs.""" |
|
|
|
|
|
|
|
__slots__ = () |
|
|
|
|
|
|
|
@ -179,10 +179,10 @@ class _TypingBase(metaclass=TypingMeta, _root=True): |
|
|
|
|
|
|
|
|
|
|
|
class _FinalTypingBase(_TypingBase, _root=True): |
|
|
|
"""Mix-in class to prevent instantiation. |
|
|
|
"""Internal mix-in class to prevent instantiation. |
|
|
|
|
|
|
|
Prevents instantiation unless _root=True is given in class call. |
|
|
|
It is used to create pseudo-singleton instances Any, Union, Tuple, etc. |
|
|
|
It is used to create pseudo-singleton instances Any, Union, Optional, etc. |
|
|
|
""" |
|
|
|
|
|
|
|
__slots__ = () |
|
|
|
@ -198,7 +198,7 @@ class _FinalTypingBase(_TypingBase, _root=True): |
|
|
|
|
|
|
|
|
|
|
|
class _ForwardRef(_TypingBase, _root=True): |
|
|
|
"""Wrapper to hold a forward reference.""" |
|
|
|
"""Internal wrapper to hold a forward reference.""" |
|
|
|
|
|
|
|
__slots__ = ('__forward_arg__', '__forward_code__', |
|
|
|
'__forward_evaluated__', '__forward_value__') |
|
|
|
@ -206,11 +206,11 @@ class _ForwardRef(_TypingBase, _root=True): |
|
|
|
def __init__(self, arg): |
|
|
|
super().__init__(arg) |
|
|
|
if not isinstance(arg, str): |
|
|
|
raise TypeError('ForwardRef must be a string -- got %r' % (arg,)) |
|
|
|
raise TypeError('Forward reference must be a string -- got %r' % (arg,)) |
|
|
|
try: |
|
|
|
code = compile(arg, '<string>', 'eval') |
|
|
|
except SyntaxError: |
|
|
|
raise SyntaxError('ForwardRef must be an expression -- got %r' % |
|
|
|
raise SyntaxError('Forward reference must be an expression -- got %r' % |
|
|
|
(arg,)) |
|
|
|
self.__forward_arg__ = arg |
|
|
|
self.__forward_code__ = code |
|
|
|
@ -336,7 +336,7 @@ def _eval_type(t, globalns, localns): |
|
|
|
|
|
|
|
|
|
|
|
def _type_check(arg, msg): |
|
|
|
"""Check that the argument is a type, and return it. |
|
|
|
"""Check that the argument is a type, and return it (internal helper). |
|
|
|
|
|
|
|
As a special case, accept None and return type(None) instead. |
|
|
|
Also, _TypeAlias instances (e.g. Match, Pattern) are acceptable. |
|
|
|
@ -363,7 +363,7 @@ def _type_check(arg, msg): |
|
|
|
|
|
|
|
|
|
|
|
def _type_repr(obj): |
|
|
|
"""Return the repr() of an object, special-casing types. |
|
|
|
"""Return the repr() of an object, special-casing types (internal helper). |
|
|
|
|
|
|
|
If obj is a type, we return a shorter version than the default |
|
|
|
type.__repr__, based on the module and qualified name, which is |
|
|
|
@ -418,7 +418,7 @@ class TypeVar(_TypingBase, _root=True): |
|
|
|
as for generic function definitions. See class Generic for more |
|
|
|
information on generic types. Generic functions work as follows: |
|
|
|
|
|
|
|
def repeat(x: T, n: int) -> Sequence[T]: |
|
|
|
def repeat(x: T, n: int) -> List[T]: |
|
|
|
'''Return a list containing n references to x.''' |
|
|
|
return [x]*n |
|
|
|
|
|
|
|
@ -431,10 +431,7 @@ class TypeVar(_TypingBase, _root=True): |
|
|
|
that if the arguments are instances of some subclass of str, |
|
|
|
the return type is still plain str. |
|
|
|
|
|
|
|
At runtime, isinstance(x, T) will raise TypeError. However, |
|
|
|
issubclass(C, T) is true for any class C, and issubclass(str, A) |
|
|
|
and issubclass(bytes, A) are true, and issubclass(int, A) is |
|
|
|
false. (TODO: Why is this needed? This may change. See #136.) |
|
|
|
At runtime, isinstance(x, T) and issubclass(C, T) will raise TypeError. |
|
|
|
|
|
|
|
Type variables defined with covariant=True or contravariant=True |
|
|
|
can be used do declare covariant or contravariant generic types. |
|
|
|
@ -509,7 +506,7 @@ AnyStr = TypeVar('AnyStr', bytes, str) |
|
|
|
|
|
|
|
|
|
|
|
def _replace_arg(arg, tvars, args): |
|
|
|
""" A helper fuunction: replace arg if it is a type variable |
|
|
|
"""An internal helper function: replace arg if it is a type variable |
|
|
|
found in tvars with corresponding substitution from args or |
|
|
|
with corresponding substitution sub-tree if arg is a generic type. |
|
|
|
""" |
|
|
|
@ -526,9 +523,15 @@ def _replace_arg(arg, tvars, args): |
|
|
|
|
|
|
|
|
|
|
|
def _subs_tree(cls, tvars=None, args=None): |
|
|
|
""" Calculate substitution tree for generic cls after |
|
|
|
replacing its type parameters with substitutions in tvars -> args (if any). |
|
|
|
Repeat the same cyclicaly following __origin__'s. |
|
|
|
"""An internal helper function: calculate substitution tree |
|
|
|
for generic cls after replacing its type parameters with |
|
|
|
substitutions in tvars -> args (if any). |
|
|
|
Repeat the same following __origin__'s. |
|
|
|
|
|
|
|
Return a list of arguments with all possible substitutions |
|
|
|
performed. Arguments that are generic classes themselves are represented |
|
|
|
as tuples (so that no new classes are created by this function). |
|
|
|
For example: _subs_tree(List[Tuple[int, T]][str]) == [(Tuple, int, str)] |
|
|
|
""" |
|
|
|
|
|
|
|
if cls.__origin__ is None: |
|
|
|
@ -553,7 +556,7 @@ def _subs_tree(cls, tvars=None, args=None): |
|
|
|
|
|
|
|
|
|
|
|
def _remove_dups_flatten(parameters): |
|
|
|
""" A helper for Union creation and substitution: flatten Union's |
|
|
|
"""An internal helper for Union creation and substitution: flatten Union's |
|
|
|
among parameters, then remove duplicates and strict subclasses. |
|
|
|
""" |
|
|
|
|
|
|
|
@ -594,7 +597,7 @@ def _remove_dups_flatten(parameters): |
|
|
|
|
|
|
|
|
|
|
|
def _check_generic(cls, parameters): |
|
|
|
# Check correct count for parameters of a generic cls. |
|
|
|
# Check correct count for parameters of a generic cls (internal helper). |
|
|
|
if not cls.__parameters__: |
|
|
|
raise TypeError("%s is not a generic class" % repr(cls)) |
|
|
|
alen = len(parameters) |
|
|
|
@ -608,7 +611,7 @@ _cleanups = [] |
|
|
|
|
|
|
|
|
|
|
|
def _tp_cache(func): |
|
|
|
""" Caching for __getitem__ of generic types with a fallback to |
|
|
|
"""Internal wrapper caching __getitem__ of generic types with a fallback to |
|
|
|
original function for non-hashable arguments. |
|
|
|
""" |
|
|
|
|
|
|
|
@ -788,7 +791,7 @@ Optional = _Optional(_root=True) |
|
|
|
|
|
|
|
|
|
|
|
def _gorg(a): |
|
|
|
"""Return the farthest origin of a generic class.""" |
|
|
|
"""Return the farthest origin of a generic class (internal helper).""" |
|
|
|
assert isinstance(a, GenericMeta) |
|
|
|
while a.__origin__ is not None: |
|
|
|
a = a.__origin__ |
|
|
|
@ -796,10 +799,10 @@ def _gorg(a): |
|
|
|
|
|
|
|
|
|
|
|
def _geqv(a, b): |
|
|
|
"""Return whether two generic classes are equivalent. |
|
|
|
"""Return whether two generic classes are equivalent (internal helper). |
|
|
|
|
|
|
|
The intention is to consider generic class X and any of its |
|
|
|
parameterized forms (X[T], X[int], etc.) as equivalent. |
|
|
|
parameterized forms (X[T], X[int], etc.) as equivalent. |
|
|
|
|
|
|
|
However, X is not equivalent to a subclass of X. |
|
|
|
|
|
|
|
@ -825,6 +828,7 @@ def _next_in_mro(cls): |
|
|
|
|
|
|
|
|
|
|
|
def _valid_for_check(cls): |
|
|
|
"""An internal helper to prohibit isinstance([1], List[str]) etc.""" |
|
|
|
if cls is Generic: |
|
|
|
raise TypeError("Class %r cannot be used with class " |
|
|
|
"or instance checks" % cls) |
|
|
|
@ -1083,8 +1087,8 @@ def _generic_new(base_cls, cls, *args, **kwds): |
|
|
|
class Generic(metaclass=GenericMeta): |
|
|
|
"""Abstract base class for generic types. |
|
|
|
|
|
|
|
A generic type is typically declared by inheriting from an |
|
|
|
instantiation of this class with one or more type variables. |
|
|
|
A generic type is typically declared by inheriting from |
|
|
|
this class parameterized with one or more type variables. |
|
|
|
For example, a generic mapping type might be defined as:: |
|
|
|
|
|
|
|
class Mapping(Generic[KT, VT]): |
|
|
|
@ -1111,18 +1115,18 @@ class Generic(metaclass=GenericMeta): |
|
|
|
|
|
|
|
|
|
|
|
class _TypingEmpty: |
|
|
|
"""Placeholder for () or []. Used by TupleMeta and CallableMeta |
|
|
|
to allow empy list/tuple in specific places, without allowing them |
|
|
|
"""Internal placeholder for () or []. Used by TupleMeta and CallableMeta |
|
|
|
to allow empty list/tuple in specific places, without allowing them |
|
|
|
to sneak in where prohibited. |
|
|
|
""" |
|
|
|
|
|
|
|
|
|
|
|
class _TypingEllipsis: |
|
|
|
"""Ditto for ...""" |
|
|
|
"""Internal placeholder for ... (ellipsis).""" |
|
|
|
|
|
|
|
|
|
|
|
class TupleMeta(GenericMeta): |
|
|
|
"""Metaclass for Tuple""" |
|
|
|
"""Metaclass for Tuple (internal).""" |
|
|
|
|
|
|
|
@_tp_cache |
|
|
|
def __getitem__(self, parameters): |
|
|
|
@ -1175,7 +1179,7 @@ class Tuple(tuple, extra=tuple, metaclass=TupleMeta): |
|
|
|
|
|
|
|
|
|
|
|
class CallableMeta(GenericMeta): |
|
|
|
""" Metaclass for Callable.""" |
|
|
|
"""Metaclass for Callable (internal).""" |
|
|
|
|
|
|
|
def __repr__(self): |
|
|
|
if self.__origin__ is None: |
|
|
|
@ -1199,7 +1203,7 @@ class CallableMeta(GenericMeta): |
|
|
|
'[[%s], %s]' % (', '.join(arg_list[:-1]), arg_list[-1])) |
|
|
|
|
|
|
|
def __getitem__(self, parameters): |
|
|
|
""" A thin wrapper around __getitem_inner__ to provide the latter |
|
|
|
"""A thin wrapper around __getitem_inner__ to provide the latter |
|
|
|
with hashable arguments to improve speed. |
|
|
|
""" |
|
|
|
|
|
|
|
@ -1236,7 +1240,7 @@ class Callable(extra=collections_abc.Callable, metaclass = CallableMeta): |
|
|
|
|
|
|
|
The subscription syntax must always be used with exactly two |
|
|
|
values: the argument list and the return type. The argument list |
|
|
|
must be a list of types; the return type must be a single type. |
|
|
|
must be a list of types or ellipsis; the return type must be a single type. |
|
|
|
|
|
|
|
There is no syntax to indicate optional or keyword arguments, |
|
|
|
such function types are rarely used as callback types. |
|
|
|
@ -1565,7 +1569,7 @@ class _ProtocolMeta(GenericMeta): |
|
|
|
class _Protocol(metaclass=_ProtocolMeta): |
|
|
|
"""Internal base class for protocol classes. |
|
|
|
|
|
|
|
This implements a simple-minded structural isinstance check |
|
|
|
This implements a simple-minded structural issubclass check |
|
|
|
(similar but more general than the one-offs in collections.abc |
|
|
|
such as Hashable). |
|
|
|
""" |
|
|
|
|