This commit is contained in:
parent
6e723d2d11
commit
b24569a19d
|
@ -100,16 +100,16 @@ def _trim_name(nm):
|
||||||
|
|
||||||
|
|
||||||
class TypingMeta(type):
|
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
|
This overrides __new__() to require an extra keyword parameter
|
||||||
'_root', which serves as a guard against naive subclassing of the
|
'_root', which serves as a guard against naive subclassing of the
|
||||||
typing classes. Any legitimate class defined using a metaclass
|
typing classes. Any legitimate class defined using a metaclass
|
||||||
derived from TypingMeta (including internal subclasses created by
|
derived from TypingMeta must pass _root=True.
|
||||||
e.g. Union[X, Y]) must pass _root=True.
|
|
||||||
|
|
||||||
This also defines a dummy constructor (all the work is done in
|
This also defines a dummy constructor (all the work for most typing
|
||||||
__new__) and a nicer repr().
|
constructs is done in __new__) and a nicer repr().
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_is_protocol = False
|
_is_protocol = False
|
||||||
|
@ -126,8 +126,8 @@ class TypingMeta(type):
|
||||||
def _eval_type(self, globalns, localns):
|
def _eval_type(self, globalns, localns):
|
||||||
"""Override this in subclasses to interpret forward references.
|
"""Override this in subclasses to interpret forward references.
|
||||||
|
|
||||||
For example, Union['C'] is internally stored as
|
For example, List['C'] is internally stored as
|
||||||
Union[_ForwardRef('C')], which should evaluate to _Union[C],
|
List[_ForwardRef('C')], which should evaluate to List[C],
|
||||||
where C is an object found in globalns or localns (searching
|
where C is an object found in globalns or localns (searching
|
||||||
localns first, of course).
|
localns first, of course).
|
||||||
"""
|
"""
|
||||||
|
@ -142,7 +142,7 @@ class TypingMeta(type):
|
||||||
|
|
||||||
|
|
||||||
class _TypingBase(metaclass=TypingMeta, _root=True):
|
class _TypingBase(metaclass=TypingMeta, _root=True):
|
||||||
"""Indicator of special typing constructs."""
|
"""Internal indicator of special typing constructs."""
|
||||||
|
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
|
@ -179,10 +179,10 @@ class _TypingBase(metaclass=TypingMeta, _root=True):
|
||||||
|
|
||||||
|
|
||||||
class _FinalTypingBase(_TypingBase, _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.
|
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__ = ()
|
__slots__ = ()
|
||||||
|
@ -198,7 +198,7 @@ class _FinalTypingBase(_TypingBase, _root=True):
|
||||||
|
|
||||||
|
|
||||||
class _ForwardRef(_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__',
|
__slots__ = ('__forward_arg__', '__forward_code__',
|
||||||
'__forward_evaluated__', '__forward_value__')
|
'__forward_evaluated__', '__forward_value__')
|
||||||
|
@ -206,11 +206,11 @@ class _ForwardRef(_TypingBase, _root=True):
|
||||||
def __init__(self, arg):
|
def __init__(self, arg):
|
||||||
super().__init__(arg)
|
super().__init__(arg)
|
||||||
if not isinstance(arg, str):
|
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:
|
try:
|
||||||
code = compile(arg, '<string>', 'eval')
|
code = compile(arg, '<string>', 'eval')
|
||||||
except SyntaxError:
|
except SyntaxError:
|
||||||
raise SyntaxError('ForwardRef must be an expression -- got %r' %
|
raise SyntaxError('Forward reference must be an expression -- got %r' %
|
||||||
(arg,))
|
(arg,))
|
||||||
self.__forward_arg__ = arg
|
self.__forward_arg__ = arg
|
||||||
self.__forward_code__ = code
|
self.__forward_code__ = code
|
||||||
|
@ -336,7 +336,7 @@ def _eval_type(t, globalns, localns):
|
||||||
|
|
||||||
|
|
||||||
def _type_check(arg, msg):
|
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.
|
As a special case, accept None and return type(None) instead.
|
||||||
Also, _TypeAlias instances (e.g. Match, Pattern) are acceptable.
|
Also, _TypeAlias instances (e.g. Match, Pattern) are acceptable.
|
||||||
|
@ -363,7 +363,7 @@ def _type_check(arg, msg):
|
||||||
|
|
||||||
|
|
||||||
def _type_repr(obj):
|
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
|
If obj is a type, we return a shorter version than the default
|
||||||
type.__repr__, based on the module and qualified name, which is
|
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
|
as for generic function definitions. See class Generic for more
|
||||||
information on generic types. Generic functions work as follows:
|
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 a list containing n references to x.'''
|
||||||
return [x]*n
|
return [x]*n
|
||||||
|
|
||||||
|
@ -431,10 +431,7 @@ class TypeVar(_TypingBase, _root=True):
|
||||||
that if the arguments are instances of some subclass of str,
|
that if the arguments are instances of some subclass of str,
|
||||||
the return type is still plain str.
|
the return type is still plain str.
|
||||||
|
|
||||||
At runtime, isinstance(x, T) will raise TypeError. However,
|
At runtime, isinstance(x, T) and issubclass(C, T) will raise TypeError.
|
||||||
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.)
|
|
||||||
|
|
||||||
Type variables defined with covariant=True or contravariant=True
|
Type variables defined with covariant=True or contravariant=True
|
||||||
can be used do declare covariant or contravariant generic types.
|
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):
|
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
|
found in tvars with corresponding substitution from args or
|
||||||
with corresponding substitution sub-tree if arg is a generic type.
|
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):
|
def _subs_tree(cls, tvars=None, args=None):
|
||||||
""" Calculate substitution tree for generic cls after
|
"""An internal helper function: calculate substitution tree
|
||||||
replacing its type parameters with substitutions in tvars -> args (if any).
|
for generic cls after replacing its type parameters with
|
||||||
Repeat the same cyclicaly following __origin__'s.
|
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:
|
if cls.__origin__ is None:
|
||||||
|
@ -553,7 +556,7 @@ def _subs_tree(cls, tvars=None, args=None):
|
||||||
|
|
||||||
|
|
||||||
def _remove_dups_flatten(parameters):
|
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.
|
among parameters, then remove duplicates and strict subclasses.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -594,7 +597,7 @@ def _remove_dups_flatten(parameters):
|
||||||
|
|
||||||
|
|
||||||
def _check_generic(cls, 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__:
|
if not cls.__parameters__:
|
||||||
raise TypeError("%s is not a generic class" % repr(cls))
|
raise TypeError("%s is not a generic class" % repr(cls))
|
||||||
alen = len(parameters)
|
alen = len(parameters)
|
||||||
|
@ -608,7 +611,7 @@ _cleanups = []
|
||||||
|
|
||||||
|
|
||||||
def _tp_cache(func):
|
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.
|
original function for non-hashable arguments.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -788,7 +791,7 @@ Optional = _Optional(_root=True)
|
||||||
|
|
||||||
|
|
||||||
def _gorg(a):
|
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)
|
assert isinstance(a, GenericMeta)
|
||||||
while a.__origin__ is not None:
|
while a.__origin__ is not None:
|
||||||
a = a.__origin__
|
a = a.__origin__
|
||||||
|
@ -796,10 +799,10 @@ def _gorg(a):
|
||||||
|
|
||||||
|
|
||||||
def _geqv(a, b):
|
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
|
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.
|
However, X is not equivalent to a subclass of X.
|
||||||
|
|
||||||
|
@ -825,6 +828,7 @@ def _next_in_mro(cls):
|
||||||
|
|
||||||
|
|
||||||
def _valid_for_check(cls):
|
def _valid_for_check(cls):
|
||||||
|
"""An internal helper to prohibit isinstance([1], List[str]) etc."""
|
||||||
if cls is Generic:
|
if cls is Generic:
|
||||||
raise TypeError("Class %r cannot be used with class "
|
raise TypeError("Class %r cannot be used with class "
|
||||||
"or instance checks" % cls)
|
"or instance checks" % cls)
|
||||||
|
@ -1083,8 +1087,8 @@ def _generic_new(base_cls, cls, *args, **kwds):
|
||||||
class Generic(metaclass=GenericMeta):
|
class Generic(metaclass=GenericMeta):
|
||||||
"""Abstract base class for generic types.
|
"""Abstract base class for generic types.
|
||||||
|
|
||||||
A generic type is typically declared by inheriting from an
|
A generic type is typically declared by inheriting from
|
||||||
instantiation of this class with one or more type variables.
|
this class parameterized with one or more type variables.
|
||||||
For example, a generic mapping type might be defined as::
|
For example, a generic mapping type might be defined as::
|
||||||
|
|
||||||
class Mapping(Generic[KT, VT]):
|
class Mapping(Generic[KT, VT]):
|
||||||
|
@ -1111,18 +1115,18 @@ class Generic(metaclass=GenericMeta):
|
||||||
|
|
||||||
|
|
||||||
class _TypingEmpty:
|
class _TypingEmpty:
|
||||||
"""Placeholder for () or []. Used by TupleMeta and CallableMeta
|
"""Internal placeholder for () or []. Used by TupleMeta and CallableMeta
|
||||||
to allow empy list/tuple in specific places, without allowing them
|
to allow empty list/tuple in specific places, without allowing them
|
||||||
to sneak in where prohibited.
|
to sneak in where prohibited.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class _TypingEllipsis:
|
class _TypingEllipsis:
|
||||||
"""Ditto for ..."""
|
"""Internal placeholder for ... (ellipsis)."""
|
||||||
|
|
||||||
|
|
||||||
class TupleMeta(GenericMeta):
|
class TupleMeta(GenericMeta):
|
||||||
"""Metaclass for Tuple"""
|
"""Metaclass for Tuple (internal)."""
|
||||||
|
|
||||||
@_tp_cache
|
@_tp_cache
|
||||||
def __getitem__(self, parameters):
|
def __getitem__(self, parameters):
|
||||||
|
@ -1175,7 +1179,7 @@ class Tuple(tuple, extra=tuple, metaclass=TupleMeta):
|
||||||
|
|
||||||
|
|
||||||
class CallableMeta(GenericMeta):
|
class CallableMeta(GenericMeta):
|
||||||
""" Metaclass for Callable."""
|
"""Metaclass for Callable (internal)."""
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
if self.__origin__ is None:
|
if self.__origin__ is None:
|
||||||
|
@ -1199,7 +1203,7 @@ class CallableMeta(GenericMeta):
|
||||||
'[[%s], %s]' % (', '.join(arg_list[:-1]), arg_list[-1]))
|
'[[%s], %s]' % (', '.join(arg_list[:-1]), arg_list[-1]))
|
||||||
|
|
||||||
def __getitem__(self, parameters):
|
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.
|
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
|
The subscription syntax must always be used with exactly two
|
||||||
values: the argument list and the return type. The argument list
|
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,
|
There is no syntax to indicate optional or keyword arguments,
|
||||||
such function types are rarely used as callback types.
|
such function types are rarely used as callback types.
|
||||||
|
@ -1565,7 +1569,7 @@ class _ProtocolMeta(GenericMeta):
|
||||||
class _Protocol(metaclass=_ProtocolMeta):
|
class _Protocol(metaclass=_ProtocolMeta):
|
||||||
"""Internal base class for protocol classes.
|
"""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
|
(similar but more general than the one-offs in collections.abc
|
||||||
such as Hashable).
|
such as Hashable).
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue