aboutsummaryrefslogtreecommitdiff
path: root/tests/bytecode/pylib-tests/types.py
diff options
context:
space:
mode:
authorDamien2013-12-29 18:21:02 +0000
committerDamien2013-12-29 18:21:02 +0000
commit2eda70874ef193c609207db2ba87324244afcf84 (patch)
tree5a570df6296c40f7774d6d25cd3cc4c38fc1e1ff /tests/bytecode/pylib-tests/types.py
parentde690d128bbec4f53e8a7d6149738a6facae4382 (diff)
Add tests to test compiler and emitted byte code.
Diffstat (limited to 'tests/bytecode/pylib-tests/types.py')
-rw-r--r--tests/bytecode/pylib-tests/types.py101
1 files changed, 101 insertions, 0 deletions
diff --git a/tests/bytecode/pylib-tests/types.py b/tests/bytecode/pylib-tests/types.py
new file mode 100644
index 000000000..cfd09eaaf
--- /dev/null
+++ b/tests/bytecode/pylib-tests/types.py
@@ -0,0 +1,101 @@
+"""
+Define names for built-in types that aren't directly accessible as a builtin.
+"""
+import sys
+
+# Iterators in Python aren't a matter of type but of protocol. A large
+# and changing number of builtin types implement *some* flavor of
+# iterator. Don't check the type! Use hasattr to check for both
+# "__iter__" and "__next__" attributes instead.
+
+def _f(): pass
+FunctionType = type(_f)
+LambdaType = type(lambda: None) # Same as FunctionType
+CodeType = type(_f.__code__)
+MappingProxyType = type(type.__dict__)
+SimpleNamespace = type(sys.implementation)
+
+def _g():
+ yield 1
+GeneratorType = type(_g())
+
+class _C:
+ def _m(self): pass
+MethodType = type(_C()._m)
+
+BuiltinFunctionType = type(len)
+BuiltinMethodType = type([].append) # Same as BuiltinFunctionType
+
+ModuleType = type(sys)
+
+try:
+ raise TypeError
+except TypeError:
+ tb = sys.exc_info()[2]
+ TracebackType = type(tb)
+ FrameType = type(tb.tb_frame)
+ tb = None; del tb
+
+# For Jython, the following two types are identical
+GetSetDescriptorType = type(FunctionType.__code__)
+MemberDescriptorType = type(FunctionType.__globals__)
+
+del sys, _f, _g, _C, # Not for export
+
+
+# Provide a PEP 3115 compliant mechanism for class creation
+def new_class(name, bases=(), kwds=None, exec_body=None):
+ """Create a class object dynamically using the appropriate metaclass."""
+ meta, ns, kwds = prepare_class(name, bases, kwds)
+ if exec_body is not None:
+ exec_body(ns)
+ return meta(name, bases, ns, **kwds)
+
+def prepare_class(name, bases=(), kwds=None):
+ """Call the __prepare__ method of the appropriate metaclass.
+
+ Returns (metaclass, namespace, kwds) as a 3-tuple
+
+ *metaclass* is the appropriate metaclass
+ *namespace* is the prepared class namespace
+ *kwds* is an updated copy of the passed in kwds argument with any
+ 'metaclass' entry removed. If no kwds argument is passed in, this will
+ be an empty dict.
+ """
+ if kwds is None:
+ kwds = {}
+ else:
+ kwds = dict(kwds) # Don't alter the provided mapping
+ if 'metaclass' in kwds:
+ meta = kwds.pop('metaclass')
+ else:
+ if bases:
+ meta = type(bases[0])
+ else:
+ meta = type
+ if isinstance(meta, type):
+ # when meta is a type, we first determine the most-derived metaclass
+ # instead of invoking the initial candidate directly
+ meta = _calculate_meta(meta, bases)
+ if hasattr(meta, '__prepare__'):
+ ns = meta.__prepare__(name, bases, **kwds)
+ else:
+ ns = {}
+ return meta, ns, kwds
+
+def _calculate_meta(meta, bases):
+ """Calculate the most derived metaclass."""
+ winner = meta
+ for base in bases:
+ base_meta = type(base)
+ if issubclass(winner, base_meta):
+ continue
+ if issubclass(base_meta, winner):
+ winner = base_meta
+ continue
+ # else:
+ raise TypeError("metaclass conflict: "
+ "the metaclass of a derived class "
+ "must be a (non-strict) subclass "
+ "of the metaclasses of all its bases")
+ return winner