mirror of
https://github.com/AdaCore/cpython.git
synced 2026-02-12 12:57:15 -08:00
* Fix some docstrings and one Print -> print.
* Fix test_{class,code,descrtut,dis,extcall,parser,popen,pkg,subprocess,syntax,traceback}.
These were the ones that generated code with a print statement.
In most remaining failing tests there's an issue with the soft space.
400 lines
7.0 KiB
Python
400 lines
7.0 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",
|
|
"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 __float__(self, *args):
|
|
print("__float__:", args)
|
|
return 1.0
|
|
|
|
def __oct__(self, *args):
|
|
print("__oct__:", args)
|
|
return '01'
|
|
|
|
def __hex__(self, *args):
|
|
print("__hex__:", args)
|
|
return '0x1'
|
|
|
|
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)
|
|
hex(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__
|
|
__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("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)
|