summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_descr.py
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2009-03-28 21:42:05 (GMT)
committerBenjamin Peterson <benjamin@python.org>2009-03-28 21:42:05 (GMT)
commite549ead8263819ac47f60cdd0239592750888f0b (patch)
tree7e1199b4b197ac5facd66b03cbb7e768fa2b6892 /Lib/test/test_descr.py
parentb556452055590c6d8f658d90c6be00aec31f5620 (diff)
downloadcpython-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.py139
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__)