blob: d8d84709e1b97b7ec1cb88706e0ed347a9e47fd7 [file] [log] [blame]
Georg Brandle5a32dc2007-12-21 08:16:54 +00001"""
2Define names for built-in types that aren't directly accessible as a builtin.
Guido van Rossume7b146f2000-02-04 15:28:42 +00003"""
Guido van Rossum85d89451994-06-23 11:53:27 +00004import sys
5
Tim Peters26991a72001-09-25 22:02:03 +00006# 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
Georg Brandla18af4e2007-04-21 15:47:16 +00009# "__iter__" and "__next__" attributes instead.
Tim Peters26991a72001-09-25 22:02:03 +000010
Guido van Rossumadc940e1994-09-29 10:04:43 +000011def _f(): pass
12FunctionType = type(_f)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000013LambdaType = type(lambda: None) # Same as FunctionType
Guido van Rossuma8add0e2007-05-14 22:03:55 +000014CodeType = type(_f.__code__)
Victor Stinner0db176f2012-04-16 00:16:30 +020015MappingProxyType = type(type.__dict__)
Barry Warsaw409da152012-06-03 16:18:47 -040016SimpleNamespace = type(sys.implementation)
Guido van Rossum85d89451994-06-23 11:53:27 +000017
Tim Peters264c6592004-07-18 00:08:11 +000018def _g():
Tim Peters3e7b1a02001-06-25 19:46:25 +000019 yield 1
Tim Peters264c6592004-07-18 00:08:11 +000020GeneratorType = type(_g())
Tim Peters3e7b1a02001-06-25 19:46:25 +000021
Yury Selivanov5376ba92015-06-22 12:19:30 -040022async def _c(): pass
23_c = _c()
24CoroutineType = type(_c)
25_c.close() # Prevent ResourceWarning
26
Yury Selivanoveb636452016-09-08 22:01:51 -070027async def _ag():
28 yield
29_ag = _ag()
30AsyncGeneratorType = type(_ag)
31
Guido van Rossumadc940e1994-09-29 10:04:43 +000032class _C:
Guido van Rossum898c9151997-09-04 22:12:34 +000033 def _m(self): pass
Guido van Rossum65810fe2006-05-26 19:12:38 +000034MethodType = type(_C()._m)
Guido van Rossum85d89451994-06-23 11:53:27 +000035
Guido van Rossumadc940e1994-09-29 10:04:43 +000036BuiltinFunctionType = type(len)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000037BuiltinMethodType = type([].append) # Same as BuiltinFunctionType
Guido van Rossum85d89451994-06-23 11:53:27 +000038
39ModuleType = type(sys)
Guido van Rossum85d89451994-06-23 11:53:27 +000040
41try:
Guido van Rossum898c9151997-09-04 22:12:34 +000042 raise TypeError
Guido van Rossum85d89451994-06-23 11:53:27 +000043except TypeError:
Guido van Rossuma8add0e2007-05-14 22:03:55 +000044 tb = sys.exc_info()[2]
45 TracebackType = type(tb)
46 FrameType = type(tb.tb_frame)
Guido van Rossumf15d1591997-09-29 23:22:12 +000047 tb = None; del tb
Guido van Rossum85d89451994-06-23 11:53:27 +000048
Christian Heimes5e696852008-04-09 08:37:03 +000049# For Jython, the following two types are identical
50GetSetDescriptorType = type(FunctionType.__code__)
51MemberDescriptorType = type(FunctionType.__globals__)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000052
Yury Selivanov5376ba92015-06-22 12:19:30 -040053del sys, _f, _g, _C, _c, # Not for export
Nick Coghlan7fc570a2012-05-20 02:34:13 +100054
55
56# Provide a PEP 3115 compliant mechanism for class creation
57def new_class(name, bases=(), kwds=None, exec_body=None):
58 """Create a class object dynamically using the appropriate metaclass."""
59 meta, ns, kwds = prepare_class(name, bases, kwds)
60 if exec_body is not None:
61 exec_body(ns)
62 return meta(name, bases, ns, **kwds)
63
64def prepare_class(name, bases=(), kwds=None):
65 """Call the __prepare__ method of the appropriate metaclass.
66
67 Returns (metaclass, namespace, kwds) as a 3-tuple
68
69 *metaclass* is the appropriate metaclass
70 *namespace* is the prepared class namespace
71 *kwds* is an updated copy of the passed in kwds argument with any
72 'metaclass' entry removed. If no kwds argument is passed in, this will
73 be an empty dict.
74 """
75 if kwds is None:
76 kwds = {}
77 else:
78 kwds = dict(kwds) # Don't alter the provided mapping
79 if 'metaclass' in kwds:
80 meta = kwds.pop('metaclass')
81 else:
82 if bases:
83 meta = type(bases[0])
84 else:
85 meta = type
86 if isinstance(meta, type):
87 # when meta is a type, we first determine the most-derived metaclass
88 # instead of invoking the initial candidate directly
89 meta = _calculate_meta(meta, bases)
90 if hasattr(meta, '__prepare__'):
91 ns = meta.__prepare__(name, bases, **kwds)
92 else:
Eric Snow4f29e752016-09-08 15:11:11 -070093 ns = {}
Nick Coghlan7fc570a2012-05-20 02:34:13 +100094 return meta, ns, kwds
95
96def _calculate_meta(meta, bases):
97 """Calculate the most derived metaclass."""
98 winner = meta
99 for base in bases:
100 base_meta = type(base)
101 if issubclass(winner, base_meta):
102 continue
103 if issubclass(base_meta, winner):
104 winner = base_meta
105 continue
106 # else:
107 raise TypeError("metaclass conflict: "
108 "the metaclass of a derived class "
109 "must be a (non-strict) subclass "
110 "of the metaclasses of all its bases")
111 return winner
Ethan Furmane03ea372013-09-25 07:14:41 -0700112
113class DynamicClassAttribute:
114 """Route attribute access on a class to __getattr__.
115
116 This is a descriptor, used to define attributes that act differently when
117 accessed through an instance and through a class. Instance access remains
118 normal, but access to an attribute through a class will be routed to the
119 class's __getattr__ method; this is done by raising AttributeError.
120
121 This allows one to have properties active on an instance, and have virtual
122 attributes on the class with the same name (see Enum for an example).
123
124 """
125 def __init__(self, fget=None, fset=None, fdel=None, doc=None):
126 self.fget = fget
127 self.fset = fset
128 self.fdel = fdel
129 # next two lines make DynamicClassAttribute act the same as property
Ethan Furman63c141c2013-10-18 00:27:39 -0700130 self.__doc__ = doc or fget.__doc__
Ethan Furmane03ea372013-09-25 07:14:41 -0700131 self.overwrite_doc = doc is None
132 # support for abstract methods
133 self.__isabstractmethod__ = bool(getattr(fget, '__isabstractmethod__', False))
134
135 def __get__(self, instance, ownerclass=None):
136 if instance is None:
137 if self.__isabstractmethod__:
138 return self
139 raise AttributeError()
140 elif self.fget is None:
141 raise AttributeError("unreadable attribute")
142 return self.fget(instance)
143
144 def __set__(self, instance, value):
145 if self.fset is None:
146 raise AttributeError("can't set attribute")
147 self.fset(instance, value)
148
149 def __delete__(self, instance):
150 if self.fdel is None:
151 raise AttributeError("can't delete attribute")
152 self.fdel(instance)
153
154 def getter(self, fget):
155 fdoc = fget.__doc__ if self.overwrite_doc else None
156 result = type(self)(fget, self.fset, self.fdel, fdoc or self.__doc__)
157 result.overwrite_doc = self.overwrite_doc
158 return result
159
160 def setter(self, fset):
161 result = type(self)(self.fget, fset, self.fdel, self.__doc__)
162 result.overwrite_doc = self.overwrite_doc
163 return result
164
165 def deleter(self, fdel):
166 result = type(self)(self.fget, self.fset, fdel, self.__doc__)
167 result.overwrite_doc = self.overwrite_doc
168 return result
Serhiy Storchaka7beb4f92015-03-04 09:43:27 +0200169
170
Yury Selivanovc565cd52015-05-29 09:06:05 -0400171import functools as _functools
172import collections.abc as _collections_abc
173
Yury Selivanov00e33722015-06-24 11:44:51 -0400174class _GeneratorWrapper:
175 # TODO: Implement this in C.
176 def __init__(self, gen):
Yury Selivanovf847f1f2015-06-24 12:49:28 -0400177 self.__wrapped = gen
178 self.__isgen = gen.__class__ is GeneratorType
Yury Selivanov00e33722015-06-24 11:44:51 -0400179 self.__name__ = getattr(gen, '__name__', None)
180 self.__qualname__ = getattr(gen, '__qualname__', None)
181 def send(self, val):
Yury Selivanovf847f1f2015-06-24 12:49:28 -0400182 return self.__wrapped.send(val)
Yury Selivanov00e33722015-06-24 11:44:51 -0400183 def throw(self, tp, *rest):
Yury Selivanovf847f1f2015-06-24 12:49:28 -0400184 return self.__wrapped.throw(tp, *rest)
Yury Selivanov00e33722015-06-24 11:44:51 -0400185 def close(self):
Yury Selivanovf847f1f2015-06-24 12:49:28 -0400186 return self.__wrapped.close()
Yury Selivanov00e33722015-06-24 11:44:51 -0400187 @property
188 def gi_code(self):
Yury Selivanovf847f1f2015-06-24 12:49:28 -0400189 return self.__wrapped.gi_code
Yury Selivanov00e33722015-06-24 11:44:51 -0400190 @property
191 def gi_frame(self):
Yury Selivanovf847f1f2015-06-24 12:49:28 -0400192 return self.__wrapped.gi_frame
Yury Selivanov00e33722015-06-24 11:44:51 -0400193 @property
194 def gi_running(self):
Yury Selivanovf847f1f2015-06-24 12:49:28 -0400195 return self.__wrapped.gi_running
Yury Selivanov53e62302015-07-03 00:35:02 -0400196 @property
197 def gi_yieldfrom(self):
198 return self.__wrapped.gi_yieldfrom
Yury Selivanov00e33722015-06-24 11:44:51 -0400199 cr_code = gi_code
200 cr_frame = gi_frame
201 cr_running = gi_running
Yury Selivanov53e62302015-07-03 00:35:02 -0400202 cr_await = gi_yieldfrom
Yury Selivanov00e33722015-06-24 11:44:51 -0400203 def __next__(self):
Yury Selivanovf847f1f2015-06-24 12:49:28 -0400204 return next(self.__wrapped)
Yury Selivanov00e33722015-06-24 11:44:51 -0400205 def __iter__(self):
Yury Selivanovf847f1f2015-06-24 12:49:28 -0400206 if self.__isgen:
207 return self.__wrapped
Yury Selivanov00e33722015-06-24 11:44:51 -0400208 return self
209 __await__ = __iter__
210
Yury Selivanovc565cd52015-05-29 09:06:05 -0400211def coroutine(func):
212 """Convert regular generator function to a coroutine."""
213
Yury Selivanovc565cd52015-05-29 09:06:05 -0400214 if not callable(func):
215 raise TypeError('types.coroutine() expects a callable')
216
Yury Selivanov5376ba92015-06-22 12:19:30 -0400217 if (func.__class__ is FunctionType and
218 getattr(func, '__code__', None).__class__ is CodeType):
Yury Selivanovc565cd52015-05-29 09:06:05 -0400219
Yury Selivanov5376ba92015-06-22 12:19:30 -0400220 co_flags = func.__code__.co_flags
221
222 # Check if 'func' is a coroutine function.
223 # (0x180 == CO_COROUTINE | CO_ITERABLE_COROUTINE)
224 if co_flags & 0x180:
225 return func
226
227 # Check if 'func' is a generator function.
228 # (0x20 == CO_GENERATOR)
229 if co_flags & 0x20:
230 # TODO: Implement this in C.
231 co = func.__code__
232 func.__code__ = CodeType(
233 co.co_argcount, co.co_kwonlyargcount, co.co_nlocals,
234 co.co_stacksize,
235 co.co_flags | 0x100, # 0x100 == CO_ITERABLE_COROUTINE
236 co.co_code,
237 co.co_consts, co.co_names, co.co_varnames, co.co_filename,
238 co.co_name, co.co_firstlineno, co.co_lnotab, co.co_freevars,
239 co.co_cellvars)
240 return func
Yury Selivanovc565cd52015-05-29 09:06:05 -0400241
Yury Selivanov13f77232015-05-29 16:19:18 -0400242 # The following code is primarily to support functions that
243 # return generator-like objects (for instance generators
244 # compiled with Cython).
245
Yury Selivanovc565cd52015-05-29 09:06:05 -0400246 @_functools.wraps(func)
247 def wrapped(*args, **kwargs):
248 coro = func(*args, **kwargs)
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400249 if (coro.__class__ is CoroutineType or
250 coro.__class__ is GeneratorType and coro.gi_code.co_flags & 0x100):
251 # 'coro' is a native coroutine object or an iterable coroutine
Yury Selivanov5376ba92015-06-22 12:19:30 -0400252 return coro
Yury Selivanovfdbeb2b2015-07-03 13:11:35 -0400253 if (isinstance(coro, _collections_abc.Generator) and
254 not isinstance(coro, _collections_abc.Coroutine)):
Yury Selivanov5376ba92015-06-22 12:19:30 -0400255 # 'coro' is either a pure Python generator iterator, or it
256 # implements collections.abc.Generator (and does not implement
257 # collections.abc.Coroutine).
Yury Selivanov00e33722015-06-24 11:44:51 -0400258 return _GeneratorWrapper(coro)
Yury Selivanov5376ba92015-06-22 12:19:30 -0400259 # 'coro' is either an instance of collections.abc.Coroutine or
260 # some other object -- pass it through.
Yury Selivanovc565cd52015-05-29 09:06:05 -0400261 return coro
262
263 return wrapped
264
265
Serhiy Storchaka7beb4f92015-03-04 09:43:27 +0200266__all__ = [n for n in globals() if n[:1] != '_']