blob: cfd09eaaffe06d29a28fc6bb6977b2b8aaf0c7ab [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
Guido van Rossumadc940e1994-09-29 10:04:43 +000022class _C:
Guido van Rossum898c9151997-09-04 22:12:34 +000023 def _m(self): pass
Guido van Rossum65810fe2006-05-26 19:12:38 +000024MethodType = type(_C()._m)
Guido van Rossum85d89451994-06-23 11:53:27 +000025
Guido van Rossumadc940e1994-09-29 10:04:43 +000026BuiltinFunctionType = type(len)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000027BuiltinMethodType = type([].append) # Same as BuiltinFunctionType
Guido van Rossum85d89451994-06-23 11:53:27 +000028
29ModuleType = type(sys)
Guido van Rossum85d89451994-06-23 11:53:27 +000030
31try:
Guido van Rossum898c9151997-09-04 22:12:34 +000032 raise TypeError
Guido van Rossum85d89451994-06-23 11:53:27 +000033except TypeError:
Guido van Rossuma8add0e2007-05-14 22:03:55 +000034 tb = sys.exc_info()[2]
35 TracebackType = type(tb)
36 FrameType = type(tb.tb_frame)
Guido van Rossumf15d1591997-09-29 23:22:12 +000037 tb = None; del tb
Guido van Rossum85d89451994-06-23 11:53:27 +000038
Christian Heimes5e696852008-04-09 08:37:03 +000039# For Jython, the following two types are identical
40GetSetDescriptorType = type(FunctionType.__code__)
41MemberDescriptorType = type(FunctionType.__globals__)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000042
43del sys, _f, _g, _C, # Not for export
Nick Coghlan7fc570a2012-05-20 02:34:13 +100044
45
46# Provide a PEP 3115 compliant mechanism for class creation
47def new_class(name, bases=(), kwds=None, exec_body=None):
48 """Create a class object dynamically using the appropriate metaclass."""
49 meta, ns, kwds = prepare_class(name, bases, kwds)
50 if exec_body is not None:
51 exec_body(ns)
52 return meta(name, bases, ns, **kwds)
53
54def prepare_class(name, bases=(), kwds=None):
55 """Call the __prepare__ method of the appropriate metaclass.
56
57 Returns (metaclass, namespace, kwds) as a 3-tuple
58
59 *metaclass* is the appropriate metaclass
60 *namespace* is the prepared class namespace
61 *kwds* is an updated copy of the passed in kwds argument with any
62 'metaclass' entry removed. If no kwds argument is passed in, this will
63 be an empty dict.
64 """
65 if kwds is None:
66 kwds = {}
67 else:
68 kwds = dict(kwds) # Don't alter the provided mapping
69 if 'metaclass' in kwds:
70 meta = kwds.pop('metaclass')
71 else:
72 if bases:
73 meta = type(bases[0])
74 else:
75 meta = type
76 if isinstance(meta, type):
77 # when meta is a type, we first determine the most-derived metaclass
78 # instead of invoking the initial candidate directly
79 meta = _calculate_meta(meta, bases)
80 if hasattr(meta, '__prepare__'):
81 ns = meta.__prepare__(name, bases, **kwds)
82 else:
83 ns = {}
84 return meta, ns, kwds
85
86def _calculate_meta(meta, bases):
87 """Calculate the most derived metaclass."""
88 winner = meta
89 for base in bases:
90 base_meta = type(base)
91 if issubclass(winner, base_meta):
92 continue
93 if issubclass(base_meta, winner):
94 winner = base_meta
95 continue
96 # else:
97 raise TypeError("metaclass conflict: "
98 "the metaclass of a derived class "
99 "must be a (non-strict) subclass "
100 "of the metaclasses of all its bases")
101 return winner