mirror of
https://github.com/python/cpython.git
synced 2025-11-02 11:08:57 +00:00
Port test_class to unittest. Patch #1671298.
This commit is contained in:
parent
ff9b963387
commit
c325556505
2 changed files with 498 additions and 388 deletions
|
|
@ -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',)
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
"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 = [
|
||||||
# "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:
|
||||||
|
|
||||||
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
|
|
||||||
1 >> testme
|
|
||||||
|
|
||||||
testme << 1
|
|
||||||
1 << testme
|
|
||||||
|
|
||||||
testme & 1
|
|
||||||
1 & testme
|
|
||||||
|
|
||||||
testme | 1
|
|
||||||
1 | testme
|
|
||||||
|
|
||||||
testme ^ 1
|
|
||||||
1 ^ testme
|
|
||||||
|
|
||||||
|
|
||||||
# List/dict operations
|
callLst[:] = []
|
||||||
|
divmod(testme,1)
|
||||||
|
self.assertCallStack([("__coerce__", (testme, 1)), ("__divmod__", (testme, 1))])
|
||||||
|
|
||||||
class Empty: pass
|
callLst[:] = []
|
||||||
|
divmod(1, testme)
|
||||||
|
self.assertCallStack([("__coerce__", (testme, 1)), ("__rdivmod__", (testme, 1))])
|
||||||
|
|
||||||
try:
|
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()
|
1 in Empty()
|
||||||
print 'failed, should have raised TypeError'
|
self.fail('failed, should have raised TypeError')
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
1 in testme
|
callLst[:] = []
|
||||||
|
1 in testme
|
||||||
|
self.assertCallStack([('__contains__', (testme, 1))])
|
||||||
|
|
||||||
testme[1]
|
callLst[:] = []
|
||||||
testme[1] = 1
|
testme[1]
|
||||||
del testme[1]
|
self.assertCallStack([('__getitem__', (testme, 1))])
|
||||||
|
|
||||||
testme[:42]
|
callLst[:] = []
|
||||||
testme[:42] = "The Answer"
|
testme[1] = 1
|
||||||
del testme[:42]
|
self.assertCallStack([('__setitem__', (testme, 1, 1))])
|
||||||
|
|
||||||
testme[2:1024:10]
|
callLst[:] = []
|
||||||
testme[2:1024:10] = "A lot"
|
del testme[1]
|
||||||
del testme[2:1024:10]
|
self.assertCallStack([('__delitem__', (testme, 1))])
|
||||||
|
|
||||||
testme[:42, ..., :24:, 24, 100]
|
callLst[:] = []
|
||||||
testme[:42, ..., :24:, 24, 100] = "Strange"
|
|
||||||
del testme[:42, ..., :24:, 24, 100]
|
|
||||||
|
|
||||||
|
|
||||||
# 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]
|
||||||
|
self.assertCallStack([('__getslice__', (testme, 0, 42))])
|
||||||
|
|
||||||
|
callLst[:] = []
|
||||||
testme[:42] = "The Answer"
|
testme[:42] = "The Answer"
|
||||||
|
self.assertCallStack([('__setslice__', (testme, 0, 42, "The Answer"))])
|
||||||
|
|
||||||
|
callLst[:] = []
|
||||||
del testme[:42]
|
del testme[:42]
|
||||||
else:
|
self.assertCallStack([('__delslice__', (testme, 0, 42))])
|
||||||
# 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[:] = []
|
||||||
|
testme[2:1024:10]
|
||||||
|
self.assertCallStack([('__getitem__', (testme, slice(2, 1024, 10)))])
|
||||||
|
|
||||||
-testme
|
callLst[:] = []
|
||||||
+testme
|
testme[2:1024:10] = "A lot"
|
||||||
abs(testme)
|
self.assertCallStack([('__setitem__', (testme, slice(2, 1024, 10),
|
||||||
int(testme)
|
"A lot"))])
|
||||||
long(testme)
|
callLst[:] = []
|
||||||
float(testme)
|
del testme[2:1024:10]
|
||||||
oct(testme)
|
self.assertCallStack([('__delitem__', (testme, slice(2, 1024, 10)))])
|
||||||
hex(testme)
|
|
||||||
|
|
||||||
# And the rest...
|
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)))])
|
||||||
|
|
||||||
hash(testme)
|
# Now remove the slice hooks to see if converting normal slices to
|
||||||
repr(testme)
|
# slice object works.
|
||||||
str(testme)
|
|
||||||
|
|
||||||
testme == 1
|
getslice = AllTests.__getslice__
|
||||||
testme < 1
|
del AllTests.__getslice__
|
||||||
testme > 1
|
setslice = AllTests.__setslice__
|
||||||
testme <> 1
|
del AllTests.__setslice__
|
||||||
testme != 1
|
delslice = AllTests.__delslice__
|
||||||
1 == testme
|
del AllTests.__delslice__
|
||||||
1 < testme
|
|
||||||
1 > testme
|
|
||||||
1 <> testme
|
|
||||||
1 != testme
|
|
||||||
|
|
||||||
# This test has to be last (duh.)
|
# 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)))])
|
||||||
|
|
||||||
del testme
|
callLst[:] = []
|
||||||
if sys.platform[:4] == 'java':
|
testme[:42] = "The Answer"
|
||||||
import java
|
self.assertCallStack([('__setitem__', (testme, slice(0, 42, None),
|
||||||
java.lang.System.gc()
|
"The Answer"))])
|
||||||
|
callLst[:] = []
|
||||||
|
del testme[:42]
|
||||||
|
self.assertCallStack([('__delitem__', (testme, slice(0, 42, None)))])
|
||||||
|
|
||||||
# Interfering tests
|
# Restore the slice methods, or the tests will fail with regrtest -R.
|
||||||
|
AllTests.__getslice__ = getslice
|
||||||
|
AllTests.__setslice__ = setslice
|
||||||
|
AllTests.__delslice__ = delslice
|
||||||
|
|
||||||
class ExtraTests:
|
|
||||||
|
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):
|
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()
|
testme = ExtraTests()
|
||||||
testme.spam
|
|
||||||
testme.eggs = "spam, spam, spam and ham"
|
|
||||||
del testme.cardinal
|
|
||||||
|
|
||||||
|
callLst[:] = []
|
||||||
|
testme.spam
|
||||||
|
self.assertCallStack([('__getattr__', (testme, "spam"))])
|
||||||
|
|
||||||
# return values of some method are type-checked
|
callLst[:] = []
|
||||||
class BadTypeClass:
|
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):
|
def __int__(self):
|
||||||
return None
|
return None
|
||||||
__float__ = __int__
|
__float__ = __int__
|
||||||
|
|
@ -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:
|
|
||||||
exec stmt
|
|
||||||
except exception:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
raise TestFailed, "%s should raise %s" % (stmt, exception)
|
|
||||||
|
|
||||||
check_exc("int(BadTypeClass())", TypeError)
|
def testMixIntsAndLongs(self):
|
||||||
check_exc("float(BadTypeClass())", TypeError)
|
# mixing up ints and longs is okay
|
||||||
check_exc("long(BadTypeClass())", TypeError)
|
class IntLongMixClass:
|
||||||
check_exc("str(BadTypeClass())", TypeError)
|
@trackCall
|
||||||
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")
|
||||||
|
|
||||||
|
def testForExceptionsRaisedInInstanceGetattr2(self):
|
||||||
|
# Tests for exceptions raised in instance_getattr2().
|
||||||
|
|
||||||
# Tests for exceptions raised in instance_getattr2().
|
def booh(self):
|
||||||
|
raise AttributeError("booh")
|
||||||
|
|
||||||
def booh(self):
|
class A:
|
||||||
raise AttributeError, "booh"
|
|
||||||
|
|
||||||
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")
|
||||||
|
|
||||||
|
def testHashComparisonOfMethods(self):
|
||||||
# Test comparison and hash of methods
|
# Test comparison and hash of methods
|
||||||
class A:
|
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:
|
||||||
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()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue