Kaydet (Commit) c3255565 authored tarafından Georg Brandl's avatar Georg Brandl

Port test_class to unittest. Patch #1671298.

üst ff9b9633
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',)
"Test the functionality of Python classes implementing operators." "Test the functionality of Python classes implementing operators."
from test.test_support import TestFailed import unittest
import sys
from test import test_support
testmeths = [ testmeths = [
...@@ -64,55 +67,62 @@ testmeths = [ ...@@ -64,55 +67,62 @@ testmeths = [
# "setattr", # "setattr",
# "delattr", # "delattr",
callLst = []
def trackCall(f):
def track(*args, **kwargs):
callLst.append((f.__name__, args))
return f(*args, **kwargs)
return track
class AllTests: class AllTests:
trackCall = trackCall
@trackCall
def __coerce__(self, *args): def __coerce__(self, *args):
print "__coerce__:", args
return (self,) + args return (self,) + args
@trackCall
def __hash__(self, *args): def __hash__(self, *args):
print "__hash__:", args
return hash(id(self)) return hash(id(self))
@trackCall
def __str__(self, *args): def __str__(self, *args):
print "__str__:", args
return "AllTests" return "AllTests"
@trackCall
def __repr__(self, *args): def __repr__(self, *args):
print "__repr__:", args
return "AllTests" return "AllTests"
@trackCall
def __int__(self, *args): def __int__(self, *args):
print "__int__:", args
return 1 return 1
@trackCall
def __float__(self, *args): def __float__(self, *args):
print "__float__:", args
return 1.0 return 1.0
@trackCall
def __long__(self, *args): def __long__(self, *args):
print "__long__:", args
return 1L return 1L
@trackCall
def __oct__(self, *args): def __oct__(self, *args):
print "__oct__:", args
return '01' return '01'
@trackCall
def __hex__(self, *args): def __hex__(self, *args):
print "__hex__:", args
return '0x1' return '0x1'
@trackCall
def __cmp__(self, *args): def __cmp__(self, *args):
print "__cmp__:", args
return 0 return 0
def __del__(self, *args): # Synthesize all the other AllTests methods from the names in testmeths.
print "__del__:", args
# Synthesize AllTests methods from the names in testmeths.
method_template = """\ method_template = """\
@trackCall
def __%(method)s__(self, *args): def __%(method)s__(self, *args):
print "__%(method)s__:", args pass
""" """
for method in testmeths: for method in testmeths:
...@@ -120,160 +130,357 @@ for method in testmeths: ...@@ -120,160 +130,357 @@ for method in testmeths:
del method, method_template del method, method_template
# this also tests __init__ of course. class ClassTests(unittest.TestCase):
testme = AllTests() def setUp(self):
callLst[:] = []
# Binary operations 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))
testme + 1 def testInit(self):
1 + testme foo = AllTests()
self.assertCallStack([("__init__", (foo,))])
testme - 1 def testBinaryOps(self):
1 - testme testme = AllTests()
# Binary operations
testme * 1 callLst[:] = []
1 * testme testme + 1
self.assertCallStack([("__coerce__", (testme, 1)), ("__add__", (testme, 1))])
if 1/2 == 0: 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 testme / 1
self.assertCallStack([("__coerce__", (testme, 1)), ("__div__", (testme, 1))])
callLst[:] = []
1 / testme 1 / testme
else: self.assertCallStack([("__coerce__", (testme, 1)), ("__rdiv__", (testme, 1))])
# 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 callLst[:] = []
1 % testme testme % 1
self.assertCallStack([("__coerce__", (testme, 1)), ("__mod__", (testme, 1))])
divmod(testme,1) callLst[:] = []
divmod(1, testme) 1 % testme
self.assertCallStack([("__coerce__", (testme, 1)), ("__rmod__", (testme, 1))])
testme ** 1
1 ** testme
testme >> 1 callLst[:] = []
1 >> testme divmod(testme,1)
self.assertCallStack([("__coerce__", (testme, 1)), ("__divmod__", (testme, 1))])
testme << 1 callLst[:] = []
1 << testme divmod(1, testme)
self.assertCallStack([("__coerce__", (testme, 1)), ("__rdivmod__", (testme, 1))])
testme & 1 callLst[:] = []
1 & testme testme ** 1
self.assertCallStack([("__coerce__", (testme, 1)), ("__pow__", (testme, 1))])
testme | 1 callLst[:] = []
1 | testme 1 ** testme
self.assertCallStack([("__coerce__", (testme, 1)), ("__rpow__", (testme, 1))])
testme ^ 1 callLst[:] = []
1 ^ testme testme >> 1
self.assertCallStack([("__coerce__", (testme, 1)), ("__rshift__", (testme, 1))])
callLst[:] = []
1 >> testme
self.assertCallStack([("__coerce__", (testme, 1)), ("__rrshift__", (testme, 1))])
# List/dict operations callLst[:] = []
testme << 1
self.assertCallStack([("__coerce__", (testme, 1)), ("__lshift__", (testme, 1))])
class Empty: pass callLst[:] = []
1 << testme
self.assertCallStack([("__coerce__", (testme, 1)), ("__rlshift__", (testme, 1))])
try: callLst[:] = []
1 in Empty() testme & 1
print 'failed, should have raised TypeError' self.assertCallStack([("__coerce__", (testme, 1)), ("__and__", (testme, 1))])
except TypeError:
pass
1 in testme callLst[:] = []
1 & testme
self.assertCallStack([("__coerce__", (testme, 1)), ("__rand__", (testme, 1))])
testme[1] callLst[:] = []
testme[1] = 1 testme | 1
del testme[1] self.assertCallStack([("__coerce__", (testme, 1)), ("__or__", (testme, 1))])
testme[:42] callLst[:] = []
testme[:42] = "The Answer" 1 | testme
del testme[:42] self.assertCallStack([("__coerce__", (testme, 1)), ("__ror__", (testme, 1))])
testme[2:1024:10] callLst[:] = []
testme[2:1024:10] = "A lot" testme ^ 1
del testme[2:1024:10] self.assertCallStack([("__coerce__", (testme, 1)), ("__xor__", (testme, 1))])
testme[:42, ..., :24:, 24, 100] callLst[:] = []
testme[:42, ..., :24:, 24, 100] = "Strange" 1 ^ testme
del testme[:42, ..., :24:, 24, 100] self.assertCallStack([("__coerce__", (testme, 1)), ("__rxor__", (testme, 1))])
def testListAndDictOps(self):
testme = AllTests()
# Now remove the slice hooks to see if converting normal slices to slice # List/dict operations
# object works.
del AllTests.__getslice__ class Empty: pass
del AllTests.__setslice__
del AllTests.__delslice__
import sys try:
if sys.platform[:4] != 'java': 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] testme[:42]
self.assertCallStack([('__getslice__', (testme, 0, 42))])
callLst[:] = []
testme[:42] = "The Answer" testme[:42] = "The Answer"
del testme[:42] self.assertCallStack([('__setslice__', (testme, 0, 42, "The Answer"))])
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 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)))])
-testme callLst[:] = []
+testme testme[:42] = "The Answer"
abs(testme) self.assertCallStack([('__setitem__', (testme, slice(0, 42, None),
int(testme) "The Answer"))])
long(testme) callLst[:] = []
float(testme) del testme[:42]
oct(testme) self.assertCallStack([('__delitem__', (testme, slice(0, 42, None)))])
hex(testme)
# Restore the slice methods, or the tests will fail with regrtest -R.
# And the rest... AllTests.__getslice__ = getslice
AllTests.__setslice__ = setslice
hash(testme) AllTests.__delslice__ = delslice
repr(testme)
str(testme)
def testUnaryOps(self):
testme == 1 testme = AllTests()
testme < 1
testme > 1 callLst[:] = []
testme <> 1 -testme
testme != 1 self.assertCallStack([('__neg__', (testme,))])
1 == testme callLst[:] = []
1 < testme +testme
1 > testme self.assertCallStack([('__pos__', (testme,))])
1 <> testme callLst[:] = []
1 != testme abs(testme)
self.assertCallStack([('__abs__', (testme,))])
# This test has to be last (duh.) callLst[:] = []
int(testme)
del testme self.assertCallStack([('__int__', (testme,))])
if sys.platform[:4] == 'java': callLst[:] = []
import java long(testme)
java.lang.System.gc() self.assertCallStack([('__long__', (testme,))])
callLst[:] = []
# Interfering tests float(testme)
self.assertCallStack([('__float__', (testme,))])
class ExtraTests: 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): def __getattr__(self, *args):
print "__getattr__:", args
return "SomeVal" return "SomeVal"
@trackCall
def __setattr__(self, *args): def __setattr__(self, *args):
print "__setattr__:", args pass
@trackCall
def __delattr__(self, *args): def __delattr__(self, *args):
print "__delattr__:", args pass
testme = ExtraTests()
callLst[:] = []
testme.spam
self.assertCallStack([('__getattr__', (testme, "spam"))])
testme = ExtraTests() callLst[:] = []
testme.spam testme.eggs = "spam, spam, spam and ham"
testme.eggs = "spam, spam, spam and ham" self.assertCallStack([('__setattr__', (testme, "eggs",
del testme.cardinal "spam, spam, spam and ham"))])
callLst[:] = []
del testme.cardinal
self.assertCallStack([('__delattr__', (testme, "cardinal"))])
# return values of some method are type-checked def testDel(self):
class BadTypeClass: 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): def __int__(self):
return None return None
__float__ = __int__ __float__ = __int__
...@@ -283,103 +490,101 @@ class BadTypeClass: ...@@ -283,103 +490,101 @@ class BadTypeClass:
__oct__ = __int__ __oct__ = __int__
__hex__ = __int__ __hex__ = __int__
def check_exc(stmt, exception): for f in [int, float, long, str, repr, oct, hex]:
"""Raise TestFailed if executing 'stmt' does not raise 'exception' self.assertRaises(TypeError, f, BadTypeClass())
"""
try: def testMixIntsAndLongs(self):
exec stmt # mixing up ints and longs is okay
except exception: class IntLongMixClass:
pass @trackCall
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): def __int__(self):
return 0L return 42L
@trackCall
def __long__(self): def __long__(self):
return 0 return 64
try: mixIntAndLong = IntLongMixClass()
int(IntLongMixClass())
except TypeError:
raise TestFailed, "TypeError should not be raised"
try: callLst[:] = []
long(IntLongMixClass()) as_int = int(mixIntAndLong)
except TypeError: self.assertEquals(type(as_int), long)
raise TestFailed, "TypeError should not be raised" 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,))])
# Test correct errors from hash() on objects with comparisons but no __hash__ def testHashStuff(self):
# Test correct errors from hash() on objects with comparisons but
# no __hash__
class C0: class C0:
pass pass
hash(C0()) # This should work; the next two should raise TypeError hash(C0()) # This should work; the next two should raise TypeError
class C1: class C1:
def __cmp__(self, other): return 0 def __cmp__(self, other): return 0
check_exc("hash(C1())", TypeError) self.assertRaises(TypeError, hash, C1())
class C2: class C2:
def __eq__(self, other): return 1 def __eq__(self, other): return 1
check_exc("hash(C2())", TypeError) self.assertRaises(TypeError, hash, C2())
# Test for SF bug 532646
class A: def testSFBug532646(self):
# Test for SF bug 532646
class A:
pass pass
A.__call__ = A() A.__call__ = A()
a = A() a = A()
try:
try:
a() # This should not segfault a() # This should not segfault
except RuntimeError: except RuntimeError:
pass pass
else: else:
raise TestFailed, "how could this not have overflowed the stack?" self.fail("Failed to raise RuntimeError")
# Tests for exceptions raised in instance_getattr2(). def testForExceptionsRaisedInInstanceGetattr2(self):
# Tests for exceptions raised in instance_getattr2().
def booh(self): def booh(self):
raise AttributeError, "booh" raise AttributeError("booh")
class A: class A:
a = property(booh) a = property(booh)
try: try:
A().a # Raised AttributeError: A instance has no attribute 'a' A().a # Raised AttributeError: A instance has no attribute 'a'
except AttributeError, x: except AttributeError, x:
if str(x) != "booh": if str(x) != "booh":
print "attribute error for A().a got masked:", str(x) self.fail("attribute error for A().a got masked: %s" % x)
class E: class E:
__eq__ = property(booh) __eq__ = property(booh)
E() == E() # In debug mode, caused a C-level assert() to fail E() == E() # In debug mode, caused a C-level assert() to fail
class I: class I:
__init__ = property(booh) __init__ = property(booh)
try: try:
I() # In debug mode, printed XXX undetected error and raises AttributeError # In debug mode, printed XXX undetected error and
except AttributeError, x: # raises AttributeError
I()
except AttributeError, x:
pass pass
else: else:
print "attribute error for I.__init__ got masked" self.fail("attribute error for I.__init__ got masked")
# Test comparison and hash of methods def testHashComparisonOfMethods(self):
class A: # Test comparison and hash of methods
class A:
def __init__(self, x): def __init__(self, x):
self.x = x self.x = x
def f(self): def f(self):
...@@ -390,23 +595,29 @@ class A: ...@@ -390,23 +595,29 @@ class A:
return self.x == other.x return self.x == other.x
def __hash__(self): def __hash__(self):
return self.x return self.x
class B(A): class B(A):
pass pass
a1 = A(1) a1 = A(1)
a2 = A(2) a2 = A(2)
assert a1.f == a1.f self.assertEquals(a1.f, a1.f)
assert a1.f != a2.f self.assertNotEquals(a1.f, a2.f)
assert a1.f != a1.g self.assertNotEquals(a1.f, a1.g)
assert a1.f == A(1).f self.assertEquals(a1.f, A(1).f)
assert hash(a1.f) == hash(a1.f) self.assertEquals(hash(a1.f), hash(a1.f))
assert hash(a1.f) == hash(A(1).f) self.assertEquals(hash(a1.f), hash(A(1).f))
assert A.f != a1.f self.assertNotEquals(A.f, a1.f)
assert A.f != A.g self.assertNotEquals(A.f, A.g)
assert B.f == A.f self.assertEquals(B.f, A.f)
assert hash(B.f) == hash(A.f) self.assertEquals(hash(B.f), hash(A.f))
# the following triggers a SystemError in 2.4 # the following triggers a SystemError in 2.4
a = A(hash(A.f.im_func)^(-1)) a = A(hash(A.f.im_func)^(-1))
hash(a.f) hash(a.f)
def test_main():
test_support.run_unittest(ClassTests)
if __name__=='__main__':
test_main()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment