diff options
author | Benjamin Peterson <benjamin@python.org> | 2009-03-28 21:42:05 (GMT) |
---|---|---|
committer | Benjamin Peterson <benjamin@python.org> | 2009-03-28 21:42:05 (GMT) |
commit | e549ead8263819ac47f60cdd0239592750888f0b (patch) | |
tree | 7e1199b4b197ac5facd66b03cbb7e768fa2b6892 /Lib/test/test_descr.py | |
parent | b556452055590c6d8f658d90c6be00aec31f5620 (diff) | |
download | cpython-e549ead8263819ac47f60cdd0239592750888f0b.zip cpython-e549ead8263819ac47f60cdd0239592750888f0b.tar.gz cpython-e549ead8263819ac47f60cdd0239592750888f0b.tar.bz2 |
Merged revisions 70554,70588-70589,70598,70605,70611-70621,70623-70624,70626-70627 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r70554 | benjamin.peterson | 2009-03-23 16:25:15 -0500 (Mon, 23 Mar 2009) | 1 line
complain when there's no last exception
........
r70588 | benjamin.peterson | 2009-03-24 17:56:32 -0500 (Tue, 24 Mar 2009) | 1 line
fix newline issue in test summary
........
r70589 | benjamin.peterson | 2009-03-24 18:07:07 -0500 (Tue, 24 Mar 2009) | 1 line
another style nit
........
r70598 | benjamin.peterson | 2009-03-25 16:24:04 -0500 (Wed, 25 Mar 2009) | 1 line
add shorthands for expected failures and unexpected success
........
r70605 | benjamin.peterson | 2009-03-26 11:32:23 -0500 (Thu, 26 Mar 2009) | 1 line
remove uneeded function
........
r70611 | benjamin.peterson | 2009-03-26 13:35:37 -0500 (Thu, 26 Mar 2009) | 1 line
add much better tests for python version information parsing
........
r70612 | benjamin.peterson | 2009-03-26 13:55:48 -0500 (Thu, 26 Mar 2009) | 1 line
more and more implementations now support sys.subversion
........
r70613 | benjamin.peterson | 2009-03-26 13:58:30 -0500 (Thu, 26 Mar 2009) | 1 line
roll old test in with new one
........
r70614 | benjamin.peterson | 2009-03-26 14:09:21 -0500 (Thu, 26 Mar 2009) | 1 line
add support for PyPy
........
r70615 | benjamin.peterson | 2009-03-26 14:58:18 -0500 (Thu, 26 Mar 2009) | 5 lines
add some useful utilities for skipping tests with unittest's new skipping ability
most significantly apply a modified portion of the patch from #4242 with
patches for skipping implementation details
........
r70616 | benjamin.peterson | 2009-03-26 15:05:50 -0500 (Thu, 26 Mar 2009) | 1 line
rename TestCase.skip() to skipTest() because it causes annoying problems with trial #5571
........
r70617 | benjamin.peterson | 2009-03-26 15:17:27 -0500 (Thu, 26 Mar 2009) | 1 line
apply the second part of #4242's patch; classify all the implementation details in test_descr
........
r70618 | benjamin.peterson | 2009-03-26 15:48:25 -0500 (Thu, 26 Mar 2009) | 1 line
remove test_support.TestSkipped and just use unittest.SkipTest
........
r70619 | benjamin.peterson | 2009-03-26 15:49:40 -0500 (Thu, 26 Mar 2009) | 1 line
fix naming
........
r70620 | benjamin.peterson | 2009-03-26 16:10:30 -0500 (Thu, 26 Mar 2009) | 1 line
fix incorrect auto-translation of TestSkipped -> unittest.SkipTest
........
r70621 | benjamin.peterson | 2009-03-26 16:11:16 -0500 (Thu, 26 Mar 2009) | 1 line
must pass argument to get expected behavior ;)
........
r70623 | benjamin.peterson | 2009-03-26 16:30:10 -0500 (Thu, 26 Mar 2009) | 1 line
add missing import
........
r70624 | benjamin.peterson | 2009-03-26 16:30:54 -0500 (Thu, 26 Mar 2009) | 1 line
** is required here
........
r70626 | benjamin.peterson | 2009-03-26 16:40:29 -0500 (Thu, 26 Mar 2009) | 1 line
update email tests to use SkipTest
........
r70627 | benjamin.peterson | 2009-03-26 16:44:43 -0500 (Thu, 26 Mar 2009) | 1 line
fix another name
........
Diffstat (limited to 'Lib/test/test_descr.py')
-rw-r--r-- | Lib/test/test_descr.py | 139 |
1 files changed, 97 insertions, 42 deletions
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 0554fc2..6dba040 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -65,8 +65,9 @@ class OperatorsTest(unittest.TestCase): # Find method in parent class while meth not in t.__dict__: t = t.__bases__[0] - - self.assertEqual(m, t.__dict__[meth]) + # in some implementations (e.g. PyPy), 'm' can be a regular unbound + # method object; the getattr() below obtains its underlying function. + self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) self.assertEqual(m(a), res) bm = getattr(a, meth) self.assertEqual(bm(), res) @@ -85,7 +86,9 @@ class OperatorsTest(unittest.TestCase): m = getattr(t, meth) while meth not in t.__dict__: t = t.__bases__[0] - self.assertEqual(m, t.__dict__[meth]) + # in some implementations (e.g. PyPy), 'm' can be a regular unbound + # method object; the getattr() below obtains its underlying function. + self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) self.assertEqual(m(a, b), res) bm = getattr(a, meth) self.assertEqual(bm(b), res) @@ -97,7 +100,9 @@ class OperatorsTest(unittest.TestCase): m = getattr(t, meth) while meth not in t.__dict__: t = t.__bases__[0] - self.assertEqual(m, t.__dict__[meth]) + # in some implementations (e.g. PyPy), 'm' can be a regular unbound + # method object; the getattr() below obtains its underlying function. + self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) self.assertEqual(m(a, slice(b, c)), res) bm = getattr(a, meth) self.assertEqual(bm(slice(b, c)), res) @@ -110,7 +115,9 @@ class OperatorsTest(unittest.TestCase): m = getattr(t, meth) while meth not in t.__dict__: t = t.__bases__[0] - self.assertEqual(m, t.__dict__[meth]) + # in some implementations (e.g. PyPy), 'm' can be a regular unbound + # method object; the getattr() below obtains its underlying function. + self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) d['a'] = deepcopy(a) m(d['a'], b) self.assertEqual(d['a'], res) @@ -127,7 +134,9 @@ class OperatorsTest(unittest.TestCase): m = getattr(t, meth) while meth not in t.__dict__: t = t.__bases__[0] - self.assertEqual(m, t.__dict__[meth]) + # in some implementations (e.g. PyPy), 'm' can be a regular unbound + # method object; the getattr() below obtains its underlying function. + self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) d['a'] = deepcopy(a) m(d['a'], b, c) self.assertEqual(d['a'], res) @@ -144,7 +153,9 @@ class OperatorsTest(unittest.TestCase): while meth not in t.__dict__: t = t.__bases__[0] m = getattr(t, meth) - self.assertEqual(m, t.__dict__[meth]) + # in some implementations (e.g. PyPy), 'm' can be a regular unbound + # method object; the getattr() below obtains its underlying function. + self.assertEqual(getattr(m, 'im_func', m), t.__dict__[meth]) dictionary['a'] = deepcopy(a) m(dictionary['a'], slice(b, c), d) self.assertEqual(dictionary['a'], res) @@ -276,6 +287,7 @@ class OperatorsTest(unittest.TestCase): self.assertEqual(repr(a), "234.5") self.assertEqual(a.prec, 12) + @support.impl_detail("the module 'xxsubtype' is internal") def test_spam_lists(self): # Testing spamlist operations... import copy, xxsubtype as spam @@ -319,6 +331,7 @@ class OperatorsTest(unittest.TestCase): a.setstate(42) self.assertEqual(a.getstate(), 42) + @support.impl_detail("the module 'xxsubtype' is internal") def test_spam_dicts(self): # Testing spamdict operations... import copy, xxsubtype as spam @@ -778,8 +791,11 @@ order (MRO) for bases """ try: callable(*args) except exc as msg: - if not str(msg).startswith(expected): - self.fail("Message %r, expected %r" % (str(msg), expected)) + # the exact msg is generally considered an impl detail + if support.check_impl_detail(): + if not str(msg).startswith(expected): + self.fail("Message %r, expected %r" % + (str(msg), expected)) else: self.fail("Expected %s" % exc) @@ -967,6 +983,7 @@ order (MRO) for bases """ x.c = Counted() self.assertEqual(Counted.counter, 3) del x + support.gc_collect() self.assertEqual(Counted.counter, 0) class D(C): pass @@ -975,6 +992,7 @@ order (MRO) for bases """ x.z = Counted() self.assertEqual(Counted.counter, 2) del x + support.gc_collect() self.assertEqual(Counted.counter, 0) class E(D): __slots__ = ['e'] @@ -984,6 +1002,7 @@ order (MRO) for bases """ x.e = Counted() self.assertEqual(Counted.counter, 3) del x + support.gc_collect() self.assertEqual(Counted.counter, 0) # Test cyclical leaks [SF bug 519621] @@ -994,21 +1013,22 @@ order (MRO) for bases """ s.a = [Counted(), s] self.assertEqual(Counted.counter, 1) s = None - import gc - gc.collect() + support.gc_collect() self.assertEqual(Counted.counter, 0) # Test lookup leaks [SF bug 572567] import sys,gc - class G(object): - def __eq__(self, other): - return 1 - g = G() - orig_objects = len(gc.get_objects()) - for i in range(10): - g==g - new_objects = len(gc.get_objects()) - self.assertEqual(orig_objects, new_objects) + if hasattr(gc, 'get_objects'): + class G(object): + def __cmp__(self, other): + return 0 + g = G() + orig_objects = len(gc.get_objects()) + for i in range(10): + g==g + new_objects = len(gc.get_objects()) + self.assertEqual(orig_objects, new_objects) + class H(object): __slots__ = ['a', 'b'] def __init__(self): @@ -1262,6 +1282,7 @@ order (MRO) for bases """ else: self.fail("classmethod shouldn't accept keyword args") + @support.impl_detail("the module 'xxsubtype' is internal") def test_classmethods_in_c(self): # Testing C-based class methods... import xxsubtype as spam @@ -1293,6 +1314,7 @@ order (MRO) for bases """ self.assertEqual(d.foo(1), (d, 1)) self.assertEqual(D.foo(d, 1), (d, 1)) + @support.impl_detail("the module 'xxsubtype' is internal") def test_staticmethods_in_c(self): # Testing C-based static methods... import xxsubtype as spam @@ -1410,6 +1432,14 @@ order (MRO) for bases """ return [self, dict, object] class X(object, metaclass=_metaclass): pass + # In CPython, the class creation above already raises + # TypeError, as a protection against the fact that + # instances of X would segfault it. In other Python + # implementations it would be ok to let the class X + # be created, but instead get a clean TypeError on the + # __setitem__ below. + x = object.__new__(X) + x[5] = 6 except TypeError: pass else: @@ -1614,6 +1644,7 @@ order (MRO) for bases """ r = weakref.ref(c) self.assertEqual(r(), c) del c + support.gc_collect() self.assertEqual(r(), None) del r class NoWeak(object): @@ -1631,6 +1662,7 @@ order (MRO) for bases """ r = weakref.ref(yes) self.assertEqual(r(), yes) del yes + support.gc_collect() self.assertEqual(r(), None) del r @@ -1936,7 +1968,10 @@ order (MRO) for bases """ # Two essentially featureless objects, just inheriting stuff from # object. - self.assertEqual(dir(None), dir(Ellipsis)) + 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): @@ -2652,7 +2687,7 @@ order (MRO) for bases """ self.fail("shouldn't allow %r.__class__ = %r" % (x, C)) try: delattr(x, "__class__") - except TypeError: + except (TypeError, AttributeError): pass else: self.fail("shouldn't allow del %r.__class__" % x) @@ -2780,6 +2815,16 @@ order (MRO) for bases """ mod.__dict__["spam"] = "eggs" # Exception's __dict__ can be replaced, but not deleted + # (at least not any more than regular exception's __dict__ can + # be deleted; on CPython it is not the case, whereas on PyPy they + # can, just like any other new-style instance's __dict__.) + def can_delete_dict(e): + try: + del e.__dict__ + except (TypeError, AttributeError): + return False + else: + return True class Exception1(Exception, Base): pass class Exception2(Base, Exception): @@ -2788,12 +2833,7 @@ order (MRO) for bases """ e = ExceptionType() e.__dict__ = {"a": 1} self.assertEqual(e.a, 1) - try: - del e.__dict__ - except (TypeError, AttributeError): - pass - else: - self.fail("%r's __dict__ can be deleted" % e) + self.assertEqual(can_delete_dict(e), can_delete_dict(ValueError())) def test_pickles(self): # Testing pickling and copying new-style classes and objects... @@ -3070,7 +3110,7 @@ order (MRO) for bases """ class B(A): pass del B - gc.collect() + support.gc_collect() A.__setitem__ = lambda *a: None # crash def test_buffer_inheritance(self): @@ -3154,6 +3194,7 @@ order (MRO) for bases """ c = C() self.assertEqual(log, []) del c + support.gc_collect() self.assertEqual(log, [1]) class D(object): pass @@ -3249,7 +3290,7 @@ order (MRO) for bases """ self.assertEqual(hasattr(m, "__name__"), 0) self.assertEqual(hasattr(m, "__file__"), 0) self.assertEqual(hasattr(m, "foo"), 0) - self.assertEqual(m.__dict__, None) + self.assertFalse(m.__dict__) # None or {} are both reasonable answers m.foo = 1 self.assertEqual(m.__dict__, {"foo": 1}) @@ -3384,17 +3425,23 @@ order (MRO) for bases """ c = C() c.attr = 42 - # The most interesting thing here is whether this blows up, due to flawed - # GC tracking logic in typeobject.c's call_finalizer() (a 2.2.1 bug). + # The most interesting thing here is whether this blows up, due to + # flawed GC tracking logic in typeobject.c's call_finalizer() (a 2.2.1 + # bug). del c # If that didn't blow up, it's also interesting to see whether clearing - # the last container slot works: that will attempt to delete c again, - # which will cause c to get appended back to the container again "during" - # the del. - del C.container[-1] + # the last container slot works: that will attempt to delete c again, + # which will cause c to get appended back to the container again + # "during" the del. (On non-CPython implementations, however, __del__ + # is typically not called again.) + support.gc_collect() self.assertEqual(len(C.container), 1) - self.assertEqual(C.container[-1].attr, 42) + del C.container[-1] + if support.check_impl_detail(): + support.gc_collect() + self.assertEqual(len(C.container), 1) + self.assertEqual(C.container[-1].attr, 42) # Make c mortal again, so that the test framework with -l doesn't report # it as a leak. @@ -3420,7 +3467,8 @@ order (MRO) for bases """ pass class C(A,B) : __slots__=() - self.assertEqual(C.__basicsize__, B.__basicsize__) + if support.check_impl_detail(): + self.assertEqual(C.__basicsize__, B.__basicsize__) self.assert_(hasattr(C, '__dict__')) self.assert_(hasattr(C, '__weakref__')) C().x = 2 @@ -3503,7 +3551,7 @@ order (MRO) for bases """ try: del D.__bases__ - except TypeError: + except (TypeError, AttributeError): pass else: self.fail("shouldn't be able to delete .__bases__") @@ -3681,6 +3729,7 @@ order (MRO) for bases """ self.assertEqual(E() // C(), "C.__floordiv__") self.assertEqual(C() // E(), "C.__floordiv__") # This one would fail + @support.impl_detail("testing an internal kind of method object") def test_meth_class_get(self): # Testing __get__ method of METH_CLASS C methods... # Full coverage of descrobject.c::classmethod_get() @@ -3866,7 +3915,7 @@ order (MRO) for bases """ self.assertEqual(c.attr, 1) # this makes a crash more likely: - import gc; gc.collect() + support.gc_collect() self.assertEqual(hasattr(c, 'attr'), False) def test_init(self): @@ -3893,8 +3942,14 @@ order (MRO) for bases """ self.assert_(l.__add__ != [5].__add__) self.assert_(l.__add__ != l.__mul__) self.assert_(l.__add__.__name__ == '__add__') - self.assert_(l.__add__.__self__ is l) - self.assert_(l.__add__.__objclass__ is list) + if hasattr(l.__add__, '__self__'): + # CPython + self.assert_(l.__add__.__self__ is l) + self.assert_(l.__add__.__objclass__ is list) + else: + # Python implementations where [].__add__ is a normal bound method + self.assert_(l.__add__.im_self is l) + self.assert_(l.__add__.im_class is list) self.assertEqual(l.__add__.__doc__, list.__add__.__doc__) try: hash(l.__add__) |