types
Define names for built-in types that aren't directly accessible as a builtin.
1""" 2Define names for built-in types that aren't directly accessible as a builtin. 3""" 4 5# Iterators in Python aren't a matter of type but of protocol. A large 6# and changing number of builtin types implement *some* flavor of 7# iterator. Don't check the type! Use hasattr to check for both 8# "__iter__" and "__next__" attributes instead. 9 10try: 11 from _types import * 12except ImportError: 13 import sys 14 15 def _f(): pass 16 FunctionType = type(_f) 17 LambdaType = type(lambda: None) # Same as FunctionType 18 CodeType = type(_f.__code__) 19 MappingProxyType = type(type.__dict__) 20 SimpleNamespace = type(sys.implementation) 21 22 def _cell_factory(): 23 a = 1 24 def f(): 25 nonlocal a 26 return f.__closure__[0] 27 CellType = type(_cell_factory()) 28 29 def _g(): 30 yield 1 31 GeneratorType = type(_g()) 32 33 async def _c(): pass 34 _c = _c() 35 CoroutineType = type(_c) 36 _c.close() # Prevent ResourceWarning 37 38 async def _ag(): 39 yield 40 _ag = _ag() 41 AsyncGeneratorType = type(_ag) 42 43 class _C: 44 def _m(self): pass 45 MethodType = type(_C()._m) 46 47 BuiltinFunctionType = type(len) 48 BuiltinMethodType = type([].append) # Same as BuiltinFunctionType 49 50 WrapperDescriptorType = type(object.__init__) 51 MethodWrapperType = type(object().__str__) 52 MethodDescriptorType = type(str.join) 53 ClassMethodDescriptorType = type(dict.__dict__['fromkeys']) 54 55 ModuleType = type(sys) 56 57 try: 58 raise TypeError 59 except TypeError as exc: 60 TracebackType = type(exc.__traceback__) 61 FrameType = type(exc.__traceback__.tb_frame) 62 63 GetSetDescriptorType = type(FunctionType.__code__) 64 MemberDescriptorType = type(FunctionType.__globals__) 65 66 GenericAlias = type(list[int]) 67 UnionType = type(int | str) 68 69 EllipsisType = type(Ellipsis) 70 NoneType = type(None) 71 NotImplementedType = type(NotImplemented) 72 73 # CapsuleType cannot be accessed from pure Python, 74 # so there is no fallback definition. 75 76 del sys, _f, _g, _C, _c, _ag, _cell_factory # Not for export 77 78 79# Provide a PEP 3115 compliant mechanism for class creation 80def new_class(name, bases=(), kwds=None, exec_body=None): 81 """Create a class object dynamically using the appropriate metaclass.""" 82 resolved_bases = resolve_bases(bases) 83 meta, ns, kwds = prepare_class(name, resolved_bases, kwds) 84 if exec_body is not None: 85 exec_body(ns) 86 if resolved_bases is not bases: 87 ns['__orig_bases__'] = bases 88 return meta(name, resolved_bases, ns, **kwds) 89 90def resolve_bases(bases): 91 """Resolve MRO entries dynamically as specified by PEP 560.""" 92 new_bases = list(bases) 93 updated = False 94 shift = 0 95 for i, base in enumerate(bases): 96 if isinstance(base, type): 97 continue 98 if not hasattr(base, "__mro_entries__"): 99 continue 100 new_base = base.__mro_entries__(bases) 101 updated = True 102 if not isinstance(new_base, tuple): 103 raise TypeError("__mro_entries__ must return a tuple") 104 else: 105 new_bases[i+shift:i+shift+1] = new_base 106 shift += len(new_base) - 1 107 if not updated: 108 return bases 109 return tuple(new_bases) 110 111def prepare_class(name, bases=(), kwds=None): 112 """Call the __prepare__ method of the appropriate metaclass. 113 114 Returns (metaclass, namespace, kwds) as a 3-tuple 115 116 *metaclass* is the appropriate metaclass 117 *namespace* is the prepared class namespace 118 *kwds* is an updated copy of the passed in kwds argument with any 119 'metaclass' entry removed. If no kwds argument is passed in, this will 120 be an empty dict. 121 """ 122 if kwds is None: 123 kwds = {} 124 else: 125 kwds = dict(kwds) # Don't alter the provided mapping 126 if 'metaclass' in kwds: 127 meta = kwds.pop('metaclass') 128 else: 129 if bases: 130 meta = type(bases[0]) 131 else: 132 meta = type 133 if isinstance(meta, type): 134 # when meta is a type, we first determine the most-derived metaclass 135 # instead of invoking the initial candidate directly 136 meta = _calculate_meta(meta, bases) 137 if hasattr(meta, '__prepare__'): 138 ns = meta.__prepare__(name, bases, **kwds) 139 else: 140 ns = {} 141 return meta, ns, kwds 142 143def _calculate_meta(meta, bases): 144 """Calculate the most derived metaclass.""" 145 winner = meta 146 for base in bases: 147 base_meta = type(base) 148 if issubclass(winner, base_meta): 149 continue 150 if issubclass(base_meta, winner): 151 winner = base_meta 152 continue 153 # else: 154 raise TypeError("metaclass conflict: " 155 "the metaclass of a derived class " 156 "must be a (non-strict) subclass " 157 "of the metaclasses of all its bases") 158 return winner 159 160 161def get_original_bases(cls, /): 162 """Return the class's "original" bases prior to modification by `__mro_entries__`. 163 164 Examples:: 165 166 from typing import TypeVar, Generic, NamedTuple, TypedDict 167 168 T = TypeVar("T") 169 class Foo(Generic[T]): ... 170 class Bar(Foo[int], float): ... 171 class Baz(list[str]): ... 172 Eggs = NamedTuple("Eggs", [("a", int), ("b", str)]) 173 Spam = TypedDict("Spam", {"a": int, "b": str}) 174 175 assert get_original_bases(Bar) == (Foo[int], float) 176 assert get_original_bases(Baz) == (list[str],) 177 assert get_original_bases(Eggs) == (NamedTuple,) 178 assert get_original_bases(Spam) == (TypedDict,) 179 assert get_original_bases(int) == (object,) 180 """ 181 try: 182 return cls.__dict__.get("__orig_bases__", cls.__bases__) 183 except AttributeError: 184 raise TypeError( 185 f"Expected an instance of type, not {type(cls).__name__!r}" 186 ) from None 187 188 189class DynamicClassAttribute: 190 """Route attribute access on a class to __getattr__. 191 192 This is a descriptor, used to define attributes that act differently when 193 accessed through an instance and through a class. Instance access remains 194 normal, but access to an attribute through a class will be routed to the 195 class's __getattr__ method; this is done by raising AttributeError. 196 197 This allows one to have properties active on an instance, and have virtual 198 attributes on the class with the same name. (Enum used this between Python 199 versions 3.4 - 3.9 .) 200 201 Subclass from this to use a different method of accessing virtual attributes 202 and still be treated properly by the inspect module. (Enum uses this since 203 Python 3.10 .) 204 205 """ 206 def __init__(self, fget=None, fset=None, fdel=None, doc=None): 207 self.fget = fget 208 self.fset = fset 209 self.fdel = fdel 210 # next two lines make DynamicClassAttribute act the same as property 211 self.__doc__ = doc or fget.__doc__ 212 self.overwrite_doc = doc is None 213 # support for abstract methods 214 self.__isabstractmethod__ = bool(getattr(fget, '__isabstractmethod__', False)) 215 216 def __get__(self, instance, ownerclass=None): 217 if instance is None: 218 if self.__isabstractmethod__: 219 return self 220 raise AttributeError() 221 elif self.fget is None: 222 raise AttributeError("unreadable attribute") 223 return self.fget(instance) 224 225 def __set__(self, instance, value): 226 if self.fset is None: 227 raise AttributeError("can't set attribute") 228 self.fset(instance, value) 229 230 def __delete__(self, instance): 231 if self.fdel is None: 232 raise AttributeError("can't delete attribute") 233 self.fdel(instance) 234 235 def getter(self, fget): 236 fdoc = fget.__doc__ if self.overwrite_doc else None 237 result = type(self)(fget, self.fset, self.fdel, fdoc or self.__doc__) 238 result.overwrite_doc = self.overwrite_doc 239 return result 240 241 def setter(self, fset): 242 result = type(self)(self.fget, fset, self.fdel, self.__doc__) 243 result.overwrite_doc = self.overwrite_doc 244 return result 245 246 def deleter(self, fdel): 247 result = type(self)(self.fget, self.fset, fdel, self.__doc__) 248 result.overwrite_doc = self.overwrite_doc 249 return result 250 251 252class _GeneratorWrapper: 253 # TODO: Implement this in C. 254 def __init__(self, gen): 255 self.__wrapped = gen 256 self.__isgen = gen.__class__ is GeneratorType 257 self.__name__ = getattr(gen, '__name__', None) 258 self.__qualname__ = getattr(gen, '__qualname__', None) 259 def send(self, val): 260 return self.__wrapped.send(val) 261 def throw(self, tp, *rest): 262 return self.__wrapped.throw(tp, *rest) 263 def close(self): 264 return self.__wrapped.close() 265 @property 266 def gi_code(self): 267 return self.__wrapped.gi_code 268 @property 269 def gi_frame(self): 270 return self.__wrapped.gi_frame 271 @property 272 def gi_running(self): 273 return self.__wrapped.gi_running 274 @property 275 def gi_yieldfrom(self): 276 return self.__wrapped.gi_yieldfrom 277 @property 278 def gi_suspended(self): 279 return self.__wrapped.gi_suspended 280 cr_code = gi_code 281 cr_frame = gi_frame 282 cr_running = gi_running 283 cr_await = gi_yieldfrom 284 cr_suspended = gi_suspended 285 def __next__(self): 286 return next(self.__wrapped) 287 def __iter__(self): 288 if self.__isgen: 289 return self.__wrapped 290 return self 291 __await__ = __iter__ 292 293def coroutine(func): 294 """Convert regular generator function to a coroutine.""" 295 296 if not callable(func): 297 raise TypeError('types.coroutine() expects a callable') 298 299 if (func.__class__ is FunctionType and 300 getattr(func, '__code__', None).__class__ is CodeType): 301 302 co_flags = func.__code__.co_flags 303 304 # Check if 'func' is a coroutine function. 305 # (0x180 == CO_COROUTINE | CO_ITERABLE_COROUTINE) 306 if co_flags & 0x180: 307 return func 308 309 # Check if 'func' is a generator function. 310 # (0x20 == CO_GENERATOR) 311 if co_flags & 0x20: 312 # TODO: Implement this in C. 313 co = func.__code__ 314 # 0x100 == CO_ITERABLE_COROUTINE 315 func.__code__ = co.replace(co_flags=co.co_flags | 0x100) 316 return func 317 318 # The following code is primarily to support functions that 319 # return generator-like objects (for instance generators 320 # compiled with Cython). 321 322 # Delay functools and _collections_abc import for speeding up types import. 323 import functools 324 import _collections_abc 325 @functools.wraps(func) 326 def wrapped(*args, **kwargs): 327 coro = func(*args, **kwargs) 328 if (coro.__class__ is CoroutineType or 329 coro.__class__ is GeneratorType and coro.gi_code.co_flags & 0x100): 330 # 'coro' is a native coroutine object or an iterable coroutine 331 return coro 332 if (isinstance(coro, _collections_abc.Generator) and 333 not isinstance(coro, _collections_abc.Coroutine)): 334 # 'coro' is either a pure Python generator iterator, or it 335 # implements collections.abc.Generator (and does not implement 336 # collections.abc.Coroutine). 337 return _GeneratorWrapper(coro) 338 # 'coro' is either an instance of collections.abc.Coroutine or 339 # some other object -- pass it through. 340 return coro 341 342 return wrapped 343 344__all__ = [n for n in globals() if not n.startswith('_')] # for pydoc
Represent a PEP 585 generic type
E.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).
The type of the None singleton.
The type of the NotImplemented singleton.
A simple attribute-based namespace.
81def new_class(name, bases=(), kwds=None, exec_body=None): 82 """Create a class object dynamically using the appropriate metaclass.""" 83 resolved_bases = resolve_bases(bases) 84 meta, ns, kwds = prepare_class(name, resolved_bases, kwds) 85 if exec_body is not None: 86 exec_body(ns) 87 if resolved_bases is not bases: 88 ns['__orig_bases__'] = bases 89 return meta(name, resolved_bases, ns, **kwds)
Create a class object dynamically using the appropriate metaclass.
91def resolve_bases(bases): 92 """Resolve MRO entries dynamically as specified by PEP 560.""" 93 new_bases = list(bases) 94 updated = False 95 shift = 0 96 for i, base in enumerate(bases): 97 if isinstance(base, type): 98 continue 99 if not hasattr(base, "__mro_entries__"): 100 continue 101 new_base = base.__mro_entries__(bases) 102 updated = True 103 if not isinstance(new_base, tuple): 104 raise TypeError("__mro_entries__ must return a tuple") 105 else: 106 new_bases[i+shift:i+shift+1] = new_base 107 shift += len(new_base) - 1 108 if not updated: 109 return bases 110 return tuple(new_bases)
Resolve MRO entries dynamically as specified by PEP 560.
112def prepare_class(name, bases=(), kwds=None): 113 """Call the __prepare__ method of the appropriate metaclass. 114 115 Returns (metaclass, namespace, kwds) as a 3-tuple 116 117 *metaclass* is the appropriate metaclass 118 *namespace* is the prepared class namespace 119 *kwds* is an updated copy of the passed in kwds argument with any 120 'metaclass' entry removed. If no kwds argument is passed in, this will 121 be an empty dict. 122 """ 123 if kwds is None: 124 kwds = {} 125 else: 126 kwds = dict(kwds) # Don't alter the provided mapping 127 if 'metaclass' in kwds: 128 meta = kwds.pop('metaclass') 129 else: 130 if bases: 131 meta = type(bases[0]) 132 else: 133 meta = type 134 if isinstance(meta, type): 135 # when meta is a type, we first determine the most-derived metaclass 136 # instead of invoking the initial candidate directly 137 meta = _calculate_meta(meta, bases) 138 if hasattr(meta, '__prepare__'): 139 ns = meta.__prepare__(name, bases, **kwds) 140 else: 141 ns = {} 142 return meta, ns, kwds
Call the __prepare__ method of the appropriate metaclass.
Returns (metaclass, namespace, kwds) as a 3-tuple
metaclass is the appropriate metaclass namespace is the prepared class namespace kwds is an updated copy of the passed in kwds argument with any 'metaclass' entry removed. If no kwds argument is passed in, this will be an empty dict.
162def get_original_bases(cls, /): 163 """Return the class's "original" bases prior to modification by `__mro_entries__`. 164 165 Examples:: 166 167 from typing import TypeVar, Generic, NamedTuple, TypedDict 168 169 T = TypeVar("T") 170 class Foo(Generic[T]): ... 171 class Bar(Foo[int], float): ... 172 class Baz(list[str]): ... 173 Eggs = NamedTuple("Eggs", [("a", int), ("b", str)]) 174 Spam = TypedDict("Spam", {"a": int, "b": str}) 175 176 assert get_original_bases(Bar) == (Foo[int], float) 177 assert get_original_bases(Baz) == (list[str],) 178 assert get_original_bases(Eggs) == (NamedTuple,) 179 assert get_original_bases(Spam) == (TypedDict,) 180 assert get_original_bases(int) == (object,) 181 """ 182 try: 183 return cls.__dict__.get("__orig_bases__", cls.__bases__) 184 except AttributeError: 185 raise TypeError( 186 f"Expected an instance of type, not {type(cls).__name__!r}" 187 ) from None
Return the class's "original" bases prior to modification by __mro_entries__.
Examples::
from typing import TypeVar, Generic, NamedTuple, TypedDict
T = TypeVar("T")
class Foo(Generic[T]): ...
class Bar(Foo[int], float): ...
class Baz(list[str]): ...
Eggs = NamedTuple("Eggs", [("a", int), ("b", str)])
Spam = TypedDict("Spam", {"a": int, "b": str})
assert get_original_bases(Bar) == (Foo[int], float)
assert get_original_bases(Baz) == (list[str],)
assert get_original_bases(Eggs) == (NamedTuple,)
assert get_original_bases(Spam) == (TypedDict,)
assert get_original_bases(int) == (object,)
190class DynamicClassAttribute: 191 """Route attribute access on a class to __getattr__. 192 193 This is a descriptor, used to define attributes that act differently when 194 accessed through an instance and through a class. Instance access remains 195 normal, but access to an attribute through a class will be routed to the 196 class's __getattr__ method; this is done by raising AttributeError. 197 198 This allows one to have properties active on an instance, and have virtual 199 attributes on the class with the same name. (Enum used this between Python 200 versions 3.4 - 3.9 .) 201 202 Subclass from this to use a different method of accessing virtual attributes 203 and still be treated properly by the inspect module. (Enum uses this since 204 Python 3.10 .) 205 206 """ 207 def __init__(self, fget=None, fset=None, fdel=None, doc=None): 208 self.fget = fget 209 self.fset = fset 210 self.fdel = fdel 211 # next two lines make DynamicClassAttribute act the same as property 212 self.__doc__ = doc or fget.__doc__ 213 self.overwrite_doc = doc is None 214 # support for abstract methods 215 self.__isabstractmethod__ = bool(getattr(fget, '__isabstractmethod__', False)) 216 217 def __get__(self, instance, ownerclass=None): 218 if instance is None: 219 if self.__isabstractmethod__: 220 return self 221 raise AttributeError() 222 elif self.fget is None: 223 raise AttributeError("unreadable attribute") 224 return self.fget(instance) 225 226 def __set__(self, instance, value): 227 if self.fset is None: 228 raise AttributeError("can't set attribute") 229 self.fset(instance, value) 230 231 def __delete__(self, instance): 232 if self.fdel is None: 233 raise AttributeError("can't delete attribute") 234 self.fdel(instance) 235 236 def getter(self, fget): 237 fdoc = fget.__doc__ if self.overwrite_doc else None 238 result = type(self)(fget, self.fset, self.fdel, fdoc or self.__doc__) 239 result.overwrite_doc = self.overwrite_doc 240 return result 241 242 def setter(self, fset): 243 result = type(self)(self.fget, fset, self.fdel, self.__doc__) 244 result.overwrite_doc = self.overwrite_doc 245 return result 246 247 def deleter(self, fdel): 248 result = type(self)(self.fget, self.fset, fdel, self.__doc__) 249 result.overwrite_doc = self.overwrite_doc 250 return result
Route attribute access on a class to __getattr__.
This is a descriptor, used to define attributes that act differently when accessed through an instance and through a class. Instance access remains normal, but access to an attribute through a class will be routed to the class's __getattr__ method; this is done by raising AttributeError.
This allows one to have properties active on an instance, and have virtual attributes on the class with the same name. (Enum used this between Python versions 3.4 - 3.9 .)
Subclass from this to use a different method of accessing virtual attributes and still be treated properly by the inspect module. (Enum uses this since Python 3.10 .)
207 def __init__(self, fget=None, fset=None, fdel=None, doc=None): 208 self.fget = fget 209 self.fset = fset 210 self.fdel = fdel 211 # next two lines make DynamicClassAttribute act the same as property 212 self.__doc__ = doc or fget.__doc__ 213 self.overwrite_doc = doc is None 214 # support for abstract methods 215 self.__isabstractmethod__ = bool(getattr(fget, '__isabstractmethod__', False))
294def coroutine(func): 295 """Convert regular generator function to a coroutine.""" 296 297 if not callable(func): 298 raise TypeError('types.coroutine() expects a callable') 299 300 if (func.__class__ is FunctionType and 301 getattr(func, '__code__', None).__class__ is CodeType): 302 303 co_flags = func.__code__.co_flags 304 305 # Check if 'func' is a coroutine function. 306 # (0x180 == CO_COROUTINE | CO_ITERABLE_COROUTINE) 307 if co_flags & 0x180: 308 return func 309 310 # Check if 'func' is a generator function. 311 # (0x20 == CO_GENERATOR) 312 if co_flags & 0x20: 313 # TODO: Implement this in C. 314 co = func.__code__ 315 # 0x100 == CO_ITERABLE_COROUTINE 316 func.__code__ = co.replace(co_flags=co.co_flags | 0x100) 317 return func 318 319 # The following code is primarily to support functions that 320 # return generator-like objects (for instance generators 321 # compiled with Cython). 322 323 # Delay functools and _collections_abc import for speeding up types import. 324 import functools 325 import _collections_abc 326 @functools.wraps(func) 327 def wrapped(*args, **kwargs): 328 coro = func(*args, **kwargs) 329 if (coro.__class__ is CoroutineType or 330 coro.__class__ is GeneratorType and coro.gi_code.co_flags & 0x100): 331 # 'coro' is a native coroutine object or an iterable coroutine 332 return coro 333 if (isinstance(coro, _collections_abc.Generator) and 334 not isinstance(coro, _collections_abc.Coroutine)): 335 # 'coro' is either a pure Python generator iterator, or it 336 # implements collections.abc.Generator (and does not implement 337 # collections.abc.Coroutine). 338 return _GeneratorWrapper(coro) 339 # 'coro' is either an instance of collections.abc.Coroutine or 340 # some other object -- pass it through. 341 return coro 342 343 return wrapped
Convert regular generator function to a coroutine.