logo

oasis-root

Compiled tree of Oasis Linux based on own branch at <https://hacktivis.me/git/oasis/> git clone https://anongit.hacktivis.me/git/oasis-root.git

types.py (10078B)


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