[Python-checkins] r57409 - in python/trunk/Lib/test: output/test_class test_class.py

georg.brandl python-checkins at python.org
Fri Aug 24 21:33:54 CEST 2007


Author: georg.brandl
Date: Fri Aug 24 21:33:53 2007
New Revision: 57409

Removed:
   python/trunk/Lib/test/output/test_class
Modified:
   python/trunk/Lib/test/test_class.py
Log:
Port test_class to unittest. Patch #1671298.


Deleted: /python/trunk/Lib/test/output/test_class
==============================================================================
--- /python/trunk/Lib/test/output/test_class	Fri Aug 24 21:33:53 2007
+++ (empty file)
@@ -1,101 +0,0 @@
-test_class
-__init__: ()
-__coerce__: (1,)
-__add__: (1,)
-__coerce__: (1,)
-__radd__: (1,)
-__coerce__: (1,)
-__sub__: (1,)
-__coerce__: (1,)
-__rsub__: (1,)
-__coerce__: (1,)
-__mul__: (1,)
-__coerce__: (1,)
-__rmul__: (1,)
-__coerce__: (1,)
-__div__: (1,)
-__coerce__: (1,)
-__rdiv__: (1,)
-__coerce__: (1,)
-__mod__: (1,)
-__coerce__: (1,)
-__rmod__: (1,)
-__coerce__: (1,)
-__divmod__: (1,)
-__coerce__: (1,)
-__rdivmod__: (1,)
-__coerce__: (1,)
-__pow__: (1,)
-__coerce__: (1,)
-__rpow__: (1,)
-__coerce__: (1,)
-__rshift__: (1,)
-__coerce__: (1,)
-__rrshift__: (1,)
-__coerce__: (1,)
-__lshift__: (1,)
-__coerce__: (1,)
-__rlshift__: (1,)
-__coerce__: (1,)
-__and__: (1,)
-__coerce__: (1,)
-__rand__: (1,)
-__coerce__: (1,)
-__or__: (1,)
-__coerce__: (1,)
-__ror__: (1,)
-__coerce__: (1,)
-__xor__: (1,)
-__coerce__: (1,)
-__rxor__: (1,)
-__contains__: (1,)
-__getitem__: (1,)
-__setitem__: (1, 1)
-__delitem__: (1,)
-__getslice__: (0, 42)
-__setslice__: (0, 42, 'The Answer')
-__delslice__: (0, 42)
-__getitem__: (slice(2, 1024, 10),)
-__setitem__: (slice(2, 1024, 10), 'A lot')
-__delitem__: (slice(2, 1024, 10),)
-__getitem__: ((slice(None, 42, None), Ellipsis, slice(None, 24, None), 24, 100),)
-__setitem__: ((slice(None, 42, None), Ellipsis, slice(None, 24, None), 24, 100), 'Strange')
-__delitem__: ((slice(None, 42, None), Ellipsis, slice(None, 24, None), 24, 100),)
-__getitem__: (slice(0, 42, None),)
-__setitem__: (slice(0, 42, None), 'The Answer')
-__delitem__: (slice(0, 42, None),)
-__neg__: ()
-__pos__: ()
-__abs__: ()
-__int__: ()
-__long__: ()
-__float__: ()
-__oct__: ()
-__hex__: ()
-__hash__: ()
-__repr__: ()
-__str__: ()
-__coerce__: (1,)
-__cmp__: (1,)
-__coerce__: (1,)
-__cmp__: (1,)
-__coerce__: (1,)
-__cmp__: (1,)
-__coerce__: (1,)
-__cmp__: (1,)
-__coerce__: (1,)
-__cmp__: (1,)
-__coerce__: (1,)
-__cmp__: (1,)
-__coerce__: (1,)
-__cmp__: (1,)
-__coerce__: (1,)
-__cmp__: (1,)
-__coerce__: (1,)
-__cmp__: (1,)
-__coerce__: (1,)
-__cmp__: (1,)
-__del__: ()
-__getattr__: ('spam',)
-__setattr__: ('eggs', 'spam, spam, spam and ham')
-__delattr__: ('cardinal',)

Modified: python/trunk/Lib/test/test_class.py
==============================================================================
--- python/trunk/Lib/test/test_class.py	(original)
+++ python/trunk/Lib/test/test_class.py	Fri Aug 24 21:33:53 2007
@@ -1,6 +1,9 @@
 "Test the functionality of Python classes implementing operators."
 
-from test.test_support import TestFailed
+import unittest
+import sys
+
+from test import test_support
 
 testmeths = [
 
@@ -64,55 +67,62 @@
 #    "setattr",
 #    "delattr",
 
+callLst = []
+def trackCall(f):
+    def track(*args, **kwargs):
+        callLst.append((f.__name__, args))
+        return f(*args, **kwargs)
+    return track
+
 class AllTests:
+    trackCall = trackCall
+
+    @trackCall
     def __coerce__(self, *args):
-        print "__coerce__:", args
         return (self,) + args
 
+    @trackCall
     def __hash__(self, *args):
-        print "__hash__:", args
         return hash(id(self))
 
+    @trackCall
     def __str__(self, *args):
-        print "__str__:", args
         return "AllTests"
 
+    @trackCall
     def __repr__(self, *args):
-        print "__repr__:", args
         return "AllTests"
 
+    @trackCall
     def __int__(self, *args):
-        print "__int__:", args
         return 1
 
+    @trackCall
     def __float__(self, *args):
-        print "__float__:", args
         return 1.0
 
+    @trackCall
     def __long__(self, *args):
-        print "__long__:", args
         return 1L
 
+    @trackCall
     def __oct__(self, *args):
-        print "__oct__:", args
         return '01'
 
+    @trackCall
     def __hex__(self, *args):
-        print "__hex__:", args
         return '0x1'
 
+    @trackCall
     def __cmp__(self, *args):
-        print "__cmp__:", args
         return 0
 
-    def __del__(self, *args):
-        print "__del__:", args
-
-# Synthesize AllTests methods from the names in testmeths.
+# Synthesize all the other AllTests methods from the names in testmeths.
 
 method_template = """\
+ at trackCall
 def __%(method)s__(self, *args):
-    print "__%(method)s__:", args
+    pass
 """
 
 for method in testmeths:
@@ -120,293 +130,494 @@
 
 del method, method_template
 
-# this also tests __init__ of course.
-testme = AllTests()
-
-# Binary operations
-
-testme + 1
-1 + testme
-
-testme - 1
-1 - testme
-
-testme * 1
-1 * testme
-
-if 1/2 == 0:
-    testme / 1
-    1 / testme
-else:
-    # True division is in effect, so "/" doesn't map to __div__ etc; but
-    # the canned expected-output file requires that __div__ etc get called.
-    testme.__coerce__(1)
-    testme.__div__(1)
-    testme.__coerce__(1)
-    testme.__rdiv__(1)
-
-testme % 1
-1 % testme
-
-divmod(testme,1)
-divmod(1, testme)
-
-testme ** 1
-1 ** testme
-
-testme >> 1
-1 >> testme
-
-testme << 1
-1 << testme
-
-testme & 1
-1 & testme
-
-testme | 1
-1 | testme
-
-testme ^ 1
-1 ^ testme
-
-
-# List/dict operations
-
-class Empty: pass
-
-try:
-    1 in Empty()
-    print 'failed, should have raised TypeError'
-except TypeError:
-    pass
-
-1 in testme
-
-testme[1]
-testme[1] = 1
-del testme[1]
-
-testme[:42]
-testme[:42] = "The Answer"
-del testme[:42]
-
-testme[2:1024:10]
-testme[2:1024:10] = "A lot"
-del testme[2:1024:10]
-
-testme[:42, ..., :24:, 24, 100]
-testme[:42, ..., :24:, 24, 100] = "Strange"
-del testme[:42, ..., :24:, 24, 100]
-
+class ClassTests(unittest.TestCase):
+    def setUp(self):
+        callLst[:] = []
+
+    def assertCallStack(self, expected_calls):
+        actualCallList = callLst[:]  # need to copy because the comparison below will add
+                                     # additional calls to callLst
+        if expected_calls != actualCallList:
+            self.fail("Expected call list:\n  %s\ndoes not match actual call list\n  %s" %
+                      (expected_calls, actualCallList))
+
+    def testInit(self):
+        foo = AllTests()
+        self.assertCallStack([("__init__", (foo,))])
+
+    def testBinaryOps(self):
+        testme = AllTests()
+        # Binary operations
+
+        callLst[:] = []
+        testme + 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__add__", (testme, 1))])
+
+        callLst[:] = []
+        1 + testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__radd__", (testme, 1))])
+
+        callLst[:] = []
+        testme - 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__sub__", (testme, 1))])
+
+        callLst[:] = []
+        1 - testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__rsub__", (testme, 1))])
+
+        callLst[:] = []
+        testme * 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__mul__", (testme, 1))])
+
+        callLst[:] = []
+        1 * testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__rmul__", (testme, 1))])
+
+        if 1/2 == 0:
+            callLst[:] = []
+            testme / 1
+            self.assertCallStack([("__coerce__", (testme, 1)), ("__div__", (testme, 1))])
+
+
+            callLst[:] = []
+            1 / testme
+            self.assertCallStack([("__coerce__", (testme, 1)), ("__rdiv__", (testme, 1))])
+
+        callLst[:] = []
+        testme % 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__mod__", (testme, 1))])
+
+        callLst[:] = []
+        1 % testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__rmod__", (testme, 1))])
+
+
+        callLst[:] = []
+        divmod(testme,1)
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__divmod__", (testme, 1))])
+
+        callLst[:] = []
+        divmod(1, testme)
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__rdivmod__", (testme, 1))])
+
+        callLst[:] = []
+        testme ** 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__pow__", (testme, 1))])
+
+        callLst[:] = []
+        1 ** testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__rpow__", (testme, 1))])
+
+        callLst[:] = []
+        testme >> 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__rshift__", (testme, 1))])
+
+        callLst[:] = []
+        1 >> testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__rrshift__", (testme, 1))])
+
+        callLst[:] = []
+        testme << 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__lshift__", (testme, 1))])
+
+        callLst[:] = []
+        1 << testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__rlshift__", (testme, 1))])
+
+        callLst[:] = []
+        testme & 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__and__", (testme, 1))])
+
+        callLst[:] = []
+        1 & testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__rand__", (testme, 1))])
+
+        callLst[:] = []
+        testme | 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__or__", (testme, 1))])
+
+        callLst[:] = []
+        1 | testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__ror__", (testme, 1))])
+
+        callLst[:] = []
+        testme ^ 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__xor__", (testme, 1))])
+
+        callLst[:] = []
+        1 ^ testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ("__rxor__", (testme, 1))])
+
+    def testListAndDictOps(self):
+        testme = AllTests()
+
+        # List/dict operations
+
+        class Empty: pass
+
+        try:
+            1 in Empty()
+            self.fail('failed, should have raised TypeError')
+        except TypeError:
+            pass
+
+        callLst[:] = []
+        1 in testme
+        self.assertCallStack([('__contains__', (testme, 1))])
+
+        callLst[:] = []
+        testme[1]
+        self.assertCallStack([('__getitem__', (testme, 1))])
+
+        callLst[:] = []
+        testme[1] = 1
+        self.assertCallStack([('__setitem__', (testme, 1, 1))])
+
+        callLst[:] = []
+        del testme[1]
+        self.assertCallStack([('__delitem__', (testme, 1))])
+
+        callLst[:] = []
+        testme[:42]
+        self.assertCallStack([('__getslice__', (testme, 0, 42))])
+
+        callLst[:] = []
+        testme[:42] = "The Answer"
+        self.assertCallStack([('__setslice__', (testme, 0, 42, "The Answer"))])
+
+        callLst[:] = []
+        del testme[:42]
+        self.assertCallStack([('__delslice__', (testme, 0, 42))])
+
+        callLst[:] = []
+        testme[2:1024:10]
+        self.assertCallStack([('__getitem__', (testme, slice(2, 1024, 10)))])
+
+        callLst[:] = []
+        testme[2:1024:10] = "A lot"
+        self.assertCallStack([('__setitem__', (testme, slice(2, 1024, 10),
+                                                                    "A lot"))])
+        callLst[:] = []
+        del testme[2:1024:10]
+        self.assertCallStack([('__delitem__', (testme, slice(2, 1024, 10)))])
+
+        callLst[:] = []
+        testme[:42, ..., :24:, 24, 100]
+        self.assertCallStack([('__getitem__', (testme, (slice(None, 42, None),
+                                                        Ellipsis,
+                                                        slice(None, 24, None),
+                                                        24, 100)))])
+        callLst[:] = []
+        testme[:42, ..., :24:, 24, 100] = "Strange"
+        self.assertCallStack([('__setitem__', (testme, (slice(None, 42, None),
+                                                        Ellipsis,
+                                                        slice(None, 24, None),
+                                                        24, 100), "Strange"))])
+        callLst[:] = []
+        del testme[:42, ..., :24:, 24, 100]
+        self.assertCallStack([('__delitem__', (testme, (slice(None, 42, None),
+                                                        Ellipsis,
+                                                        slice(None, 24, None),
+                                                        24, 100)))])
+
+        # Now remove the slice hooks to see if converting normal slices to
+        #  slice object works.
+
+        getslice = AllTests.__getslice__
+        del AllTests.__getslice__
+        setslice = AllTests.__setslice__
+        del AllTests.__setslice__
+        delslice = AllTests.__delslice__
+        del AllTests.__delslice__
+
+        # XXX when using new-style classes the slice testme[:42] produces
+        #  slice(None, 42, None) instead of slice(0, 42, None). py3k will have
+        #  to change this test.
+        callLst[:] = []
+        testme[:42]
+        self.assertCallStack([('__getitem__', (testme, slice(0, 42, None)))])
+
+        callLst[:] = []
+        testme[:42] = "The Answer"
+        self.assertCallStack([('__setitem__', (testme, slice(0, 42, None),
+                                                                "The Answer"))])
+        callLst[:] = []
+        del testme[:42]
+        self.assertCallStack([('__delitem__', (testme, slice(0, 42, None)))])
+
+        # Restore the slice methods, or the tests will fail with regrtest -R.
+        AllTests.__getslice__ = getslice
+        AllTests.__setslice__ = setslice
+        AllTests.__delslice__ = delslice
+
+
+    def testUnaryOps(self):
+        testme = AllTests()
+
+        callLst[:] = []
+        -testme
+        self.assertCallStack([('__neg__', (testme,))])
+        callLst[:] = []
+        +testme
+        self.assertCallStack([('__pos__', (testme,))])
+        callLst[:] = []
+        abs(testme)
+        self.assertCallStack([('__abs__', (testme,))])
+        callLst[:] = []
+        int(testme)
+        self.assertCallStack([('__int__', (testme,))])
+        callLst[:] = []
+        long(testme)
+        self.assertCallStack([('__long__', (testme,))])
+        callLst[:] = []
+        float(testme)
+        self.assertCallStack([('__float__', (testme,))])
+        callLst[:] = []
+        oct(testme)
+        self.assertCallStack([('__oct__', (testme,))])
+        callLst[:] = []
+        hex(testme)
+        self.assertCallStack([('__hex__', (testme,))])
+
+
+    def testMisc(self):
+        testme = AllTests()
+
+        callLst[:] = []
+        hash(testme)
+        self.assertCallStack([('__hash__', (testme,))])
+
+        callLst[:] = []
+        repr(testme)
+        self.assertCallStack([('__repr__', (testme,))])
+
+        callLst[:] = []
+        str(testme)
+        self.assertCallStack([('__str__', (testme,))])
+
+        callLst[:] = []
+        testme == 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (testme, 1))])
+
+        callLst[:] = []
+        testme < 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (testme, 1))])
+
+        callLst[:] = []
+        testme > 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (testme, 1))])
+
+        callLst[:] = []
+        testme <> 1  # XXX kill this in py3k
+        self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (testme, 1))])
+
+        callLst[:] = []
+        testme != 1
+        self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (testme, 1))])
+
+        callLst[:] = []
+        1 == testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (1, testme))])
+
+        callLst[:] = []
+        1 < testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (1, testme))])
+
+        callLst[:] = []
+        1 > testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (1, testme))])
+
+        callLst[:] = []
+        1 <> testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (1, testme))])
+
+        callLst[:] = []
+        1 != testme
+        self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (1, testme))])
+
+
+    def testGetSetAndDel(self):
+        # Interfering tests
+        class ExtraTests(AllTests):
+            @trackCall
+            def __getattr__(self, *args):
+                return "SomeVal"
+
+            @trackCall
+            def __setattr__(self, *args):
+                pass
+
+            @trackCall
+            def __delattr__(self, *args):
+                pass
+
+        testme = ExtraTests()
+
+        callLst[:] = []
+        testme.spam
+        self.assertCallStack([('__getattr__', (testme, "spam"))])
+
+        callLst[:] = []
+        testme.eggs = "spam, spam, spam and ham"
+        self.assertCallStack([('__setattr__', (testme, "eggs",
+                                               "spam, spam, spam and ham"))])
+
+        callLst[:] = []
+        del testme.cardinal
+        self.assertCallStack([('__delattr__', (testme, "cardinal"))])
+
+    def testDel(self):
+        x = []
+
+        class DelTest:
+            def __del__(self):
+                x.append("crab people, crab people")
+        testme = DelTest()
+        del testme
+        import gc
+        gc.collect()
+        self.assertEquals(["crab people, crab people"], x)
+
+    def testBadTypeReturned(self):
+        # return values of some method are type-checked
+        class BadTypeClass:
+            def __int__(self):
+                return None
+            __float__ = __int__
+            __long__ = __int__
+            __str__ = __int__
+            __repr__ = __int__
+            __oct__ = __int__
+            __hex__ = __int__
+
+        for f in [int, float, long, str, repr, oct, hex]:
+            self.assertRaises(TypeError, f, BadTypeClass())
+
+    def testMixIntsAndLongs(self):
+        # mixing up ints and longs is okay
+        class IntLongMixClass:
+            @trackCall
+            def __int__(self):
+                return 42L
+
+            @trackCall
+            def __long__(self):
+                return 64
+
+        mixIntAndLong = IntLongMixClass()
+
+        callLst[:] = []
+        as_int = int(mixIntAndLong)
+        self.assertEquals(type(as_int), long)
+        self.assertEquals(as_int, 42L)
+        self.assertCallStack([('__int__', (mixIntAndLong,))])
+
+        callLst[:] = []
+        as_long = long(mixIntAndLong)
+        self.assertEquals(type(as_long), int)
+        self.assertEquals(as_long, 64)
+        self.assertCallStack([('__long__', (mixIntAndLong,))])
+
+    def testHashStuff(self):
+        # Test correct errors from hash() on objects with comparisons but
+        #  no __hash__
+
+        class C0:
+            pass
+
+        hash(C0()) # This should work; the next two should raise TypeError
+
+        class C1:
+            def __cmp__(self, other): return 0
+
+        self.assertRaises(TypeError, hash, C1())
+
+        class C2:
+            def __eq__(self, other): return 1
+
+        self.assertRaises(TypeError, hash, C2())
+
+
+    def testSFBug532646(self):
+        # Test for SF bug 532646
+
+        class A:
+            pass
+        A.__call__ = A()
+        a = A()
+
+        try:
+            a() # This should not segfault
+        except RuntimeError:
+            pass
+        else:
+            self.fail("Failed to raise RuntimeError")
+
+    def testForExceptionsRaisedInInstanceGetattr2(self):
+        # Tests for exceptions raised in instance_getattr2().
+
+        def booh(self):
+            raise AttributeError("booh")
+
+        class A:
+            a = property(booh)
+        try:
+            A().a # Raised AttributeError: A instance has no attribute 'a'
+        except AttributeError, x:
+            if str(x) != "booh":
+                self.fail("attribute error for A().a got masked: %s" % x)
+
+        class E:
+            __eq__ = property(booh)
+        E() == E() # In debug mode, caused a C-level assert() to fail
+
+        class I:
+            __init__ = property(booh)
+        try:
+            # In debug mode, printed XXX undetected error and
+            #  raises AttributeError
+            I()
+        except AttributeError, x:
+            pass
+        else:
+            self.fail("attribute error for I.__init__ got masked")
+
+    def testHashComparisonOfMethods(self):
+        # Test comparison and hash of methods
+        class A:
+            def __init__(self, x):
+                self.x = x
+            def f(self):
+                pass
+            def g(self):
+                pass
+            def __eq__(self, other):
+                return self.x == other.x
+            def __hash__(self):
+                return self.x
+        class B(A):
+            pass
+
+        a1 = A(1)
+        a2 = A(2)
+        self.assertEquals(a1.f, a1.f)
+        self.assertNotEquals(a1.f, a2.f)
+        self.assertNotEquals(a1.f, a1.g)
+        self.assertEquals(a1.f, A(1).f)
+        self.assertEquals(hash(a1.f), hash(a1.f))
+        self.assertEquals(hash(a1.f), hash(A(1).f))
+
+        self.assertNotEquals(A.f, a1.f)
+        self.assertNotEquals(A.f, A.g)
+        self.assertEquals(B.f, A.f)
+        self.assertEquals(hash(B.f), hash(A.f))
+
+        # the following triggers a SystemError in 2.4
+        a = A(hash(A.f.im_func)^(-1))
+        hash(a.f)
 
-# Now remove the slice hooks to see if converting normal slices to slice
-# object works.
-
-del AllTests.__getslice__
-del AllTests.__setslice__
-del AllTests.__delslice__
-
-import sys
-if sys.platform[:4] != 'java':
-    testme[:42]
-    testme[:42] = "The Answer"
-    del testme[:42]
-else:
-    # This works under Jython, but the actual slice values are
-    # different.
-    print "__getitem__: (slice(0, 42, None),)"
-    print "__setitem__: (slice(0, 42, None), 'The Answer')"
-    print "__delitem__: (slice(0, 42, None),)"
-
-# Unary operations
-
--testme
-+testme
-abs(testme)
-int(testme)
-long(testme)
-float(testme)
-oct(testme)
-hex(testme)
-
-# And the rest...
-
-hash(testme)
-repr(testme)
-str(testme)
-
-testme == 1
-testme < 1
-testme > 1
-testme <> 1
-testme != 1
-1 == testme
-1 < testme
-1 > testme
-1 <> testme
-1 != testme
-
-# This test has to be last (duh.)
-
-del testme
-if sys.platform[:4] == 'java':
-    import java
-    java.lang.System.gc()
-
-# Interfering tests
-
-class ExtraTests:
-    def __getattr__(self, *args):
-        print "__getattr__:", args
-        return "SomeVal"
-
-    def __setattr__(self, *args):
-        print "__setattr__:", args
-
-    def __delattr__(self, *args):
-        print "__delattr__:", args
-
-testme = ExtraTests()
-testme.spam
-testme.eggs = "spam, spam, spam and ham"
-del testme.cardinal
-
-
-# return values of some method are type-checked
-class BadTypeClass:
-    def __int__(self):
-        return None
-    __float__ = __int__
-    __long__ = __int__
-    __str__ = __int__
-    __repr__ = __int__
-    __oct__ = __int__
-    __hex__ = __int__
-
-def check_exc(stmt, exception):
-    """Raise TestFailed if executing 'stmt' does not raise 'exception'
-    """
-    try:
-        exec stmt
-    except exception:
-        pass
-    else:
-        raise TestFailed, "%s should raise %s" % (stmt, exception)
-
-check_exc("int(BadTypeClass())", TypeError)
-check_exc("float(BadTypeClass())", TypeError)
-check_exc("long(BadTypeClass())", TypeError)
-check_exc("str(BadTypeClass())", TypeError)
-check_exc("repr(BadTypeClass())", TypeError)
-check_exc("oct(BadTypeClass())", TypeError)
-check_exc("hex(BadTypeClass())", TypeError)
-
-# mixing up ints and longs is okay
-class IntLongMixClass:
-    def __int__(self):
-        return 0L
-
-    def __long__(self):
-        return 0
-
-try:
-    int(IntLongMixClass())
-except TypeError:
-    raise TestFailed, "TypeError should not be raised"
-
-try:
-    long(IntLongMixClass())
-except TypeError:
-    raise TestFailed, "TypeError should not be raised"
-
-
-# Test correct errors from hash() on objects with comparisons but no __hash__
-
-class C0:
-    pass
-
-hash(C0()) # This should work; the next two should raise TypeError
-
-class C1:
-    def __cmp__(self, other): return 0
-
-check_exc("hash(C1())", TypeError)
-
-class C2:
-    def __eq__(self, other): return 1
-
-check_exc("hash(C2())", TypeError)
-
-# Test for SF bug 532646
-
-class A:
-    pass
-A.__call__ = A()
-a = A()
-try:
-    a() # This should not segfault
-except RuntimeError:
-    pass
-else:
-    raise TestFailed, "how could this not have overflowed the stack?"
-
-
-# Tests for exceptions raised in instance_getattr2().
-
-def booh(self):
-    raise AttributeError, "booh"
-
-class A:
-    a = property(booh)
-try:
-    A().a # Raised AttributeError: A instance has no attribute 'a'
-except AttributeError, x:
-    if str(x) != "booh":
-        print "attribute error for A().a got masked:", str(x)
-
-class E:
-    __eq__ = property(booh)
-E() == E() # In debug mode, caused a C-level assert() to fail
-
-class I:
-    __init__ = property(booh)
-try:
-    I() # In debug mode, printed XXX undetected error and raises AttributeError
-except AttributeError, x:
-    pass
-else:
-    print "attribute error for I.__init__ got masked"
-
-
-# Test comparison and hash of methods
-class A:
-    def __init__(self, x):
-        self.x = x
-    def f(self):
-        pass
-    def g(self):
-        pass
-    def __eq__(self, other):
-        return self.x == other.x
-    def __hash__(self):
-        return self.x
-class B(A):
-    pass
+def test_main():
+    test_support.run_unittest(ClassTests)
 
-a1 = A(1)
-a2 = A(2)
-assert a1.f == a1.f
-assert a1.f != a2.f
-assert a1.f != a1.g
-assert a1.f == A(1).f
-assert hash(a1.f) == hash(a1.f)
-assert hash(a1.f) == hash(A(1).f)
-
-assert A.f != a1.f
-assert A.f != A.g
-assert B.f == A.f
-assert hash(B.f) == hash(A.f)
-
-# the following triggers a SystemError in 2.4
-a = A(hash(A.f.im_func)^(-1))
-hash(a.f)
+if __name__=='__main__':
+    test_main()


More information about the Python-checkins mailing list