diff --git a/Lib/typing.py b/Lib/typing.py index c7fe5ddb912..1a943aca20a 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -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, '', '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). """