Python types 模块,new_class() 实例源码
我们从Python开源项目中,提取了以下39个代码示例,用于说明如何使用types.new_class()。
def named_tuple(classname, fieldnames):
# Populate a dictionary of field property accessors
cls_dict = { name: property(operator.itemgetter(n))
for n, name in enumerate(fieldnames) }
# Make a __new__ function and add to the class dict
def __new__(cls, *args):
if len(args) != len(fieldnames):
raise TypeError('Expected {} arguments'.format(len(fieldnames)))
return tuple.__new__(cls, (args))
cls_dict['__new__'] = __new__
# Make the class
cls = types.new_class(classname, (tuple,), {},
lambda ns: ns.update(cls_dict))
cls.__module__ = sys._getframe(1).f_globals['__name__']
return cls
def test_prepare_class(self):
# Basic test of metaclass derivation
expected_ns = {}
class A(type):
def __new__(*args, **kwargs):
return type.__new__(*args, **kwargs)
def __prepare__(*args):
return expected_ns
B = types.new_class("B", (object,))
C = types.new_class("C", (object,), {"metaclass": A})
# The most derived metaclass of D is A rather than type.
meta, ns, kwds = types.prepare_class("D", (B, C), {"metaclass": type})
self.assertIs(meta, A)
self.assertIs(ns, expected_ns)
self.assertEqual(len(kwds), 0)
def test_metaclass_override_function(self):
# Special case: the given metaclass isn't a class,
# so there is no metaclass calculation.
class A(metaclass=self.Meta):
pass
marker = object()
def func(*args, **kwargs):
return marker
X = types.new_class("X", (), {"metaclass": func})
Y = types.new_class("Y", (object,), {"metaclass": func})
Z = types.new_class("Z", (A,), {"metaclass": func})
self.assertIs(marker, X)
self.assertIs(marker, Y)
self.assertIs(marker, Z)
def test_metaclass_override_function(self):
# Special case: the given metaclass isn't a class,
# so there is no metaclass calculation.
class A(metaclass=self.Meta):
pass
marker = object()
def func(*args, **kwargs):
return marker
X = types.new_class("X", (), {"metaclass": func})
Y = types.new_class("Y", (object,), {"metaclass": func})
Z = types.new_class("Z", (A,), {"metaclass": func})
self.assertIs(marker, X)
self.assertIs(marker, Y)
self.assertIs(marker, Z)
def test_metaclass_override_function(self):
# Special case: the given metaclass isn't a class,
# so there is no metaclass calculation.
class A(metaclass=self.Meta):
pass
marker = object()
def func(*args, **kwargs):
return marker
X = types.new_class("X", (), {"metaclass": func})
Y = types.new_class("Y", (object,), {"metaclass": func})
Z = types.new_class("Z", (A,), {"metaclass": func})
self.assertIs(marker, X)
self.assertIs(marker, Y)
self.assertIs(marker, Z)
def NewTagClass(class_name: str, tag: str = None,
bases: Union[type, Iterable] = (Tag, ),
**kwargs: Any) -> type:
"""Generate and return new ``Tag`` class.
If ``tag`` is empty, lower case of ``class_name`` is used for a tag name of
the new class. ``bases`` should be a tuple of base classes. If it is empty,
use ``Tag`` class for a base class. Other keyword arguments are used for
class variables of the new class.
Example::
MyButton = NewTagClass('MyButton', 'button', (Button,),
class_='btn', is_='my-button')
my_button = MyButton('Click!')
print(my_button.html)
>>> <button class="btn" id="111111111" is="my-button">Click!</button>
"""
if tag is None:
tag = class_name.lower()
if not isinstance(type, tuple):
if isinstance(bases, Iterable):
bases = tuple(bases)
elif isinstance(bases, type):
bases = (bases, )
else:
TypeError('Invalid base class: {}'.format(str(bases)))
kwargs['tag'] = tag
# Here not use type() function, since it does not support
# metaclasss (__prepare__) properly.
cls = new_class( # type: ignore
class_name, bases, {}, lambda ns: ns.update(kwargs))
return cls
def test_new_class_basics(self):
C = types.new_class("C")
self.assertEqual(C.__name__, "C")
self.assertEqual(C.__bases__, (object,))
def test_new_class_subclass(self):
C = types.new_class("C", (int,))
self.assertTrue(issubclass(C, int))
def test_new_class_meta(self):
Meta = self.Meta
settings = {"metaclass": Meta, "z": 2}
# We do this twice to make sure the passed in dict isn't mutated
for i in range(2):
C = types.new_class("C" + str(i), (), settings)
self.assertIsInstance(C, Meta)
self.assertEqual(C.y, 1)
self.assertEqual(C.z, 2)
def test_new_class_exec_body(self):
Meta = self.Meta
def func(ns):
ns["x"] = 0
C = types.new_class("C", (), {"metaclass": Meta, "z": 2}, func)
self.assertIsInstance(C, Meta)
self.assertEqual(C.x, 0)
self.assertEqual(C.y, 1)
self.assertEqual(C.z, 2)
def test_new_class_metaclass_keywords(self):
#Test that keywords are passed to the metaclass:
def meta_func(name, bases, ns, **kw):
return name, bases, ns, kw
res = types.new_class("X",
(int, object),
dict(metaclass=meta_func, x=0))
self.assertEqual(res, ("X", (int, object), {}, {"x": 0}))
def test_new_class_meta_with_base(self):
Meta = self.Meta
def func(ns):
ns["x"] = 0
C = types.new_class(name="C",
bases=(int,),
kwds=dict(metaclass=Meta, z=2),
exec_body=func)
self.assertTrue(issubclass(C, int))
self.assertIsInstance(C, Meta)
self.assertEqual(C.x, 0)
self.assertEqual(C.y, 1)
self.assertEqual(C.z, 2)
# Many of the following tests are derived from test_descr.py
def create_inheritance_tests(base_class):
def set_frozen(ns):
ns['abc'] = frozen_abc
def set_source(ns):
ns['abc'] = source_abc
classes = []
for prefix, ns_set in [('Frozen', set_frozen), ('Source', set_source)]:
classes.append(types.new_class('_'.join([prefix, base_class.__name__]),
(base_class, unittest.TestCase),
exec_body=ns_set))
return classes
def make_abc_subclasses(base_class):
classes = []
for kind, abc in [('Frozen', frozen_abc), ('Source', source_abc)]:
name = '_'.join([kind, base_class.__name__])
base_classes = base_class, getattr(abc, base_class.__name__)
classes.append(types.new_class(name, base_classes))
return classes
def make_return_value_tests(base_class, test_class):
frozen_class, source_class = make_abc_subclasses(base_class)
tests = []
for prefix, class_in_test in [('Frozen', frozen_class), ('Source', source_class)]:
def set_ns(ns):
ns['ins'] = class_in_test()
tests.append(types.new_class('_'.join([prefix, test_class.__name__]),
(test_class, unittest.TestCase),
exec_body=set_ns))
return tests
def test_both(test_class, **kwargs):
frozen_tests = types.new_class('Frozen_'+test_class.__name__,
(test_class, unittest.TestCase))
source_tests = types.new_class('Source_'+test_class.__name__,
(test_class, unittest.TestCase))
frozen_tests.__module__ = source_tests.__module__ = test_class.__module__
for attr, (frozen_value, source_value) in kwargs.items():
setattr(frozen_tests, attr, frozen_value)
setattr(source_tests, attr, source_value)
return frozen_tests, source_tests
def test_new_class_basics(self):
C = types.new_class("C")
self.assertEqual(C.__name__, "C")
self.assertEqual(C.__bases__, (object,))
def test_new_class_meta(self):
Meta = self.Meta
settings = {"metaclass": Meta, "z": 2}
# We do this twice to make sure the passed in dict isn't mutated
for i in range(2):
C = types.new_class("C" + str(i), (), settings)
self.assertIsInstance(C, Meta)
self.assertEqual(C.y, 1)
self.assertEqual(C.z, 2)
def test_new_class_exec_body(self):
Meta = self.Meta
def func(ns):
ns["x"] = 0
C = types.new_class("C", (), {"metaclass": Meta, "z": 2}, func)
self.assertIsInstance(C, Meta)
self.assertEqual(C.x, 0)
self.assertEqual(C.y, 1)
self.assertEqual(C.z, 2)
def test_new_class_metaclass_keywords(self):
#Test that keywords are passed to the metaclass:
def meta_func(name, bases, ns, **kw):
return name, bases, ns, kw
res = types.new_class("X",
(int, object),
dict(metaclass=meta_func, x=0))
self.assertEqual(res, ("X", (int, object), {}, {"x": 0}))
def test_new_class_defaults(self):
# Test defaults/keywords:
C = types.new_class("C", (), {}, None)
self.assertEqual(C.__name__, "C")
self.assertEqual(C.__bases__, (object,))
def test_new_class_meta_with_base(self):
Meta = self.Meta
def func(ns):
ns["x"] = 0
C = types.new_class(name="C",
bases=(int,),
kwds=dict(metaclass=Meta, z=2),
exec_body=func)
self.assertTrue(issubclass(C, int))
self.assertIsInstance(C, Meta)
self.assertEqual(C.x, 0)
self.assertEqual(C.y, 1)
self.assertEqual(C.z, 2)
# Many of the following tests are derived from test_descr.py
def __get__(self, instance, owner):
supers = (SysException, self.ex_type, Exception) \
if self.ex_type and self.ex_type is not Exception else (SysException, Exception)
api_ex_cls = types.new_class('SysException', supers, {}, lambda ns: ns)
api_ex = api_ex_cls(err_msg=self.err_msg, err_code=self.err_code, http_code=self.http_code)
return api_ex
def test_tests_fail_1(self):
SimpleTestCase = types.new_class('SimpleTestCase',
(BaseSimpleTestCase, tb.TestCase))
suite = unittest.TestSuite()
suite.addTest(SimpleTestCase('test_tests_zero_error'))
result = unittest.TestResult()
suite.run(result)
self.assertIn('ZeroDivisionError', result.errors[0][1])
def create_inheritance_tests(base_class):
def set_frozen(ns):
ns['abc'] = frozen_abc
def set_source(ns):
ns['abc'] = source_abc
classes = []
for prefix, ns_set in [('Frozen', set_frozen), ('Source', set_source)]:
classes.append(types.new_class('_'.join([prefix, base_class.__name__]),
(base_class, unittest.TestCase),
exec_body=ns_set))
return classes
def make_abc_subclasses(base_class):
classes = []
for kind, abc in [('Frozen', frozen_abc), ('Source', source_abc)]:
name = '_'.join([kind, base_class.__name__])
base_classes = base_class, getattr(abc, base_class.__name__)
classes.append(types.new_class(name, base_classes))
return classes
def make_return_value_tests(base_class, test_class):
frozen_class, source_class = make_abc_subclasses(base_class)
tests = []
for prefix, class_in_test in [('Frozen', frozen_class), ('Source', source_class)]:
def set_ns(ns):
ns['ins'] = class_in_test()
tests.append(types.new_class('_'.join([prefix, test_class.__name__]),
(test_class, unittest.TestCase),
exec_body=set_ns))
return tests
def test_both(test_class, **kwargs):
frozen_tests = types.new_class('Frozen_'+test_class.__name__,
(test_class, unittest.TestCase))
source_tests = types.new_class('Source_'+test_class.__name__,
(test_class, unittest.TestCase))
frozen_tests.__module__ = source_tests.__module__ = test_class.__module__
for attr, (frozen_value, source_value) in kwargs.items():
setattr(frozen_tests, attr, frozen_value)
setattr(source_tests, attr, source_value)
return frozen_tests, source_tests
def test_new_class_basics(self):
C = types.new_class("C")
self.assertEqual(C.__name__, "C")
self.assertEqual(C.__bases__, (object,))
def test_new_class_meta(self):
Meta = self.Meta
settings = {"metaclass": Meta, "z": 2}
# We do this twice to make sure the passed in dict isn't mutated
for i in range(2):
C = types.new_class("C" + str(i), (), settings)
self.assertIsInstance(C, Meta)
self.assertEqual(C.y, 1)
self.assertEqual(C.z, 2)
def test_new_class_exec_body(self):
Meta = self.Meta
def func(ns):
ns["x"] = 0
C = types.new_class("C", (), {"metaclass": Meta, "z": 2}, func)
self.assertIsInstance(C, Meta)
self.assertEqual(C.x, 0)
self.assertEqual(C.y, 1)
self.assertEqual(C.z, 2)
def test_new_class_metaclass_keywords(self):
#Test that keywords are passed to the metaclass:
def meta_func(name, bases, ns, **kw):
return name, bases, ns, kw
res = types.new_class("X",
(int, object),
dict(metaclass=meta_func, x=0))
self.assertEqual(res, ("X", (int, object), {}, {"x": 0}))
def test_new_class_defaults(self):
# Test defaults/keywords:
C = types.new_class("C", (), {}, None)
self.assertEqual(C.__name__, "C")
self.assertEqual(C.__bases__, (object,))
def test_new_class_meta_with_base(self):
Meta = self.Meta
def func(ns):
ns["x"] = 0
C = types.new_class(name="C",
bases=(int,),
kwds=dict(metaclass=Meta, z=2),
exec_body=func)
self.assertTrue(issubclass(C, int))
self.assertIsInstance(C, Meta)
self.assertEqual(C.x, 0)
self.assertEqual(C.y, 1)
self.assertEqual(C.z, 2)
# Many of the following tests are derived from test_descr.py
def generate_fakechannel():
fakechannel = types.new_class('Channel')
fakechannel.is_private = True
fakechannel.calls = 0
fakechannel.id = 0
return fakechannel
def test_commands():
fakebot = generate_fakebot()
loop = asyncio.get_event_loop()
for cmd in dir(command.Commands):
if cmd.startswith('_'):
continue
if cmd in ['restartbot', 'updateprices', 'clearimagecache', 'bug']:
continue
channel = generate_fakechannel()
calls = channel.calls
message = types.new_class('Message')
message.content = "!{0} args".format(cmd)
message.channel = channel
if cmd == 'time':
message.content = '!time Melbourne'
message.author = types.new_class('User')
message.author.mention = "@nobody"
message.author.voice = types.new_class('VoiceState')
message.author.voice.voice_channel = None
print("Calling {0}".format(message.content))
loop.run_until_complete(command.handle_command(message, fakebot))
assert channel.calls > calls
calls = channel.calls
loop.close()
def test_metaclass_derivation(self):
# issue1294232: correct metaclass calculation
new_calls = [] # to check the order of __new__ calls
class AMeta(type):
def __new__(mcls, name, bases, ns):
new_calls.append('AMeta')
return super().__new__(mcls, name, bases, ns)
@classmethod
def __prepare__(mcls, name, bases):
return {}
class BMeta(AMeta):
def __new__(mcls, name, bases, ns):
new_calls.append('BMeta')
return super().__new__(mcls, name, bases, ns)
@classmethod
def __prepare__(mcls, name, bases):
ns = super().__prepare__(name, bases)
ns['BMeta_was_here'] = True
return ns
A = types.new_class("A", (), {"metaclass": AMeta})
self.assertEqual(new_calls, ['AMeta'])
new_calls.clear()
B = types.new_class("B", (), {"metaclass": BMeta})
# BMeta.__new__ calls AMeta.__new__ with super:
self.assertEqual(new_calls, ['BMeta', 'AMeta'])
new_calls.clear()
C = types.new_class("C", (A, B))
# The most derived metaclass is BMeta:
self.assertEqual(new_calls, ['BMeta', 'AMeta'])
new_calls.clear()
# BMeta.__prepare__ should've been called:
self.assertIn('BMeta_was_here', C.__dict__)
# The order of the bases shouldn't matter:
C2 = types.new_class("C2", (B, A))
self.assertEqual(new_calls, ['BMeta', 'AMeta'])
new_calls.clear()
self.assertIn('BMeta_was_here', C2.__dict__)
# Check correct metaclass calculation when a metaclass is declared:
D = types.new_class("D", (C,), {"metaclass": type})
self.assertEqual(new_calls, ['BMeta', 'AMeta'])
new_calls.clear()
self.assertIn('BMeta_was_here', D.__dict__)
E = types.new_class("E", (C,), {"metaclass": AMeta})
self.assertEqual(new_calls, ['BMeta', 'AMeta'])
new_calls.clear()
self.assertIn('BMeta_was_here', E.__dict__)
def test_metaclass_derivation(self):
# issue1294232: correct metaclass calculation
new_calls = [] # to check the order of __new__ calls
class AMeta(type):
def __new__(mcls, name, bases, ns):
new_calls.append('AMeta')
return super().__new__(mcls, name, bases, ns)
@classmethod
def __prepare__(mcls, name, bases):
return {}
class BMeta(AMeta):
def __new__(mcls, name, bases, ns):
new_calls.append('BMeta')
return super().__new__(mcls, name, bases, ns)
@classmethod
def __prepare__(mcls, name, bases):
ns = super().__prepare__(name, bases)
ns['BMeta_was_here'] = True
return ns
A = types.new_class("A", (), {"metaclass": AMeta})
self.assertEqual(new_calls, ['AMeta'])
new_calls.clear()
B = types.new_class("B", (), {"metaclass": BMeta})
# BMeta.__new__ calls AMeta.__new__ with super:
self.assertEqual(new_calls, ['BMeta', 'AMeta'])
new_calls.clear()
C = types.new_class("C", (A, B))
# The most derived metaclass is BMeta:
self.assertEqual(new_calls, ['BMeta', 'AMeta'])
new_calls.clear()
# BMeta.__prepare__ should've been called:
self.assertIn('BMeta_was_here', C.__dict__)
# The order of the bases shouldn't matter:
C2 = types.new_class("C2", (B, A))
self.assertEqual(new_calls, ['BMeta', 'AMeta'])
new_calls.clear()
self.assertIn('BMeta_was_here', C2.__dict__)
# Check correct metaclass calculation when a metaclass is declared:
D = types.new_class("D", (C,), {"metaclass": type})
self.assertEqual(new_calls, ['BMeta', 'AMeta'])
new_calls.clear()
self.assertIn('BMeta_was_here', D.__dict__)
E = types.new_class("E", (C,), {"metaclass": AMeta})
self.assertEqual(new_calls, ['BMeta', 'AMeta'])
new_calls.clear()
self.assertIn('BMeta_was_here', E.__dict__)
def test_metaclass_derivation(self):
# issue1294232: correct metaclass calculation
new_calls = [] # to check the order of __new__ calls
class AMeta(type):
def __new__(mcls, name, bases, ns):
new_calls.append('AMeta')
return super().__new__(mcls, name, bases, ns)
@classmethod
def __prepare__(mcls, name, bases):
return {}
class BMeta(AMeta):
def __new__(mcls, name, bases, ns):
new_calls.append('BMeta')
return super().__new__(mcls, name, bases, ns)
@classmethod
def __prepare__(mcls, name, bases):
ns = super().__prepare__(name, bases)
ns['BMeta_was_here'] = True
return ns
A = types.new_class("A", (), {"metaclass": AMeta})
self.assertEqual(new_calls, ['AMeta'])
new_calls.clear()
B = types.new_class("B", (), {"metaclass": BMeta})
# BMeta.__new__ calls AMeta.__new__ with super:
self.assertEqual(new_calls, ['BMeta', 'AMeta'])
new_calls.clear()
C = types.new_class("C", (A, B))
# The most derived metaclass is BMeta:
self.assertEqual(new_calls, ['BMeta', 'AMeta'])
new_calls.clear()
# BMeta.__prepare__ should've been called:
self.assertIn('BMeta_was_here', C.__dict__)
# The order of the bases shouldn't matter:
C2 = types.new_class("C2", (B, A))
self.assertEqual(new_calls, ['BMeta', 'AMeta'])
new_calls.clear()
self.assertIn('BMeta_was_here', C2.__dict__)
# Check correct metaclass calculation when a metaclass is declared:
D = types.new_class("D", (C,), {"metaclass": type})
self.assertEqual(new_calls, ['BMeta', 'AMeta'])
new_calls.clear()
self.assertIn('BMeta_was_here', D.__dict__)
E = types.new_class("E", (C,), {"metaclass": AMeta})
self.assertEqual(new_calls, ['BMeta', 'AMeta'])
new_calls.clear()
self.assertIn('BMeta_was_here', E.__dict__)