Skip to content

Commit fedf90c

Browse files
committed
types: Add pristine from Python-3.3.3 tarball.
1 parent 955b172 commit fedf90c

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed

types/types.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
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 _g():
19+
yield 1
20+
GeneratorType = type(_g())
21+
22+
class _C:
23+
def _m(self): pass
24+
MethodType = type(_C()._m)
25+
26+
BuiltinFunctionType = type(len)
27+
BuiltinMethodType = type([].append) # Same as BuiltinFunctionType
28+
29+
ModuleType = type(sys)
30+
31+
try:
32+
raise TypeError
33+
except TypeError:
34+
tb = sys.exc_info()[2]
35+
TracebackType = type(tb)
36+
FrameType = type(tb.tb_frame)
37+
tb = None; del tb
38+
39+
# For Jython, the following two types are identical
40+
GetSetDescriptorType = type(FunctionType.__code__)
41+
MemberDescriptorType = type(FunctionType.__globals__)
42+
43+
del sys, _f, _g, _C, # Not for export
44+
45+
46+
# Provide a PEP 3115 compliant mechanism for class creation
47+
def 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+
54+
def 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+
86+
def _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

0 commit comments

Comments
 (0)