mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	 2c9590f625
			
		
	
	
		2c9590f625
		
	
	
	
	
		
			
			Since properties are supported here, is possible that instance_getattr2() raises an exception. Fix all code that made this assumption. Backport candidate.
		
			
				
	
	
		
			317 lines
		
	
	
	
		
			5.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			317 lines
		
	
	
	
		
			5.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| "Test the functionality of Python classes implementing operators."
 | |
| 
 | |
| from test.test_support import TestFailed
 | |
| 
 | |
| testmeths = [
 | |
| 
 | |
| # Binary operations
 | |
|     "add",
 | |
|     "radd",
 | |
|     "sub",
 | |
|     "rsub",
 | |
|     "mul",
 | |
|     "rmul",
 | |
|     "div",
 | |
|     "rdiv",
 | |
|     "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",
 | |
|     "int",
 | |
|     "long",
 | |
|     "float",
 | |
|     "oct",
 | |
|     "hex",
 | |
| 
 | |
| # generic operations
 | |
|     "init",
 | |
|     ]
 | |
| 
 | |
| # These need to return something other than None
 | |
| #    "coerce",
 | |
| #    "hash",
 | |
| #    "str",
 | |
| #    "repr",
 | |
| 
 | |
| # These are separate because they can influence the test of other methods.
 | |
| #    "getattr",
 | |
| #    "setattr",
 | |
| #    "delattr",
 | |
| 
 | |
| class AllTests:
 | |
|     def __coerce__(self, *args):
 | |
|         print "__coerce__:", args
 | |
|         return (self,) + args
 | |
| 
 | |
|     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 __cmp__(self, *args):
 | |
|         print "__cmp__:", args
 | |
|         return 0
 | |
| 
 | |
|     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
 | |
| """
 | |
| 
 | |
| for method in testmeths:
 | |
|     exec method_template % locals() in AllTests.__dict__
 | |
| 
 | |
| 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
 | |
| 
 | |
| 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)
 | |
| if sys.platform[:4] != 'java':
 | |
|     int(testme)
 | |
|     long(testme)
 | |
|     float(testme)
 | |
|     oct(testme)
 | |
|     hex(testme)
 | |
| else:
 | |
|     # Jython enforced that the these methods return
 | |
|     # a value of the expected type.
 | |
|     print "__int__: ()"
 | |
|     print "__long__: ()"
 | |
|     print "__float__: ()"
 | |
|     print "__oct__: ()"
 | |
|     print "__hex__: ()"
 | |
| 
 | |
| 
 | |
| # 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
 | |
| 
 | |
| 
 | |
| # 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
 | |
| 
 | |
| try: hash(C1())
 | |
| except TypeError: pass
 | |
| else: raise TestFailed, "hash(C1()) should raise an exception"
 | |
| 
 | |
| class C2:
 | |
|     def __eq__(self, other): return 1
 | |
| 
 | |
| try: hash(C2())
 | |
| except TypeError: pass
 | |
| else: raise TestFailed, "hash(C2()) should raise an exception"
 | |
| 
 | |
| 
 | |
| # 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) is not "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"
 |