Apply SF patch #101029: call __getitem__ with a proper slice object if there

is no __getslice__ available. Also does the same for C extension types.
Includes rudimentary documentation (it could use a cross reference to the
section on slice objects, I couldn't figure out how to do that) and a test
suite for all Python __hooks__ I could think of, including the new
behaviour.
This commit is contained in:
Thomas Wouters 2000-08-17 22:37:32 +00:00
parent 68add2e938
commit 1d75a79c00
5 changed files with 435 additions and 18 deletions

101
Lib/test/output/test_class Normal file
View file

@ -0,0 +1,101 @@
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',)

219
Lib/test/test_class.py Normal file
View file

@ -0,0 +1,219 @@
"Test the functionality of Python classes implementing operators."
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",
"del",
]
# 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 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
for method in testmeths:
exec("""def __%(method)s__(self, *args):
print "__%(method)s__:", args
"""%locals(), AllTests.__dict__);
# 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
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__
testme[:42]
testme[:42] = "The Answer"
del testme[:42]
# Unary operations
-testme
+testme
abs(testme)
int(testme)
long(testme)
float(testme)
oct(testme)
hex(testme)
# 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
# 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