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