diff options
Diffstat (limited to 'Lib/test/test_descr.py')
-rw-r--r-- | Lib/test/test_descr.py | 204 |
1 files changed, 159 insertions, 45 deletions
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index cdaf7d2..b5a10ed 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -654,19 +654,19 @@ class ClassPropertiesAndMethods(unittest.TestCase): class A(metaclass=AMeta): pass self.assertEqual(['AMeta'], new_calls) - new_calls[:] = [] + new_calls.clear() class B(metaclass=BMeta): pass # BMeta.__new__ calls AMeta.__new__ with super: self.assertEqual(['BMeta', 'AMeta'], new_calls) - new_calls[:] = [] + new_calls.clear() class C(A, B): pass # The most derived metaclass is BMeta: self.assertEqual(['BMeta', 'AMeta'], new_calls) - new_calls[:] = [] + new_calls.clear() # BMeta.__prepare__ should've been called: self.assertIn('BMeta_was_here', C.__dict__) @@ -674,20 +674,20 @@ class ClassPropertiesAndMethods(unittest.TestCase): class C2(B, A): pass self.assertEqual(['BMeta', 'AMeta'], new_calls) - new_calls[:] = [] + new_calls.clear() self.assertIn('BMeta_was_here', C2.__dict__) # Check correct metaclass calculation when a metaclass is declared: class D(C, metaclass=type): pass self.assertEqual(['BMeta', 'AMeta'], new_calls) - new_calls[:] = [] + new_calls.clear() self.assertIn('BMeta_was_here', D.__dict__) class E(C, metaclass=AMeta): pass self.assertEqual(['BMeta', 'AMeta'], new_calls) - new_calls[:] = [] + new_calls.clear() self.assertIn('BMeta_was_here', E.__dict__) # Special case: the given metaclass isn't a class, @@ -729,33 +729,33 @@ class ClassPropertiesAndMethods(unittest.TestCase): pass self.assertIs(ANotMeta, type(A)) self.assertEqual(['ANotMeta'], prepare_calls) - prepare_calls[:] = [] + prepare_calls.clear() self.assertEqual(['ANotMeta'], new_calls) - new_calls[:] = [] + new_calls.clear() class B(metaclass=BNotMeta): pass self.assertIs(BNotMeta, type(B)) self.assertEqual(['BNotMeta', 'ANotMeta'], prepare_calls) - prepare_calls[:] = [] + prepare_calls.clear() self.assertEqual(['BNotMeta', 'ANotMeta'], new_calls) - new_calls[:] = [] + new_calls.clear() class C(A, B): pass self.assertIs(BNotMeta, type(C)) self.assertEqual(['BNotMeta', 'ANotMeta'], new_calls) - new_calls[:] = [] + new_calls.clear() self.assertEqual(['BNotMeta', 'ANotMeta'], prepare_calls) - prepare_calls[:] = [] + prepare_calls.clear() class C2(B, A): pass self.assertIs(BNotMeta, type(C2)) self.assertEqual(['BNotMeta', 'ANotMeta'], new_calls) - new_calls[:] = [] + new_calls.clear() self.assertEqual(['BNotMeta', 'ANotMeta'], prepare_calls) - prepare_calls[:] = [] + prepare_calls.clear() # This is a TypeError, because of a metaclass conflict: # BNotMeta is neither a subclass, nor a superclass of type @@ -767,25 +767,25 @@ class ClassPropertiesAndMethods(unittest.TestCase): pass self.assertIs(BNotMeta, type(E)) self.assertEqual(['BNotMeta', 'ANotMeta'], new_calls) - new_calls[:] = [] + new_calls.clear() self.assertEqual(['BNotMeta', 'ANotMeta'], prepare_calls) - prepare_calls[:] = [] + prepare_calls.clear() class F(object(), C): pass self.assertIs(BNotMeta, type(F)) self.assertEqual(['BNotMeta', 'ANotMeta'], new_calls) - new_calls[:] = [] + new_calls.clear() self.assertEqual(['BNotMeta', 'ANotMeta'], prepare_calls) - prepare_calls[:] = [] + prepare_calls.clear() class F2(C, object()): pass self.assertIs(BNotMeta, type(F2)) self.assertEqual(['BNotMeta', 'ANotMeta'], new_calls) - new_calls[:] = [] + new_calls.clear() self.assertEqual(['BNotMeta', 'ANotMeta'], prepare_calls) - prepare_calls[:] = [] + prepare_calls.clear() # TypeError: BNotMeta is neither a # subclass, nor a superclass of int @@ -1444,6 +1444,14 @@ order (MRO) for bases """ else: self.fail("classmethod shouldn't accept keyword args") + cm = classmethod(f) + self.assertEqual(cm.__dict__, {}) + cm.x = 42 + self.assertEqual(cm.x, 42) + self.assertEqual(cm.__dict__, {"x" : 42}) + del cm.x + self.assertFalse(hasattr(cm, "x")) + @support.impl_detail("the module 'xxsubtype' is internal") def test_classmethods_in_c(self): # Testing C-based class methods... @@ -1491,6 +1499,13 @@ order (MRO) for bases """ self.assertEqual(d.goo(1), (1,)) self.assertEqual(d.foo(1), (d, 1)) self.assertEqual(D.foo(d, 1), (d, 1)) + sm = staticmethod(None) + self.assertEqual(sm.__dict__, {}) + sm.x = 42 + self.assertEqual(sm.x, 42) + self.assertEqual(sm.__dict__, {"x" : 42}) + del sm.x + self.assertFalse(hasattr(sm, "x")) @support.impl_detail("the module 'xxsubtype' is internal") def test_staticmethods_in_c(self): @@ -1771,6 +1786,7 @@ order (MRO) for bases """ ("__format__", format, format_impl, set(), {}), ("__floor__", math.floor, zero, set(), {}), ("__trunc__", math.trunc, zero, set(), {}), + ("__trunc__", int, zero, set(), {}), ("__ceil__", math.ceil, zero, set(), {}), ("__dir__", dir, empty_seq, set(), {}), ] @@ -1816,12 +1832,7 @@ order (MRO) for bases """ for attr, obj in env.items(): setattr(X, attr, obj) setattr(X, name, ErrDescr()) - try: - runner(X()) - except MyException: - pass - else: - self.fail("{0!r} didn't raise".format(name)) + self.assertRaises(MyException, runner, X()) def test_specials(self): # Testing special operators... @@ -2258,9 +2269,6 @@ order (MRO) for bases """ # Two essentially featureless objects, just inheriting stuff from # object. self.assertEqual(dir(NotImplemented), dir(Ellipsis)) - if support.check_impl_detail(): - # None differs in PyPy: it has a __nonzero__ - self.assertEqual(dir(None), dir(Ellipsis)) # Nasty test case for proxied objects class Wrapper(object): @@ -4456,6 +4464,62 @@ order (MRO) for bases """ x.y = 42 self.assertEqual(x["y"], 42) + def test_slot_shadows_class_variable(self): + with self.assertRaises(ValueError) as cm: + class X: + __slots__ = ["foo"] + foo = None + m = str(cm.exception) + self.assertEqual("'foo' in __slots__ conflicts with class variable", m) + + def test_set_doc(self): + class X: + "elephant" + X.__doc__ = "banana" + self.assertEqual(X.__doc__, "banana") + with self.assertRaises(TypeError) as cm: + type(list).__dict__["__doc__"].__set__(list, "blah") + self.assertIn("can't set list.__doc__", str(cm.exception)) + with self.assertRaises(TypeError) as cm: + type(X).__dict__["__doc__"].__delete__(X) + self.assertIn("can't delete X.__doc__", str(cm.exception)) + self.assertEqual(X.__doc__, "banana") + + def test_qualname(self): + descriptors = [str.lower, complex.real, float.real, int.__add__] + types = ['method', 'member', 'getset', 'wrapper'] + + # make sure we have an example of each type of descriptor + for d, n in zip(descriptors, types): + self.assertEqual(type(d).__name__, n + '_descriptor') + + for d in descriptors: + qualname = d.__objclass__.__qualname__ + '.' + d.__name__ + self.assertEqual(d.__qualname__, qualname) + + self.assertEqual(str.lower.__qualname__, 'str.lower') + self.assertEqual(complex.real.__qualname__, 'complex.real') + self.assertEqual(float.real.__qualname__, 'float.real') + self.assertEqual(int.__add__.__qualname__, 'int.__add__') + + class X: + pass + with self.assertRaises(TypeError): + del X.__qualname__ + + self.assertRaises(TypeError, type.__dict__['__qualname__'].__set__, + str, 'Oink') + + def test_qualname_dict(self): + ns = {'__qualname__': 'some.name'} + tp = type('Foo', (), ns) + self.assertEqual(tp.__qualname__, 'some.name') + self.assertNotIn('__qualname__', tp.__dict__) + self.assertEqual(ns, {'__qualname__': 'some.name'}) + + ns = {'__qualname__': 1} + self.assertRaises(TypeError, type, 'Foo', (), ns) + def test_cycle_through_dict(self): # See bug #1469629 class X(dict): @@ -4471,6 +4535,27 @@ order (MRO) for bases """ for o in gc.get_objects(): self.assertIsNot(type(o), X) + def test_object_new_and_init_with_parameters(self): + # See issue #1683368 + class OverrideNeither: + pass + self.assertRaises(TypeError, OverrideNeither, 1) + self.assertRaises(TypeError, OverrideNeither, kw=1) + class OverrideNew: + def __new__(cls, foo, kw=0, *args, **kwds): + return object.__new__(cls, *args, **kwds) + class OverrideInit: + def __init__(self, foo, kw=0, *args, **kwargs): + return object.__init__(self, *args, **kwargs) + class OverrideBoth(OverrideNew, OverrideInit): + pass + for case in OverrideNew, OverrideInit, OverrideBoth: + case(1) + case(1, kw=2) + self.assertRaises(TypeError, case, 1, 2, 3) + self.assertRaises(TypeError, case, 1, 2, foo=3) + + class DictProxyTests(unittest.TestCase): def setUp(self): class C(object): @@ -4478,6 +4563,8 @@ class DictProxyTests(unittest.TestCase): pass self.C = C + @unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(), + 'trace function introduces __local__') def test_iter_keys(self): # Testing dict-proxy keys... it = self.C.__dict__.keys() @@ -4485,8 +4572,10 @@ class DictProxyTests(unittest.TestCase): keys = list(it) keys.sort() self.assertEqual(keys, ['__dict__', '__doc__', '__module__', - '__weakref__', 'meth']) + '__weakref__', 'meth']) + @unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(), + 'trace function introduces __local__') def test_iter_values(self): # Testing dict-proxy values... it = self.C.__dict__.values() @@ -4494,6 +4583,8 @@ class DictProxyTests(unittest.TestCase): values = list(it) self.assertEqual(len(values), 5) + @unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(), + 'trace function introduces __local__') def test_iter_items(self): # Testing dict-proxy iteritems... it = self.C.__dict__.items() @@ -4501,7 +4592,7 @@ class DictProxyTests(unittest.TestCase): keys = [item[0] for item in it] keys.sort() self.assertEqual(keys, ['__dict__', '__doc__', '__module__', - '__weakref__', 'meth']) + '__weakref__', 'meth']) def test_dict_type_with_metaclass(self): # Testing type of __dict__ when metaclass set... @@ -4515,19 +4606,14 @@ class DictProxyTests(unittest.TestCase): self.assertEqual(type(C.__dict__), type(B.__dict__)) def test_repr(self): - # Testing dict_proxy.__repr__ - def sorted_dict_repr(repr_): - # Given the repr of a dict, sort the keys - assert repr_.startswith('{') - assert repr_.endswith('}') - kvs = repr_[1:-1].split(', ') - return '{' + ', '.join(sorted(kvs)) + '}' - dict_ = {k: v for k, v in self.C.__dict__.items()} - repr_ = repr(self.C.__dict__) - self.assertTrue(repr_.startswith('dict_proxy(')) - self.assertTrue(repr_.endswith(')')) - self.assertEqual(sorted_dict_repr(repr_[len('dict_proxy('):-len(')')]), - sorted_dict_repr('{!r}'.format(dict_))) + # Testing mappingproxy.__repr__. + # We can't blindly compare with the repr of another dict as ordering + # of keys and values is arbitrary and may differ. + r = repr(self.C.__dict__) + self.assertTrue(r.startswith('mappingproxy('), r) + self.assertTrue(r.endswith(')'), r) + for k, v in self.C.__dict__.items(): + self.assertIn('{!r}: {!r}'.format(k, v), r) class PTypesLongInitTest(unittest.TestCase): @@ -4552,10 +4638,38 @@ class PTypesLongInitTest(unittest.TestCase): type.mro(tuple) +class MiscTests(unittest.TestCase): + def test_type_lookup_mro_reference(self): + # Issue #14199: _PyType_Lookup() has to keep a strong reference to + # the type MRO because it may be modified during the lookup, if + # __bases__ is set during the lookup for example. + class MyKey(object): + def __hash__(self): + return hash('mykey') + + def __eq__(self, other): + X.__bases__ = (Base2,) + + class Base(object): + mykey = 'from Base' + mykey2 = 'from Base' + + class Base2(object): + mykey = 'from Base2' + mykey2 = 'from Base2' + + X = type('X', (Base,), {MyKey(): 5}) + # mykey is read from Base + self.assertEqual(X.mykey, 'from Base') + # mykey2 is read from Base2 because MyKey.__eq__ has set __bases__ + self.assertEqual(X.mykey2, 'from Base2') + + def test_main(): # Run all local test cases, with PTypesLongInitTest first. support.run_unittest(PTypesLongInitTest, OperatorsTest, - ClassPropertiesAndMethods, DictProxyTests) + ClassPropertiesAndMethods, DictProxyTests, + MiscTests) if __name__ == "__main__": test_main() |