typing_extensions.py 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. import abc
  2. import typing
  3. from typing import ( # noqa
  4. # These are imported for re-export.
  5. ClassVar, Type, Generic, Callable, GenericMeta, TypingMeta,
  6. Counter, DefaultDict, Deque, TypeVar, Tuple, Final, final,
  7. NewType, overload, Text, TYPE_CHECKING, Literal, TypedDict, Protocol,
  8. SupportsIndex,
  9. runtime_checkable,
  10. # We use internal typing helpers here, but this significantly reduces
  11. # code duplication. (Also this is only until Protocol is in typing.)
  12. _type_vars, _tp_cache, _type_check,
  13. )
  14. # Please keep __all__ alphabetized within each category.
  15. __all__ = [
  16. # Super-special typing primitives.
  17. 'ClassVar',
  18. 'Final',
  19. 'Protocol',
  20. 'Type',
  21. 'TypedDict',
  22. # Concrete collection types.
  23. 'ContextManager',
  24. 'Counter',
  25. 'Deque',
  26. 'DefaultDict',
  27. # Structural checks, a.k.a. protocols.
  28. 'SupportsIndex',
  29. # One-off things.
  30. 'final',
  31. 'IntVar',
  32. 'Literal',
  33. 'NewType',
  34. 'overload',
  35. 'runtime_checkable',
  36. 'Text',
  37. 'TYPE_CHECKING',
  38. ]
  39. if hasattr(typing, 'NoReturn'):
  40. NoReturn = typing.NoReturn
  41. else:
  42. # TODO: Remove once typing.py has been updated
  43. class _NoReturnMeta(typing.TypingMeta):
  44. """Metaclass for NoReturn."""
  45. def __new__(cls, name, bases, namespace):
  46. cls.assert_no_subclassing(bases)
  47. self = super(_NoReturnMeta, cls).__new__(cls, name, bases, namespace)
  48. return self
  49. class _NoReturn(typing._FinalTypingBase):
  50. """Special type indicating functions that never return.
  51. Example::
  52. from typing import NoReturn
  53. def stop() -> NoReturn:
  54. raise Exception('no way')
  55. This type is invalid in other positions, e.g., ``List[NoReturn]``
  56. will fail in static type checkers.
  57. """
  58. __metaclass__ = _NoReturnMeta
  59. __slots__ = ()
  60. def __instancecheck__(self, obj):
  61. raise TypeError("NoReturn cannot be used with isinstance().")
  62. def __subclasscheck__(self, cls):
  63. raise TypeError("NoReturn cannot be used with issubclass().")
  64. NoReturn = _NoReturn(_root=True)
  65. T_co = typing.TypeVar('T_co', covariant=True)
  66. if hasattr(typing, 'ContextManager'):
  67. ContextManager = typing.ContextManager
  68. else:
  69. # TODO: Remove once typing.py has been updated
  70. class ContextManager(typing.Generic[T_co]):
  71. __slots__ = ()
  72. def __enter__(self):
  73. return self
  74. @abc.abstractmethod
  75. def __exit__(self, exc_type, exc_value, traceback):
  76. return None
  77. @classmethod
  78. def __subclasshook__(cls, C):
  79. if cls is ContextManager:
  80. # In Python 3.6+, it is possible to set a method to None to
  81. # explicitly indicate that the class does not implement an ABC
  82. # (https://bugs.python.org/issue25958), but we do not support
  83. # that pattern here because this fallback class is only used
  84. # in Python 3.5 and earlier.
  85. if (any("__enter__" in B.__dict__ for B in C.__mro__) and
  86. any("__exit__" in B.__dict__ for B in C.__mro__)):
  87. return True
  88. return NotImplemented
  89. def IntVar(name):
  90. return TypeVar(name)
  91. def _is_dunder(name):
  92. """Returns True if name is a __dunder_variable_name__."""
  93. return len(name) > 4 and name.startswith('__') and name.endswith('__')
  94. class AnnotatedMeta(GenericMeta):
  95. """Metaclass for Annotated"""
  96. def __new__(cls, name, bases, namespace, **kwargs):
  97. if any(b is not object for b in bases):
  98. raise TypeError("Cannot subclass %s" % Annotated)
  99. return super(AnnotatedMeta, cls).__new__(cls, name, bases, namespace, **kwargs)
  100. @property
  101. def __metadata__(self):
  102. return self._subs_tree()[2]
  103. def _tree_repr(self, tree):
  104. cls, origin, metadata = tree
  105. if not isinstance(origin, tuple):
  106. tp_repr = typing._type_repr(origin)
  107. else:
  108. tp_repr = origin[0]._tree_repr(origin)
  109. metadata_reprs = ", ".join(repr(arg) for arg in metadata)
  110. return '%s[%s, %s]' % (cls, tp_repr, metadata_reprs)
  111. def _subs_tree(self, tvars=None, args=None):
  112. if self is Annotated:
  113. return Annotated
  114. res = super(AnnotatedMeta, self)._subs_tree(tvars=tvars, args=args)
  115. # Flatten nested Annotated
  116. if isinstance(res[1], tuple) and res[1][0] is Annotated:
  117. sub_tp = res[1][1]
  118. sub_annot = res[1][2]
  119. return (Annotated, sub_tp, sub_annot + res[2])
  120. return res
  121. def _get_cons(self):
  122. """Return the class used to create instance of this type."""
  123. if self.__origin__ is None:
  124. raise TypeError("Cannot get the underlying type of a non-specialized "
  125. "Annotated type.")
  126. tree = self._subs_tree()
  127. while isinstance(tree, tuple) and tree[0] is Annotated:
  128. tree = tree[1]
  129. if isinstance(tree, tuple):
  130. return tree[0]
  131. else:
  132. return tree
  133. @_tp_cache
  134. def __getitem__(self, params):
  135. if not isinstance(params, tuple):
  136. params = (params,)
  137. if self.__origin__ is not None: # specializing an instantiated type
  138. return super(AnnotatedMeta, self).__getitem__(params)
  139. elif not isinstance(params, tuple) or len(params) < 2:
  140. raise TypeError("Annotated[...] should be instantiated with at "
  141. "least two arguments (a type and an annotation).")
  142. else:
  143. msg = "Annotated[t, ...]: t must be a type."
  144. tp = typing._type_check(params[0], msg)
  145. metadata = tuple(params[1:])
  146. return self.__class__(
  147. self.__name__,
  148. self.__bases__,
  149. dict(self.__dict__),
  150. tvars=_type_vars((tp,)),
  151. # Metadata is a tuple so it won't be touched by _replace_args et al.
  152. args=(tp, metadata),
  153. origin=self,
  154. )
  155. def __call__(self, *args, **kwargs):
  156. cons = self._get_cons()
  157. result = cons(*args, **kwargs)
  158. try:
  159. result.__orig_class__ = self
  160. except AttributeError:
  161. pass
  162. return result
  163. def __getattr__(self, attr):
  164. # For simplicity we just don't relay all dunder names
  165. if self.__origin__ is not None and not _is_dunder(attr):
  166. return getattr(self._get_cons(), attr)
  167. raise AttributeError(attr)
  168. def __setattr__(self, attr, value):
  169. if _is_dunder(attr) or attr.startswith('_abc_'):
  170. super(AnnotatedMeta, self).__setattr__(attr, value)
  171. elif self.__origin__ is None:
  172. raise AttributeError(attr)
  173. else:
  174. setattr(self._get_cons(), attr, value)
  175. class Annotated(object):
  176. """Add context specific metadata to a type.
  177. Example: Annotated[int, runtime_check.Unsigned] indicates to the
  178. hypothetical runtime_check module that this type is an unsigned int.
  179. Every other consumer of this type can ignore this metadata and treat
  180. this type as int.
  181. The first argument to Annotated must be a valid type, the remaining
  182. arguments are kept as a tuple in the __metadata__ field.
  183. Details:
  184. - It's an error to call `Annotated` with less than two arguments.
  185. - Nested Annotated are flattened::
  186. Annotated[Annotated[int, Ann1, Ann2], Ann3] == Annotated[int, Ann1, Ann2, Ann3]
  187. - Instantiating an annotated type is equivalent to instantiating the
  188. underlying type::
  189. Annotated[C, Ann1](5) == C(5)
  190. - Annotated can be used as a generic type alias::
  191. Optimized = Annotated[T, runtime.Optimize()]
  192. Optimized[int] == Annotated[int, runtime.Optimize()]
  193. OptimizedList = Annotated[List[T], runtime.Optimize()]
  194. OptimizedList[int] == Annotated[List[int], runtime.Optimize()]
  195. """
  196. __metaclass__ = AnnotatedMeta
  197. __slots__ = ()
  198. class _TypeAliasMeta(typing.TypingMeta):
  199. """Metaclass for TypeAlias"""
  200. def __new__(cls, name, bases, namespace):
  201. cls.assert_no_subclassing(bases)
  202. self = super(_TypeAliasMeta, cls).__new__(cls, name, bases, namespace)
  203. return self
  204. def __repr__(self):
  205. return 'typing_extensions.TypeAlias'
  206. class _TypeAliasBase(typing._FinalTypingBase):
  207. """Special marker indicating that an assignment should
  208. be recognized as a proper type alias definition by type
  209. checkers.
  210. For example::
  211. Predicate = Callable[..., bool] # type: TypeAlias
  212. It's invalid when used anywhere except as in the example above.
  213. """
  214. __metaclass__ = _TypeAliasMeta
  215. __slots__ = ()
  216. def __instancecheck__(self, obj):
  217. raise TypeError("TypeAlias cannot be used with isinstance().")
  218. def __subclasscheck__(self, cls):
  219. raise TypeError("TypeAlias cannot be used with issubclass().")
  220. def __repr__(self):
  221. return 'typing_extensions.TypeAlias'
  222. TypeAlias = _TypeAliasBase(_root=True)
  223. # This alias exists for backwards compatibility.
  224. runtime = runtime_checkable