"Test the functionality of Python classes implementing operators." from test.test_support import TestFailed testmeths = [ # Binary operations "add", "radd", "sub", "rsub", "mul", "rmul", "truediv", "rtruediv", "mod", "rmod", "divmod", "rdivmod", "pow", "rpow", "rshift", "rrshift", "lshift", "rlshift", "and", "rand", "or", "ror", "xor", "rxor", # List/dict operations "contains", "getitem", "getslice", "setitem", "setslice", "delitem", "delslice", # Unary operations "neg", "pos", "abs", # generic operations "init", ] # These need to return something other than None # "hash", # "str", # "repr", # "int", # "long", # "float", # "oct", # "hex", # These are separate because they can influence the test of other methods. # "getattr", # "setattr", # "delattr", class AllTests: def __hash__(self, *args): print("__hash__:", args) return hash(id(self)) def __str__(self, *args): print("__str__:", args) return "AllTests" def __repr__(self, *args): print("__repr__:", args) return "AllTests" def __int__(self, *args): print("__int__:", args) return 1 def __index__(self, *args): print("__index__:", args) return 1 def __float__(self, *args): print("__float__:", args) return 1.0 def __cmp__(self, *args): print("__cmp__:", args) return 0 def __eq__(self, *args): print("__eq__:", args) return True def __ne__(self, *args): print("__ne__:", args) return False def __lt__(self, *args): print("__lt__:", args) return False def __le__(self, *args): print("__le__:", args) return True def __gt__(self, *args): print("__gt__:", args) return False def __ge__(self, *args): print("__ge__:", args) return True def __del__(self, *args): print("__del__:", args) # Synthesize AllTests methods from the names in testmeths. method_template = """\ def __%(method)s__(self, *args): print("__%(method)s__:", args) """ d = {} for method in testmeths: exec(method_template % locals(), d) for k in d: setattr(AllTests, k, d[k]) del d, k 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 testme / 1 1 / testme 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] # 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) int(testme) float(testme) oct(testme) # And the rest... hash(testme) repr(testme) str(testme) testme == 1 testme < 1 testme > 1 testme != 1 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__ __str__ = __int__ __repr__ = __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("str(BadTypeClass())", TypeError) check_exc("repr(BadTypeClass())", TypeError) check_exc("oct(BadTypeClass())", TypeError) check_exc("hex(BadTypeClass())", TypeError) # 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 as 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 as 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 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)