Remove the simple slicing API. All slicing is now done with slice objects.
This commit is contained in:
parent
582b586617
commit
d2cf20eea2
|
@ -252,9 +252,9 @@ typedef struct {
|
|||
binaryfunc sq_concat;
|
||||
ssizeargfunc sq_repeat;
|
||||
ssizeargfunc sq_item;
|
||||
ssizessizeargfunc sq_slice;
|
||||
void *was_sq_slice;
|
||||
ssizeobjargproc sq_ass_item;
|
||||
ssizessizeobjargproc sq_ass_slice;
|
||||
void *was_sq_ass_slice;
|
||||
objobjproc sq_contains;
|
||||
|
||||
binaryfunc sq_inplace_concat;
|
||||
|
|
|
@ -36,15 +36,6 @@ extern "C" {
|
|||
#define INPLACE_FLOOR_DIVIDE 28
|
||||
#define INPLACE_TRUE_DIVIDE 29
|
||||
|
||||
#define SLICE 30
|
||||
/* Also uses 31-33 */
|
||||
|
||||
#define STORE_SLICE 40
|
||||
/* Also uses 41-43 */
|
||||
|
||||
#define DELETE_SLICE 50
|
||||
/* Also uses 51-53 */
|
||||
|
||||
#define INPLACE_ADD 55
|
||||
#define INPLACE_SUBTRACT 56
|
||||
#define INPLACE_MULTIPLY 57
|
||||
|
|
|
@ -28,20 +28,6 @@ class UserList:
|
|||
def __getitem__(self, i): return self.data[i]
|
||||
def __setitem__(self, i, item): self.data[i] = item
|
||||
def __delitem__(self, i): del self.data[i]
|
||||
def __getslice__(self, i, j):
|
||||
i = max(i, 0); j = max(j, 0)
|
||||
return self.__class__(self.data[i:j])
|
||||
def __setslice__(self, i, j, other):
|
||||
i = max(i, 0); j = max(j, 0)
|
||||
if isinstance(other, UserList):
|
||||
self.data[i:j] = other.data
|
||||
elif isinstance(other, type(self.data)):
|
||||
self.data[i:j] = other
|
||||
else:
|
||||
self.data[i:j] = list(other)
|
||||
def __delslice__(self, i, j):
|
||||
i = max(i, 0); j = max(j, 0)
|
||||
del self.data[i:j]
|
||||
def __add__(self, other):
|
||||
if isinstance(other, UserList):
|
||||
return self.__class__(self.data + other.data)
|
||||
|
|
|
@ -63,10 +63,6 @@ class UserString:
|
|||
|
||||
def __len__(self): return len(self.data)
|
||||
def __getitem__(self, index): return self.__class__(self.data[index])
|
||||
def __getslice__(self, start, end):
|
||||
start = max(start, 0); end = max(end, 0)
|
||||
return self.__class__(self.data[start:end])
|
||||
|
||||
def __add__(self, other):
|
||||
if isinstance(other, UserString):
|
||||
return self.__class__(self.data + other.data)
|
||||
|
@ -220,17 +216,6 @@ class MutableString(UserString):
|
|||
index += len(self.data)
|
||||
if index < 0 or index >= len(self.data): raise IndexError
|
||||
self.data = self.data[:index] + self.data[index+1:]
|
||||
def __setslice__(self, start, end, sub):
|
||||
start = max(start, 0); end = max(end, 0)
|
||||
if isinstance(sub, UserString):
|
||||
self.data = self.data[:start]+sub.data+self.data[end:]
|
||||
elif isinstance(sub, basestring):
|
||||
self.data = self.data[:start]+sub+self.data[end:]
|
||||
else:
|
||||
self.data = self.data[:start]+str(sub)+self.data[end:]
|
||||
def __delslice__(self, start, end):
|
||||
start = max(start, 0); end = max(end, 0)
|
||||
self.data = self.data[:start] + self.data[end:]
|
||||
def immutable(self):
|
||||
return UserString(self.data)
|
||||
def __iadd__(self, other):
|
||||
|
|
|
@ -70,20 +70,6 @@ def_op('BINARY_FLOOR_DIVIDE', 26)
|
|||
def_op('BINARY_TRUE_DIVIDE', 27)
|
||||
def_op('INPLACE_FLOOR_DIVIDE', 28)
|
||||
def_op('INPLACE_TRUE_DIVIDE', 29)
|
||||
def_op('SLICE+0', 30)
|
||||
def_op('SLICE+1', 31)
|
||||
def_op('SLICE+2', 32)
|
||||
def_op('SLICE+3', 33)
|
||||
|
||||
def_op('STORE_SLICE+0', 40)
|
||||
def_op('STORE_SLICE+1', 41)
|
||||
def_op('STORE_SLICE+2', 42)
|
||||
def_op('STORE_SLICE+3', 43)
|
||||
|
||||
def_op('DELETE_SLICE+0', 50)
|
||||
def_op('DELETE_SLICE+1', 51)
|
||||
def_op('DELETE_SLICE+2', 52)
|
||||
def_op('DELETE_SLICE+3', 53)
|
||||
|
||||
def_op('INPLACE_ADD', 55)
|
||||
def_op('INPLACE_SUBTRACT', 56)
|
||||
|
|
|
@ -139,8 +139,6 @@ class SubPattern:
|
|||
return self.data[index]
|
||||
def __setitem__(self, index, code):
|
||||
self.data[index] = code
|
||||
def __getslice__(self, start, stop):
|
||||
return SubPattern(self.pattern, self.data[start:stop])
|
||||
def insert(self, index, code):
|
||||
self.data.insert(index, code)
|
||||
def append(self, code):
|
||||
|
|
|
@ -178,10 +178,8 @@ class CommonTest(seq_tests.CommonTest):
|
|||
a[:] = tuple(range(10))
|
||||
self.assertEqual(a, self.type2test(range(10)))
|
||||
|
||||
self.assertRaises(TypeError, a.__setslice__, 0, 1, 5)
|
||||
self.assertRaises(TypeError, a.__setitem__, slice(0, 1, 5))
|
||||
|
||||
self.assertRaises(TypeError, a.__setslice__)
|
||||
self.assertRaises(TypeError, a.__setitem__)
|
||||
|
||||
def test_delslice(self):
|
||||
|
|
|
@ -196,8 +196,6 @@ class CommonTest(unittest.TestCase):
|
|||
self.assertEqual(a[ -pow(2,128): 3 ], self.type2test([0,1,2]))
|
||||
self.assertEqual(a[ 3: pow(2,145) ], self.type2test([3,4]))
|
||||
|
||||
self.assertRaises(TypeError, u.__getslice__)
|
||||
|
||||
def test_contains(self):
|
||||
u = self.type2test([0, 1, 2])
|
||||
for i in u:
|
||||
|
|
|
@ -939,17 +939,17 @@ class MixinStrUnicodeUserStringTest:
|
|||
self.checkraises(TypeError, 'abc', '__getitem__', 'def')
|
||||
|
||||
def test_slice(self):
|
||||
self.checkequal('abc', 'abc', '__getslice__', 0, 1000)
|
||||
self.checkequal('abc', 'abc', '__getslice__', 0, 3)
|
||||
self.checkequal('ab', 'abc', '__getslice__', 0, 2)
|
||||
self.checkequal('bc', 'abc', '__getslice__', 1, 3)
|
||||
self.checkequal('b', 'abc', '__getslice__', 1, 2)
|
||||
self.checkequal('', 'abc', '__getslice__', 2, 2)
|
||||
self.checkequal('', 'abc', '__getslice__', 1000, 1000)
|
||||
self.checkequal('', 'abc', '__getslice__', 2000, 1000)
|
||||
self.checkequal('', 'abc', '__getslice__', 2, 1)
|
||||
self.checkequal('abc', 'abc', '__getitem__', slice(0, 1000))
|
||||
self.checkequal('abc', 'abc', '__getitem__', slice(0, 3))
|
||||
self.checkequal('ab', 'abc', '__getitem__', slice(0, 2))
|
||||
self.checkequal('bc', 'abc', '__getitem__', slice(1, 3))
|
||||
self.checkequal('b', 'abc', '__getitem__', slice(1, 2))
|
||||
self.checkequal('', 'abc', '__getitem__', slice(2, 2))
|
||||
self.checkequal('', 'abc', '__getitem__', slice(1000, 1000))
|
||||
self.checkequal('', 'abc', '__getitem__', slice(2000, 1000))
|
||||
self.checkequal('', 'abc', '__getitem__', slice(2, 1))
|
||||
|
||||
self.checkraises(TypeError, 'abc', '__getslice__', 'def')
|
||||
self.checkraises(TypeError, 'abc', '__getitem__', 'def')
|
||||
|
||||
def test_extended_getslice(self):
|
||||
# Test extended slicing by comparing with list slicing.
|
||||
|
|
|
@ -562,12 +562,10 @@ class BaseTest(unittest.TestCase):
|
|||
)
|
||||
|
||||
a = array.array(self.typecode, self.example)
|
||||
self.assertRaises(TypeError, a.__setslice__, 0, 0, None)
|
||||
self.assertRaises(TypeError, a.__setitem__, slice(0, 0), None)
|
||||
self.assertRaises(TypeError, a.__setitem__, slice(0, 1), None)
|
||||
|
||||
b = array.array(self.badtypecode())
|
||||
self.assertRaises(TypeError, a.__setslice__, 0, 0, b)
|
||||
self.assertRaises(TypeError, a.__setitem__, slice(0, 0), b)
|
||||
self.assertRaises(TypeError, a.__setitem__, slice(0, 1), b)
|
||||
|
||||
|
|
|
@ -36,11 +36,8 @@ testmeths = [
|
|||
# List/dict operations
|
||||
"contains",
|
||||
"getitem",
|
||||
"getslice",
|
||||
"setitem",
|
||||
"setslice",
|
||||
"delitem",
|
||||
"delslice",
|
||||
|
||||
# Unary operations
|
||||
"neg",
|
||||
|
@ -288,15 +285,16 @@ class ClassTests(unittest.TestCase):
|
|||
|
||||
callLst[:] = []
|
||||
testme[:42]
|
||||
self.assertCallStack([('__getslice__', (testme, 0, 42))])
|
||||
self.assertCallStack([('__getitem__', (testme, slice(None, 42)))])
|
||||
|
||||
callLst[:] = []
|
||||
testme[:42] = "The Answer"
|
||||
self.assertCallStack([('__setslice__', (testme, 0, 42, "The Answer"))])
|
||||
self.assertCallStack([('__setitem__', (testme, slice(None, 42),
|
||||
"The Answer"))])
|
||||
|
||||
callLst[:] = []
|
||||
del testme[:42]
|
||||
self.assertCallStack([('__delslice__', (testme, 0, 42))])
|
||||
self.assertCallStack([('__delitem__', (testme, slice(None, 42)))])
|
||||
|
||||
callLst[:] = []
|
||||
testme[2:1024:10]
|
||||
|
@ -329,37 +327,6 @@ class ClassTests(unittest.TestCase):
|
|||
slice(None, 24, None),
|
||||
24, 100)))])
|
||||
|
||||
# Now remove the slice hooks to see if converting normal slices to
|
||||
# slice object works.
|
||||
|
||||
getslice = AllTests.__getslice__
|
||||
del AllTests.__getslice__
|
||||
setslice = AllTests.__setslice__
|
||||
del AllTests.__setslice__
|
||||
delslice = AllTests.__delslice__
|
||||
del AllTests.__delslice__
|
||||
|
||||
# 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[0:42]
|
||||
self.assertCallStack([('__getitem__', (testme, slice(0, 42, None)))])
|
||||
|
||||
callLst[:] = []
|
||||
testme[:42] = "The Answer"
|
||||
self.assertCallStack([('__setitem__', (testme, slice(None, 42, None),
|
||||
"The Answer"))])
|
||||
callLst[:] = []
|
||||
del testme[0:42]
|
||||
self.assertCallStack([('__delitem__', (testme, slice(0, 42, None)))])
|
||||
|
||||
# Restore the slice methods, or the tests will fail with regrtest -R.
|
||||
AllTests.__getslice__ = getslice
|
||||
AllTests.__setslice__ = setslice
|
||||
AllTests.__delslice__ = delslice
|
||||
|
||||
|
||||
def testUnaryOps(self):
|
||||
testme = AllTests()
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ def testbinop(a, b, res, expr="a+b", meth="__add__"):
|
|||
bm = getattr(a, meth)
|
||||
vereq(bm(b), res)
|
||||
|
||||
def testternop(a, b, c, res, expr="a[b:c]", meth="__getslice__"):
|
||||
def testsliceop(a, b, c, res, expr="a[b:c]", meth="__getitem__"):
|
||||
if verbose: print("checking", expr)
|
||||
dict = {'a': a, 'b': b, 'c': c}
|
||||
vereq(eval(expr, dict), res)
|
||||
|
@ -50,9 +50,9 @@ def testternop(a, b, c, res, expr="a[b:c]", meth="__getslice__"):
|
|||
while meth not in t.__dict__:
|
||||
t = t.__bases__[0]
|
||||
vereq(m, t.__dict__[meth])
|
||||
vereq(m(a, b, c), res)
|
||||
vereq(m(a, slice(b, c)), res)
|
||||
bm = getattr(a, meth)
|
||||
vereq(bm(b, c), res)
|
||||
vereq(bm(slice(b, c)), res)
|
||||
|
||||
def testsetop(a, b, res, stmt="a+=b", meth="__iadd__"):
|
||||
if verbose: print("checking", stmt)
|
||||
|
@ -90,7 +90,7 @@ def testset2op(a, b, c, res, stmt="a[b]=c", meth="__setitem__"):
|
|||
bm(b, c)
|
||||
vereq(dict['a'], res)
|
||||
|
||||
def testset3op(a, b, c, d, res, stmt="a[b:c]=d", meth="__setslice__"):
|
||||
def testsetsliceop(a, b, c, d, res, stmt="a[b:c]=d", meth="__setitem__"):
|
||||
if verbose: print("checking", stmt)
|
||||
dict = {'a': deepcopy(a), 'b': b, 'c': c, 'd': d}
|
||||
exec(stmt, dict)
|
||||
|
@ -101,11 +101,11 @@ def testset3op(a, b, c, d, res, stmt="a[b:c]=d", meth="__setslice__"):
|
|||
m = getattr(t, meth)
|
||||
vereq(m, t.__dict__[meth])
|
||||
dict['a'] = deepcopy(a)
|
||||
m(dict['a'], b, c, d)
|
||||
m(dict['a'], slice(b, c), d)
|
||||
vereq(dict['a'], res)
|
||||
dict['a'] = deepcopy(a)
|
||||
bm = getattr(dict['a'], meth)
|
||||
bm(b, c, d)
|
||||
bm(slice(b, c), d)
|
||||
vereq(dict['a'], res)
|
||||
|
||||
def class_docstrings():
|
||||
|
@ -142,14 +142,15 @@ def lists():
|
|||
testbinop([1,2,3], 2, 1, "b in a", "__contains__")
|
||||
testbinop([1,2,3], 4, 0, "b in a", "__contains__")
|
||||
testbinop([1,2,3], 1, 2, "a[b]", "__getitem__")
|
||||
testternop([1,2,3], 0, 2, [1,2], "a[b:c]", "__getslice__")
|
||||
testsliceop([1,2,3], 0, 2, [1,2], "a[b:c]", "__getitem__")
|
||||
testsetop([1], [2], [1,2], "a+=b", "__iadd__")
|
||||
testsetop([1,2], 3, [1,2,1,2,1,2], "a*=b", "__imul__")
|
||||
testunop([1,2,3], 3, "len(a)", "__len__")
|
||||
testbinop([1,2], 3, [1,2,1,2,1,2], "a*b", "__mul__")
|
||||
testbinop([1,2], 3, [1,2,1,2,1,2], "b*a", "__rmul__")
|
||||
testset2op([1,2], 1, 3, [1,3], "a[b]=c", "__setitem__")
|
||||
testset3op([1,2,3,4], 1, 3, [5,6], [1,5,6,4], "a[b:c]=d", "__setslice__")
|
||||
testsetsliceop([1,2,3,4], 1, 3, [5,6], [1,5,6,4], "a[b:c]=d",
|
||||
"__setitem__")
|
||||
|
||||
def dicts():
|
||||
if verbose: print("Testing dict operations...")
|
||||
|
@ -485,8 +486,8 @@ def spamlists():
|
|||
testbinop(spamlist([1,2,3]), 2, 1, "b in a", "__contains__")
|
||||
testbinop(spamlist([1,2,3]), 4, 0, "b in a", "__contains__")
|
||||
testbinop(spamlist([1,2,3]), 1, 2, "a[b]", "__getitem__")
|
||||
testternop(spamlist([1,2,3]), 0, 2, spamlist([1,2]),
|
||||
"a[b:c]", "__getslice__")
|
||||
testsliceop(spamlist([1,2,3]), 0, 2, spamlist([1,2]),
|
||||
"a[b:c]", "__getitem__")
|
||||
testsetop(spamlist([1]), spamlist([2]), spamlist([1,2]),
|
||||
"a+=b", "__iadd__")
|
||||
testsetop(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "a*=b", "__imul__")
|
||||
|
@ -494,8 +495,8 @@ def spamlists():
|
|||
testbinop(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "a*b", "__mul__")
|
||||
testbinop(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "b*a", "__rmul__")
|
||||
testset2op(spamlist([1,2]), 1, 3, spamlist([1,3]), "a[b]=c", "__setitem__")
|
||||
testset3op(spamlist([1,2,3,4]), 1, 3, spamlist([5,6]),
|
||||
spamlist([1,5,6,4]), "a[b:c]=d", "__setslice__")
|
||||
testsetsliceop(spamlist([1,2,3,4]), 1, 3, spamlist([5,6]),
|
||||
spamlist([1,5,6,4]), "a[b:c]=d", "__setitem__")
|
||||
# Test subclassing
|
||||
class C(spam.spamlist):
|
||||
def foo(self): return 1
|
||||
|
@ -609,9 +610,9 @@ def pylists():
|
|||
if verbose: print("Testing Python subclass of list...")
|
||||
class C(list):
|
||||
def __getitem__(self, i):
|
||||
if isinstance(i, slice):
|
||||
return (i.start, i.stop)
|
||||
return list.__getitem__(self, i) + 100
|
||||
def __getslice__(self, i, j):
|
||||
return (i, j)
|
||||
a = C()
|
||||
a.extend([0,1,2])
|
||||
vereq(a[0], 100)
|
||||
|
@ -1651,13 +1652,6 @@ def overloading():
|
|||
def __delitem__(self, key):
|
||||
self.delitem = key
|
||||
|
||||
def __getslice__(self, i, j):
|
||||
return ("getslice", i, j)
|
||||
def __setslice__(self, i, j, value):
|
||||
self.setslice = (i, j, value)
|
||||
def __delslice__(self, i, j):
|
||||
self.delslice = (i, j)
|
||||
|
||||
a = C()
|
||||
vereq(a.foo, ("getattr", "foo"))
|
||||
a.foo = 12
|
||||
|
@ -1671,11 +1665,11 @@ def overloading():
|
|||
del a[12]
|
||||
vereq(a.delitem, 12)
|
||||
|
||||
vereq(a[0:10], ("getslice", 0, 10))
|
||||
vereq(a[0:10], ("getitem", slice(0, 10)))
|
||||
a[0:10] = "foo"
|
||||
vereq(a.setslice, (0, 10, "foo"))
|
||||
vereq(a.setitem, (slice(0, 10), "foo"))
|
||||
del a[0:10]
|
||||
vereq(a.delslice, (0, 10))
|
||||
vereq(a.delitem, slice(0, 10))
|
||||
|
||||
def methods():
|
||||
if verbose: print("Testing methods...")
|
||||
|
@ -4116,7 +4110,7 @@ def test_assign_slice():
|
|||
# tp->tp_as_sequence->sq_ass_slice
|
||||
|
||||
class C(object):
|
||||
def __setslice__(self, start, stop, value):
|
||||
def __setitem__(self, idx, value):
|
||||
self.value = value
|
||||
|
||||
c = C()
|
||||
|
|
|
@ -170,14 +170,12 @@ You can get the information from the list type:
|
|||
'__contains__',
|
||||
'__delattr__',
|
||||
'__delitem__',
|
||||
'__delslice__',
|
||||
'__doc__',
|
||||
'__eq__',
|
||||
'__format__',
|
||||
'__ge__',
|
||||
'__getattribute__',
|
||||
'__getitem__',
|
||||
'__getslice__',
|
||||
'__gt__',
|
||||
'__hash__',
|
||||
'__iadd__',
|
||||
|
@ -197,7 +195,6 @@ You can get the information from the list type:
|
|||
'__rmul__',
|
||||
'__setattr__',
|
||||
'__setitem__',
|
||||
'__setslice__',
|
||||
'__str__',
|
||||
'append',
|
||||
'count',
|
||||
|
|
|
@ -177,26 +177,17 @@ class OverflowTestCase(unittest.TestCase):
|
|||
self.assertEqual(self.pos.__index__(), self.pos)
|
||||
self.assertEqual(self.neg.__index__(), self.neg)
|
||||
|
||||
def _getitem_helper(self, base):
|
||||
class GetItem(base):
|
||||
def test_getitem(self):
|
||||
class GetItem(object):
|
||||
def __len__(self):
|
||||
return maxint #cannot return long here
|
||||
def __getitem__(self, key):
|
||||
return key
|
||||
def __getslice__(self, i, j):
|
||||
return i, j
|
||||
x = GetItem()
|
||||
self.assertEqual(x[self.pos], self.pos)
|
||||
self.assertEqual(x[self.neg], self.neg)
|
||||
self.assertEqual(x[self.neg:self.pos], (maxint+minsize, maxsize))
|
||||
self.assertEqual(x[self.neg:self.pos:1].indices(maxsize), (0, maxsize, 1))
|
||||
|
||||
def test_getitem(self):
|
||||
self._getitem_helper(object)
|
||||
|
||||
def test_getitem_classic(self):
|
||||
class Empty: pass
|
||||
self._getitem_helper(Empty)
|
||||
self.assertEqual(x[self.neg:self.pos].indices(maxsize),
|
||||
(0, maxsize, 1))
|
||||
|
||||
def test_sequence_repeat(self):
|
||||
self.failUnlessRaises(OverflowError, lambda: "a" * self.pos)
|
||||
|
|
|
@ -283,17 +283,6 @@ class LongTest(unittest.TestCase):
|
|||
self.assert_(type(y) is int,
|
||||
"overflowing int conversion must return long not long subtype")
|
||||
|
||||
# long -> Py_ssize_t conversion
|
||||
class X(object):
|
||||
def __getslice__(self, i, j):
|
||||
return i, j
|
||||
|
||||
self.assertEqual(X()[-5:7], (-5, 7))
|
||||
# use the clamping effect to test the smallest and largest longs
|
||||
# that fit a Py_ssize_t
|
||||
slicemin, slicemax = X()[-2**100:2**100]
|
||||
self.assertEqual(X()[slicemin:slicemax], (slicemin, slicemax))
|
||||
|
||||
# ----------------------------------- tests of auto int->long conversion
|
||||
|
||||
def test_auto_overflow(self):
|
||||
|
|
|
@ -99,12 +99,12 @@ class SliceTest(unittest.TestCase):
|
|||
def test_setslice_without_getslice(self):
|
||||
tmp = []
|
||||
class X(object):
|
||||
def __setslice__(self, i, j, k):
|
||||
tmp.append((i, j, k))
|
||||
def __setitem__(self, i, k):
|
||||
tmp.append((i, k))
|
||||
|
||||
x = X()
|
||||
x[1:2] = 42
|
||||
self.assertEquals(tmp, [(1, 2, 42)])
|
||||
self.assertEquals(tmp, [(slice(1, 2), 42)])
|
||||
|
||||
def test_pickle(self):
|
||||
s = slice(10, 20, 3)
|
||||
|
|
|
@ -423,11 +423,7 @@ _1M = 1024*1024
|
|||
_1G = 1024 * _1M
|
||||
_2G = 2 * _1G
|
||||
|
||||
# Hack to get at the maximum value an internal index can take.
|
||||
class _Dummy:
|
||||
def __getslice__(self, i, j):
|
||||
return j
|
||||
MAX_Py_ssize_t = _Dummy()[:]
|
||||
MAX_Py_ssize_t = sys.maxsize
|
||||
|
||||
def set_memlimit(limit):
|
||||
import re
|
||||
|
|
|
@ -3701,52 +3701,6 @@ Array_item(PyObject *_self, Py_ssize_t index)
|
|||
index, size, self->b_ptr + offset);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Array_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh)
|
||||
{
|
||||
CDataObject *self = (CDataObject *)_self;
|
||||
StgDictObject *stgdict, *itemdict;
|
||||
PyObject *proto;
|
||||
PyListObject *np;
|
||||
Py_ssize_t i, len;
|
||||
|
||||
if (ilow < 0)
|
||||
ilow = 0;
|
||||
else if (ilow > self->b_length)
|
||||
ilow = self->b_length;
|
||||
if (ihigh < ilow)
|
||||
ihigh = ilow;
|
||||
else if (ihigh > self->b_length)
|
||||
ihigh = self->b_length;
|
||||
len = ihigh - ilow;
|
||||
|
||||
stgdict = PyObject_stgdict((PyObject *)self);
|
||||
assert(stgdict); /* Cannot be NULL for array object instances */
|
||||
proto = stgdict->proto;
|
||||
itemdict = PyType_stgdict(proto);
|
||||
assert(itemdict); /* proto is the item type of the array, a ctypes
|
||||
type, so this cannot be NULL */
|
||||
if (itemdict->getfunc == getentry("c")->getfunc) {
|
||||
char *ptr = (char *)self->b_ptr;
|
||||
return PyString_FromStringAndSize(ptr + ilow, len);
|
||||
#ifdef CTYPES_UNICODE
|
||||
} else if (itemdict->getfunc == getentry("u")->getfunc) {
|
||||
wchar_t *ptr = (wchar_t *)self->b_ptr;
|
||||
return PyUnicode_FromWideChar(ptr + ilow, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
np = (PyListObject *) PyList_New(len);
|
||||
if (np == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
PyObject *v = Array_item(_self, i+ilow);
|
||||
PyList_SET_ITEM(np, i, v);
|
||||
}
|
||||
return (PyObject *)np;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Array_subscript(PyObject *_self, PyObject *item)
|
||||
{
|
||||
|
@ -3989,9 +3943,9 @@ static PySequenceMethods Array_as_sequence = {
|
|||
0, /* sq_concat; */
|
||||
0, /* sq_repeat; */
|
||||
Array_item, /* sq_item; */
|
||||
Array_slice, /* sq_slice; */
|
||||
0, /* sq_slice; */
|
||||
Array_ass_item, /* sq_ass_item; */
|
||||
Array_ass_slice, /* sq_ass_slice; */
|
||||
0, /* sq_ass_slice; */
|
||||
0, /* sq_contains; */
|
||||
|
||||
0, /* sq_inplace_concat; */
|
||||
|
@ -4426,48 +4380,6 @@ Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
|
|||
return GenericCData_new(type, args, kw);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Pointer_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh)
|
||||
{
|
||||
CDataObject *self = (CDataObject *)_self;
|
||||
PyListObject *np;
|
||||
StgDictObject *stgdict, *itemdict;
|
||||
PyObject *proto;
|
||||
Py_ssize_t i, len;
|
||||
|
||||
if (ilow < 0)
|
||||
ilow = 0;
|
||||
if (ihigh < ilow)
|
||||
ihigh = ilow;
|
||||
len = ihigh - ilow;
|
||||
|
||||
stgdict = PyObject_stgdict((PyObject *)self);
|
||||
assert(stgdict); /* Cannot be NULL fr pointer instances */
|
||||
proto = stgdict->proto;
|
||||
assert(proto);
|
||||
itemdict = PyType_stgdict(proto);
|
||||
assert(itemdict);
|
||||
if (itemdict->getfunc == getentry("c")->getfunc) {
|
||||
char *ptr = *(char **)self->b_ptr;
|
||||
return PyString_FromStringAndSize(ptr + ilow, len);
|
||||
#ifdef CTYPES_UNICODE
|
||||
} else if (itemdict->getfunc == getentry("u")->getfunc) {
|
||||
wchar_t *ptr = *(wchar_t **)self->b_ptr;
|
||||
return PyUnicode_FromWideChar(ptr + ilow, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
np = (PyListObject *) PyList_New(len);
|
||||
if (np == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
PyObject *v = Pointer_item(_self, i+ilow);
|
||||
PyList_SET_ITEM(np, i, v);
|
||||
}
|
||||
return (PyObject *)np;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Pointer_subscript(PyObject *_self, PyObject *item)
|
||||
{
|
||||
|
@ -4606,7 +4518,7 @@ static PySequenceMethods Pointer_as_sequence = {
|
|||
0, /* binaryfunc sq_concat; */
|
||||
0, /* intargfunc sq_repeat; */
|
||||
Pointer_item, /* intargfunc sq_item; */
|
||||
Pointer_slice, /* intintargfunc sq_slice; */
|
||||
0, /* intintargfunc sq_slice; */
|
||||
Pointer_ass_item, /* intobjargproc sq_ass_item; */
|
||||
0, /* intintobjargproc sq_ass_slice; */
|
||||
0, /* objobjproc sq_contains; */
|
||||
|
|
|
@ -1835,9 +1835,9 @@ static PySequenceMethods array_as_sequence = {
|
|||
(binaryfunc)array_concat, /*sq_concat*/
|
||||
(ssizeargfunc)array_repeat, /*sq_repeat*/
|
||||
(ssizeargfunc)array_item, /*sq_item*/
|
||||
(ssizessizeargfunc)array_slice, /*sq_slice*/
|
||||
0, /*sq_slice*/
|
||||
(ssizeobjargproc)array_ass_item, /*sq_ass_item*/
|
||||
(ssizessizeobjargproc)array_ass_slice, /*sq_ass_slice*/
|
||||
0, /*sq_ass_slice*/
|
||||
(objobjproc)array_contains, /*sq_contains*/
|
||||
(binaryfunc)array_inplace_concat, /*sq_inplace_concat*/
|
||||
(ssizeargfunc)array_inplace_repeat /*sq_inplace_repeat*/
|
||||
|
|
|
@ -641,24 +641,6 @@ mmap_item(mmap_object *self, Py_ssize_t i)
|
|||
return PyBytes_FromStringAndSize(self->data + i, 1);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
mmap_slice(mmap_object *self, Py_ssize_t ilow, Py_ssize_t ihigh)
|
||||
{
|
||||
CHECK_VALID(NULL);
|
||||
if (ilow < 0)
|
||||
ilow = 0;
|
||||
else if ((size_t)ilow > self->size)
|
||||
ilow = self->size;
|
||||
if (ihigh < 0)
|
||||
ihigh = 0;
|
||||
if (ihigh < ilow)
|
||||
ihigh = ilow;
|
||||
else if ((size_t)ihigh > self->size)
|
||||
ihigh = self->size;
|
||||
|
||||
return PyBytes_FromStringAndSize(self->data + ilow, ihigh-ilow);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
mmap_subscript(mmap_object *self, PyObject *item)
|
||||
{
|
||||
|
@ -731,45 +713,6 @@ mmap_repeat(mmap_object *self, Py_ssize_t n)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
mmap_ass_slice(mmap_object *self, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
|
||||
{
|
||||
const char *buf;
|
||||
|
||||
CHECK_VALID(-1);
|
||||
if (ilow < 0)
|
||||
ilow = 0;
|
||||
else if ((size_t)ilow > self->size)
|
||||
ilow = self->size;
|
||||
if (ihigh < 0)
|
||||
ihigh = 0;
|
||||
if (ihigh < ilow)
|
||||
ihigh = ilow;
|
||||
else if ((size_t)ihigh > self->size)
|
||||
ihigh = self->size;
|
||||
|
||||
if (v == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"mmap object doesn't support slice deletion");
|
||||
return -1;
|
||||
}
|
||||
if (! (PyBytes_Check(v)) ) {
|
||||
PyErr_SetString(PyExc_IndexError,
|
||||
"mmap slice assignment must be bytes");
|
||||
return -1;
|
||||
}
|
||||
if (PyBytes_Size(v) != (ihigh - ilow)) {
|
||||
PyErr_SetString(PyExc_IndexError,
|
||||
"mmap slice assignment is wrong size");
|
||||
return -1;
|
||||
}
|
||||
if (!is_writeable(self))
|
||||
return -1;
|
||||
buf = PyBytes_AsString(v);
|
||||
memcpy(self->data + ilow, buf, ihigh-ilow);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mmap_ass_item(mmap_object *self, Py_ssize_t i, PyObject *v)
|
||||
{
|
||||
|
@ -892,9 +835,9 @@ static PySequenceMethods mmap_as_sequence = {
|
|||
(binaryfunc)mmap_concat, /*sq_concat*/
|
||||
(ssizeargfunc)mmap_repeat, /*sq_repeat*/
|
||||
(ssizeargfunc)mmap_item, /*sq_item*/
|
||||
(ssizessizeargfunc)mmap_slice, /*sq_slice*/
|
||||
0, /*sq_slice*/
|
||||
(ssizeobjargproc)mmap_ass_item, /*sq_ass_item*/
|
||||
(ssizessizeobjargproc)mmap_ass_slice, /*sq_ass_slice*/
|
||||
0, /*sq_ass_slice*/
|
||||
};
|
||||
|
||||
static PyMappingMethods mmap_as_mapping = {
|
||||
|
|
|
@ -1505,26 +1505,12 @@ PySequence_GetItem(PyObject *s, Py_ssize_t i)
|
|||
PyObject *
|
||||
PySequence_GetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2)
|
||||
{
|
||||
PySequenceMethods *m;
|
||||
PyMappingMethods *mp;
|
||||
|
||||
if (!s) return null_error();
|
||||
|
||||
m = s->ob_type->tp_as_sequence;
|
||||
if (m && m->sq_slice) {
|
||||
if (i1 < 0 || i2 < 0) {
|
||||
if (m->sq_length) {
|
||||
Py_ssize_t l = (*m->sq_length)(s);
|
||||
if (l < 0)
|
||||
return NULL;
|
||||
if (i1 < 0)
|
||||
i1 += l;
|
||||
if (i2 < 0)
|
||||
i2 += l;
|
||||
}
|
||||
}
|
||||
return m->sq_slice(s, i1, i2);
|
||||
} else if ((mp = s->ob_type->tp_as_mapping) && mp->mp_subscript) {
|
||||
mp = s->ob_type->tp_as_mapping;
|
||||
if (mp->mp_subscript) {
|
||||
PyObject *res;
|
||||
PyObject *slice = _PySlice_FromIndices(i1, i2);
|
||||
if (!slice)
|
||||
|
@ -1594,7 +1580,6 @@ PySequence_DelItem(PyObject *s, Py_ssize_t i)
|
|||
int
|
||||
PySequence_SetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2, PyObject *o)
|
||||
{
|
||||
PySequenceMethods *m;
|
||||
PyMappingMethods *mp;
|
||||
|
||||
if (s == NULL) {
|
||||
|
@ -1602,21 +1587,8 @@ PySequence_SetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2, PyObject *o)
|
|||
return -1;
|
||||
}
|
||||
|
||||
m = s->ob_type->tp_as_sequence;
|
||||
if (m && m->sq_ass_slice) {
|
||||
if (i1 < 0 || i2 < 0) {
|
||||
if (m->sq_length) {
|
||||
Py_ssize_t l = (*m->sq_length)(s);
|
||||
if (l < 0)
|
||||
return -1;
|
||||
if (i1 < 0)
|
||||
i1 += l;
|
||||
if (i2 < 0)
|
||||
i2 += l;
|
||||
}
|
||||
}
|
||||
return m->sq_ass_slice(s, i1, i2, o);
|
||||
} else if ((mp = s->ob_type->tp_as_mapping) && mp->mp_ass_subscript) {
|
||||
mp = s->ob_type->tp_as_mapping;
|
||||
if (mp->mp_ass_subscript) {
|
||||
int res;
|
||||
PyObject *slice = _PySlice_FromIndices(i1, i2);
|
||||
if (!slice)
|
||||
|
@ -1633,27 +1605,22 @@ PySequence_SetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2, PyObject *o)
|
|||
int
|
||||
PySequence_DelSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2)
|
||||
{
|
||||
PySequenceMethods *m;
|
||||
PyMappingMethods *mp;
|
||||
|
||||
if (s == NULL) {
|
||||
null_error();
|
||||
return -1;
|
||||
}
|
||||
|
||||
m = s->ob_type->tp_as_sequence;
|
||||
if (m && m->sq_ass_slice) {
|
||||
if (i1 < 0 || i2 < 0) {
|
||||
if (m->sq_length) {
|
||||
Py_ssize_t l = (*m->sq_length)(s);
|
||||
if (l < 0)
|
||||
return -1;
|
||||
if (i1 < 0)
|
||||
i1 += l;
|
||||
if (i2 < 0)
|
||||
i2 += l;
|
||||
}
|
||||
}
|
||||
return m->sq_ass_slice(s, i1, i2, (PyObject *)NULL);
|
||||
mp = s->ob_type->tp_as_mapping;
|
||||
if (mp->mp_ass_subscript) {
|
||||
int res;
|
||||
PyObject *slice = _PySlice_FromIndices(i1, i2);
|
||||
if (!slice)
|
||||
return -1;
|
||||
res = mp->mp_ass_subscript(s, slice, NULL);
|
||||
Py_DECREF(slice);
|
||||
return res;
|
||||
}
|
||||
type_error("'%.200s' object doesn't support slice deletion", s);
|
||||
return -1;
|
||||
|
@ -1925,9 +1892,7 @@ int
|
|||
PyMapping_Check(PyObject *o)
|
||||
{
|
||||
return o && o->ob_type->tp_as_mapping &&
|
||||
o->ob_type->tp_as_mapping->mp_subscript &&
|
||||
!(o->ob_type->tp_as_sequence &&
|
||||
o->ob_type->tp_as_sequence->sq_slice);
|
||||
o->ob_type->tp_as_mapping->mp_subscript;
|
||||
}
|
||||
|
||||
Py_ssize_t
|
||||
|
|
|
@ -464,28 +464,6 @@ buffer_item(PyBufferObject *self, Py_ssize_t idx)
|
|||
return ob;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
buffer_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right)
|
||||
{
|
||||
PyObject *ob;
|
||||
PyBuffer view;
|
||||
if (!get_buf(self, &view, PyBUF_SIMPLE))
|
||||
return NULL;
|
||||
if (left < 0)
|
||||
left = 0;
|
||||
if (right < 0)
|
||||
right = 0;
|
||||
if (right > view.len)
|
||||
right = view.len;
|
||||
if (right < left)
|
||||
right = left;
|
||||
/* XXX(nnorwitz): is it possible to access unitialized memory? */
|
||||
ob = PyBytes_FromStringAndSize((char *)view.buf + left,
|
||||
right - left);
|
||||
PyObject_ReleaseBuffer((PyObject *)self, &view);
|
||||
return ob;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
buffer_subscript(PyBufferObject *self, PyObject *item)
|
||||
{
|
||||
|
@ -604,62 +582,6 @@ buffer_ass_item(PyBufferObject *self, Py_ssize_t idx, PyObject *other)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
buffer_ass_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right,
|
||||
PyObject *other)
|
||||
{
|
||||
PyBufferProcs *pb;
|
||||
PyBuffer v1, v2;
|
||||
Py_ssize_t slice_len;
|
||||
|
||||
pb = other ? other->ob_type->tp_as_buffer : NULL;
|
||||
if (pb == NULL ||
|
||||
pb->bf_getbuffer == NULL) {
|
||||
PyErr_BadArgument();
|
||||
return -1;
|
||||
}
|
||||
if (!get_buf(self, &v1, PyBUF_SIMPLE))
|
||||
return -1;
|
||||
|
||||
if (self->b_readonly || v1.readonly) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"buffer is read-only");
|
||||
PyObject_ReleaseBuffer((PyObject *)self, &v1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((*pb->bf_getbuffer)(other, &v2, PyBUF_SIMPLE) < 0) {
|
||||
PyObject_ReleaseBuffer((PyObject *)self, &v1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (left < 0)
|
||||
left = 0;
|
||||
else if (left > v1.len)
|
||||
left = v1.len;
|
||||
if (right < left)
|
||||
right = left;
|
||||
else if (right > v1.len)
|
||||
right = v1.len;
|
||||
slice_len = right - left;
|
||||
|
||||
if (v2.len != slice_len) {
|
||||
PyErr_SetString(
|
||||
PyExc_TypeError,
|
||||
"right operand length must match slice length");
|
||||
PyObject_ReleaseBuffer((PyObject *)self, &v1);
|
||||
PyObject_ReleaseBuffer(other, &v2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (slice_len)
|
||||
memcpy((char *)v1.buf + left, v2.buf, slice_len);
|
||||
|
||||
PyObject_ReleaseBuffer((PyObject *)self, &v1);
|
||||
PyObject_ReleaseBuffer(other, &v2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
buffer_ass_subscript(PyBufferObject *self, PyObject *item, PyObject *value)
|
||||
{
|
||||
|
@ -743,9 +665,9 @@ static PySequenceMethods buffer_as_sequence = {
|
|||
(binaryfunc)buffer_concat, /*sq_concat*/
|
||||
(ssizeargfunc)buffer_repeat, /*sq_repeat*/
|
||||
(ssizeargfunc)buffer_item, /*sq_item*/
|
||||
(ssizessizeargfunc)buffer_slice, /*sq_slice*/
|
||||
0, /*sq_slice*/
|
||||
(ssizeobjargproc)buffer_ass_item, /*sq_ass_item*/
|
||||
(ssizessizeobjargproc)buffer_ass_slice, /*sq_ass_slice*/
|
||||
0, /*sq_ass_slice*/
|
||||
};
|
||||
|
||||
static PyMappingMethods buffer_as_mapping = {
|
||||
|
|
|
@ -2423,9 +2423,9 @@ static PySequenceMethods list_as_sequence = {
|
|||
(binaryfunc)list_concat, /* sq_concat */
|
||||
(ssizeargfunc)list_repeat, /* sq_repeat */
|
||||
(ssizeargfunc)list_item, /* sq_item */
|
||||
(ssizessizeargfunc)list_slice, /* sq_slice */
|
||||
0, /* sq_slice */
|
||||
(ssizeobjargproc)list_ass_item, /* sq_ass_item */
|
||||
(ssizessizeobjargproc)list_ass_slice, /* sq_ass_slice */
|
||||
0, /* sq_ass_slice */
|
||||
(objobjproc)list_contains, /* sq_contains */
|
||||
(binaryfunc)list_inplace_concat, /* sq_inplace_concat */
|
||||
(ssizeargfunc)list_inplace_repeat, /* sq_inplace_repeat */
|
||||
|
|
|
@ -965,29 +965,6 @@ string_repeat(register PyStringObject *a, register Py_ssize_t n)
|
|||
return (PyObject *) op;
|
||||
}
|
||||
|
||||
/* String slice a[i:j] consists of characters a[i] ... a[j-1] */
|
||||
|
||||
static PyObject *
|
||||
string_slice(register PyStringObject *a, register Py_ssize_t i,
|
||||
register Py_ssize_t j)
|
||||
/* j -- may be negative! */
|
||||
{
|
||||
if (i < 0)
|
||||
i = 0;
|
||||
if (j < 0)
|
||||
j = 0; /* Avoid signed/unsigned bug in next line */
|
||||
if (j > Py_Size(a))
|
||||
j = Py_Size(a);
|
||||
if (i == 0 && j == Py_Size(a) && PyString_CheckExact(a)) {
|
||||
/* It's the same as a */
|
||||
Py_INCREF(a);
|
||||
return (PyObject *)a;
|
||||
}
|
||||
if (j < i)
|
||||
j = i;
|
||||
return PyString_FromStringAndSize(a->ob_sval + i, j-i);
|
||||
}
|
||||
|
||||
static int
|
||||
string_contains(PyObject *str_obj, PyObject *sub_obj)
|
||||
{
|
||||
|
@ -1193,7 +1170,7 @@ static PySequenceMethods string_as_sequence = {
|
|||
(binaryfunc)string_concat, /*sq_concat*/
|
||||
(ssizeargfunc)string_repeat, /*sq_repeat*/
|
||||
(ssizeargfunc)string_item, /*sq_item*/
|
||||
(ssizessizeargfunc)string_slice, /*sq_slice*/
|
||||
0, /*sq_slice*/
|
||||
0, /*sq_ass_item*/
|
||||
0, /*sq_ass_slice*/
|
||||
(objobjproc)string_contains /*sq_contains*/
|
||||
|
|
|
@ -340,7 +340,7 @@ static PySequenceMethods structseq_as_sequence = {
|
|||
(binaryfunc)structseq_concat, /* sq_concat */
|
||||
(ssizeargfunc)structseq_repeat, /* sq_repeat */
|
||||
(ssizeargfunc)structseq_item, /* sq_item */
|
||||
(ssizessizeargfunc)structseq_slice, /* sq_slice */
|
||||
0, /* sq_slice */
|
||||
0, /* sq_ass_item */
|
||||
0, /* sq_ass_slice */
|
||||
(objobjproc)structseq_contains, /* sq_contains */
|
||||
|
|
|
@ -554,7 +554,7 @@ static PySequenceMethods tuple_as_sequence = {
|
|||
(binaryfunc)tupleconcat, /* sq_concat */
|
||||
(ssizeargfunc)tuplerepeat, /* sq_repeat */
|
||||
(ssizeargfunc)tupleitem, /* sq_item */
|
||||
(ssizessizeargfunc)tupleslice, /* sq_slice */
|
||||
0, /* sq_slice */
|
||||
0, /* sq_ass_item */
|
||||
0, /* sq_ass_slice */
|
||||
(objobjproc)tuplecontains, /* sq_contains */
|
||||
|
|
|
@ -3260,9 +3260,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base)
|
|||
COPYSEQ(sq_concat);
|
||||
COPYSEQ(sq_repeat);
|
||||
COPYSEQ(sq_item);
|
||||
COPYSEQ(sq_slice);
|
||||
COPYSEQ(sq_ass_item);
|
||||
COPYSEQ(sq_ass_slice);
|
||||
COPYSEQ(sq_contains);
|
||||
COPYSEQ(sq_inplace_concat);
|
||||
COPYSEQ(sq_inplace_repeat);
|
||||
|
@ -3765,17 +3763,6 @@ wrap_sq_item(PyObject *self, PyObject *args, void *wrapped)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
wrap_ssizessizeargfunc(PyObject *self, PyObject *args, void *wrapped)
|
||||
{
|
||||
ssizessizeargfunc func = (ssizessizeargfunc)wrapped;
|
||||
Py_ssize_t i, j;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "nn", &i, &j))
|
||||
return NULL;
|
||||
return (*func)(self, i, j);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
wrap_sq_setitem(PyObject *self, PyObject *args, void *wrapped)
|
||||
{
|
||||
|
@ -3817,39 +3804,6 @@ wrap_sq_delitem(PyObject *self, PyObject *args, void *wrapped)
|
|||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
wrap_ssizessizeobjargproc(PyObject *self, PyObject *args, void *wrapped)
|
||||
{
|
||||
ssizessizeobjargproc func = (ssizessizeobjargproc)wrapped;
|
||||
Py_ssize_t i, j;
|
||||
int res;
|
||||
PyObject *value;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "nnO", &i, &j, &value))
|
||||
return NULL;
|
||||
res = (*func)(self, i, j, value);
|
||||
if (res == -1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
wrap_delslice(PyObject *self, PyObject *args, void *wrapped)
|
||||
{
|
||||
ssizessizeobjargproc func = (ssizessizeobjargproc)wrapped;
|
||||
Py_ssize_t i, j;
|
||||
int res;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "nn", &i, &j))
|
||||
return NULL;
|
||||
res = (*func)(self, i, j, NULL);
|
||||
if (res == -1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
/* XXX objobjproc is a misnomer; should be objargpred */
|
||||
static PyObject *
|
||||
wrap_objobjproc(PyObject *self, PyObject *args, void *wrapped)
|
||||
|
@ -4363,8 +4317,6 @@ slot_sq_item(PyObject *self, Py_ssize_t i)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
SLOT2(slot_sq_slice, "__getslice__", Py_ssize_t, Py_ssize_t, "nn")
|
||||
|
||||
static int
|
||||
slot_sq_ass_item(PyObject *self, Py_ssize_t index, PyObject *value)
|
||||
{
|
||||
|
@ -4383,24 +4335,6 @@ slot_sq_ass_item(PyObject *self, Py_ssize_t index, PyObject *value)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
slot_sq_ass_slice(PyObject *self, Py_ssize_t i, Py_ssize_t j, PyObject *value)
|
||||
{
|
||||
PyObject *res;
|
||||
static PyObject *delslice_str, *setslice_str;
|
||||
|
||||
if (value == NULL)
|
||||
res = call_method(self, "__delslice__", &delslice_str,
|
||||
"(nn)", i, j);
|
||||
else
|
||||
res = call_method(self, "__setslice__", &setslice_str,
|
||||
"(nnO)", i, j, value);
|
||||
if (res == NULL)
|
||||
return -1;
|
||||
Py_DECREF(res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
slot_sq_contains(PyObject *self, PyObject *value)
|
||||
{
|
||||
|
@ -5123,23 +5057,10 @@ static slotdef slotdefs[] = {
|
|||
"x.__rmul__(n) <==> n*x"),
|
||||
SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item,
|
||||
"x.__getitem__(y) <==> x[y]"),
|
||||
SQSLOT("__getslice__", sq_slice, slot_sq_slice, wrap_ssizessizeargfunc,
|
||||
"x.__getslice__(i, j) <==> x[i:j]\n\
|
||||
\n\
|
||||
Use of negative indices is not supported."),
|
||||
SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem,
|
||||
"x.__setitem__(i, y) <==> x[i]=y"),
|
||||
SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem,
|
||||
"x.__delitem__(y) <==> del x[y]"),
|
||||
SQSLOT("__setslice__", sq_ass_slice, slot_sq_ass_slice,
|
||||
wrap_ssizessizeobjargproc,
|
||||
"x.__setslice__(i, j, y) <==> x[i:j]=y\n\
|
||||
\n\
|
||||
Use of negative indices is not supported."),
|
||||
SQSLOT("__delslice__", sq_ass_slice, slot_sq_ass_slice, wrap_delslice,
|
||||
"x.__delslice__(i, j) <==> del x[i:j]\n\
|
||||
\n\
|
||||
Use of negative indices is not supported."),
|
||||
SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc,
|
||||
"x.__contains__(y) <==> y in x"),
|
||||
SQSLOT("__iadd__", sq_inplace_concat, NULL,
|
||||
|
|
|
@ -7502,28 +7502,6 @@ unicode_rjust(PyUnicodeObject *self, PyObject *args)
|
|||
return (PyObject*) pad(self, width - self->length, 0, fillchar);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
unicode_slice(PyUnicodeObject *self, Py_ssize_t start, Py_ssize_t end)
|
||||
{
|
||||
/* standard clamping */
|
||||
if (start < 0)
|
||||
start = 0;
|
||||
if (end < 0)
|
||||
end = 0;
|
||||
if (end > self->length)
|
||||
end = self->length;
|
||||
if (start == 0 && end == self->length && PyUnicode_CheckExact(self)) {
|
||||
/* full slice, return original string */
|
||||
Py_INCREF(self);
|
||||
return (PyObject*) self;
|
||||
}
|
||||
if (start > end)
|
||||
start = end;
|
||||
/* copy slice */
|
||||
return (PyObject*) PyUnicode_FromUnicode(self->str + start,
|
||||
end - start);
|
||||
}
|
||||
|
||||
PyObject *PyUnicode_Split(PyObject *s,
|
||||
PyObject *sep,
|
||||
Py_ssize_t maxsplit)
|
||||
|
@ -8039,7 +8017,7 @@ static PySequenceMethods unicode_as_sequence = {
|
|||
PyUnicode_Concat, /* sq_concat */
|
||||
(ssizeargfunc) unicode_repeat, /* sq_repeat */
|
||||
(ssizeargfunc) unicode_getitem, /* sq_item */
|
||||
(ssizessizeargfunc) unicode_slice, /* sq_slice */
|
||||
0, /* sq_slice */
|
||||
0, /* sq_ass_item */
|
||||
0, /* sq_ass_slice */
|
||||
PyUnicode_Contains, /* sq_contains */
|
||||
|
|
|
@ -520,22 +520,6 @@ proxy_dealloc(PyWeakReference *self)
|
|||
|
||||
/* sequence slots */
|
||||
|
||||
static PyObject *
|
||||
proxy_slice(PyWeakReference *proxy, Py_ssize_t i, Py_ssize_t j)
|
||||
{
|
||||
if (!proxy_checkref(proxy))
|
||||
return NULL;
|
||||
return PySequence_GetSlice(PyWeakref_GET_OBJECT(proxy), i, j);
|
||||
}
|
||||
|
||||
static int
|
||||
proxy_ass_slice(PyWeakReference *proxy, Py_ssize_t i, Py_ssize_t j, PyObject *value)
|
||||
{
|
||||
if (!proxy_checkref(proxy))
|
||||
return -1;
|
||||
return PySequence_SetSlice(PyWeakref_GET_OBJECT(proxy), i, j, value);
|
||||
}
|
||||
|
||||
static int
|
||||
proxy_contains(PyWeakReference *proxy, PyObject *value)
|
||||
{
|
||||
|
@ -628,9 +612,9 @@ static PySequenceMethods proxy_as_sequence = {
|
|||
0, /*sq_concat*/
|
||||
0, /*sq_repeat*/
|
||||
0, /*sq_item*/
|
||||
(ssizessizeargfunc)proxy_slice, /*sq_slice*/
|
||||
0, /*sq_slice*/
|
||||
0, /*sq_ass_item*/
|
||||
(ssizessizeobjargproc)proxy_ass_slice, /*sq_ass_slice*/
|
||||
0, /*sq_ass_slice*/
|
||||
(objobjproc)proxy_contains, /* sq_contains */
|
||||
};
|
||||
|
||||
|
|
131
Python/ceval.c
131
Python/ceval.c
|
@ -111,9 +111,6 @@ static void call_exc_trace(Py_tracefunc, PyObject *, PyFrameObject *);
|
|||
static int maybe_call_line_trace(Py_tracefunc, PyObject *,
|
||||
PyFrameObject *, int *, int *, int *);
|
||||
|
||||
static PyObject * apply_slice(PyObject *, PyObject *, PyObject *);
|
||||
static int assign_slice(PyObject *, PyObject *,
|
||||
PyObject *, PyObject *);
|
||||
static PyObject * cmp_outcome(int, PyObject *, PyObject *);
|
||||
static PyObject * import_from(PyObject *, PyObject *);
|
||||
static int import_all_from(PyObject *, PyObject *);
|
||||
|
@ -1416,70 +1413,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
|
|||
if (x != NULL) continue;
|
||||
break;
|
||||
|
||||
case SLICE+0:
|
||||
case SLICE+1:
|
||||
case SLICE+2:
|
||||
case SLICE+3:
|
||||
if ((opcode-SLICE) & 2)
|
||||
w = POP();
|
||||
else
|
||||
w = NULL;
|
||||
if ((opcode-SLICE) & 1)
|
||||
v = POP();
|
||||
else
|
||||
v = NULL;
|
||||
u = TOP();
|
||||
x = apply_slice(u, v, w);
|
||||
Py_DECREF(u);
|
||||
Py_XDECREF(v);
|
||||
Py_XDECREF(w);
|
||||
SET_TOP(x);
|
||||
if (x != NULL) continue;
|
||||
break;
|
||||
|
||||
case STORE_SLICE+0:
|
||||
case STORE_SLICE+1:
|
||||
case STORE_SLICE+2:
|
||||
case STORE_SLICE+3:
|
||||
if ((opcode-STORE_SLICE) & 2)
|
||||
w = POP();
|
||||
else
|
||||
w = NULL;
|
||||
if ((opcode-STORE_SLICE) & 1)
|
||||
v = POP();
|
||||
else
|
||||
v = NULL;
|
||||
u = POP();
|
||||
t = POP();
|
||||
err = assign_slice(u, v, w, t); /* u[v:w] = t */
|
||||
Py_DECREF(t);
|
||||
Py_DECREF(u);
|
||||
Py_XDECREF(v);
|
||||
Py_XDECREF(w);
|
||||
if (err == 0) continue;
|
||||
break;
|
||||
|
||||
case DELETE_SLICE+0:
|
||||
case DELETE_SLICE+1:
|
||||
case DELETE_SLICE+2:
|
||||
case DELETE_SLICE+3:
|
||||
if ((opcode-DELETE_SLICE) & 2)
|
||||
w = POP();
|
||||
else
|
||||
w = NULL;
|
||||
if ((opcode-DELETE_SLICE) & 1)
|
||||
v = POP();
|
||||
else
|
||||
v = NULL;
|
||||
u = POP();
|
||||
err = assign_slice(u, v, w, (PyObject *)NULL);
|
||||
/* del u[v:w] */
|
||||
Py_DECREF(u);
|
||||
Py_XDECREF(v);
|
||||
Py_XDECREF(w);
|
||||
if (err == 0) continue;
|
||||
break;
|
||||
|
||||
case STORE_SUBSCR:
|
||||
w = TOP();
|
||||
v = SECOND();
|
||||
|
@ -3895,70 +3828,6 @@ _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi)
|
|||
return 1;
|
||||
}
|
||||
|
||||
#undef ISINDEX
|
||||
#define ISINDEX(x) ((x) == NULL || \
|
||||
PyInt_Check(x) || PyLong_Check(x) || PyIndex_Check(x))
|
||||
|
||||
static PyObject *
|
||||
apply_slice(PyObject *u, PyObject *v, PyObject *w) /* return u[v:w] */
|
||||
{
|
||||
PyTypeObject *tp = u->ob_type;
|
||||
PySequenceMethods *sq = tp->tp_as_sequence;
|
||||
|
||||
if (sq && sq->sq_slice && ISINDEX(v) && ISINDEX(w)) {
|
||||
Py_ssize_t ilow = 0, ihigh = PY_SSIZE_T_MAX;
|
||||
if (!_PyEval_SliceIndex(v, &ilow))
|
||||
return NULL;
|
||||
if (!_PyEval_SliceIndex(w, &ihigh))
|
||||
return NULL;
|
||||
return PySequence_GetSlice(u, ilow, ihigh);
|
||||
}
|
||||
else {
|
||||
PyObject *slice = PySlice_New(v, w, NULL);
|
||||
if (slice != NULL) {
|
||||
PyObject *res = PyObject_GetItem(u, slice);
|
||||
Py_DECREF(slice);
|
||||
return res;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
assign_slice(PyObject *u, PyObject *v, PyObject *w, PyObject *x)
|
||||
/* u[v:w] = x */
|
||||
{
|
||||
PyTypeObject *tp = u->ob_type;
|
||||
PySequenceMethods *sq = tp->tp_as_sequence;
|
||||
|
||||
if (sq && sq->sq_ass_slice && ISINDEX(v) && ISINDEX(w)) {
|
||||
Py_ssize_t ilow = 0, ihigh = PY_SSIZE_T_MAX;
|
||||
if (!_PyEval_SliceIndex(v, &ilow))
|
||||
return -1;
|
||||
if (!_PyEval_SliceIndex(w, &ihigh))
|
||||
return -1;
|
||||
if (x == NULL)
|
||||
return PySequence_DelSlice(u, ilow, ihigh);
|
||||
else
|
||||
return PySequence_SetSlice(u, ilow, ihigh, x);
|
||||
}
|
||||
else {
|
||||
PyObject *slice = PySlice_New(v, w, NULL);
|
||||
if (slice != NULL) {
|
||||
int res;
|
||||
if (x != NULL)
|
||||
res = PyObject_SetItem(u, slice, x);
|
||||
else
|
||||
res = PyObject_DelItem(u, slice);
|
||||
Py_DECREF(slice);
|
||||
return res;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#define CANNOT_CATCH_MSG "catching classes that do not inherit from "\
|
||||
"BaseException is not allowed"
|
||||
|
||||
|
|
|
@ -707,33 +707,6 @@ opcode_stack_effect(int opcode, int oparg)
|
|||
case INPLACE_TRUE_DIVIDE:
|
||||
return -1;
|
||||
|
||||
case SLICE+0:
|
||||
return 1;
|
||||
case SLICE+1:
|
||||
return 0;
|
||||
case SLICE+2:
|
||||
return 0;
|
||||
case SLICE+3:
|
||||
return -1;
|
||||
|
||||
case STORE_SLICE+0:
|
||||
return -2;
|
||||
case STORE_SLICE+1:
|
||||
return -3;
|
||||
case STORE_SLICE+2:
|
||||
return -3;
|
||||
case STORE_SLICE+3:
|
||||
return -4;
|
||||
|
||||
case DELETE_SLICE+0:
|
||||
return -1;
|
||||
case DELETE_SLICE+1:
|
||||
return -2;
|
||||
case DELETE_SLICE+2:
|
||||
return -2;
|
||||
case DELETE_SLICE+3:
|
||||
return -3;
|
||||
|
||||
case INPLACE_ADD:
|
||||
case INPLACE_SUBTRACT:
|
||||
case INPLACE_MULTIPLY:
|
||||
|
@ -3507,57 +3480,6 @@ compiler_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
compiler_simple_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
|
||||
{
|
||||
int op = 0, slice_offset = 0, stack_count = 0;
|
||||
|
||||
assert(s->v.Slice.step == NULL);
|
||||
if (s->v.Slice.lower) {
|
||||
slice_offset++;
|
||||
stack_count++;
|
||||
if (ctx != AugStore)
|
||||
VISIT(c, expr, s->v.Slice.lower);
|
||||
}
|
||||
if (s->v.Slice.upper) {
|
||||
slice_offset += 2;
|
||||
stack_count++;
|
||||
if (ctx != AugStore)
|
||||
VISIT(c, expr, s->v.Slice.upper);
|
||||
}
|
||||
|
||||
if (ctx == AugLoad) {
|
||||
switch (stack_count) {
|
||||
case 0: ADDOP(c, DUP_TOP); break;
|
||||
case 1: ADDOP_I(c, DUP_TOPX, 2); break;
|
||||
case 2: ADDOP_I(c, DUP_TOPX, 3); break;
|
||||
}
|
||||
}
|
||||
else if (ctx == AugStore) {
|
||||
switch (stack_count) {
|
||||
case 0: ADDOP(c, ROT_TWO); break;
|
||||
case 1: ADDOP(c, ROT_THREE); break;
|
||||
case 2: ADDOP(c, ROT_FOUR); break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (ctx) {
|
||||
case AugLoad: /* fall through to Load */
|
||||
case Load: op = SLICE; break;
|
||||
case AugStore:/* fall through to Store */
|
||||
case Store: op = STORE_SLICE; break;
|
||||
case Del: op = DELETE_SLICE; break;
|
||||
case Param:
|
||||
default:
|
||||
PyErr_SetString(PyExc_SystemError,
|
||||
"param invalid in simple slice");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ADDOP(c, op + slice_offset);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
compiler_visit_nested_slice(struct compiler *c, slice_ty s,
|
||||
expr_context_ty ctx)
|
||||
|
@ -3590,8 +3512,6 @@ compiler_visit_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
|
|||
break;
|
||||
case Slice_kind:
|
||||
kindname = "slice";
|
||||
if (!s->v.Slice.step)
|
||||
return compiler_simple_slice(c, s, ctx);
|
||||
if (ctx != AugStore) {
|
||||
if (!compiler_slice(c, s, ctx))
|
||||
return 0;
|
||||
|
|
|
@ -875,6 +875,7 @@ PyDoc_STR(
|
|||
Static objects:\n\
|
||||
\n\
|
||||
maxint -- the largest supported integer (the smallest is -maxint-1)\n\
|
||||
maxsize -- the largest supported length of containers.\n\
|
||||
maxunicode -- the largest supported character\n\
|
||||
builtin_module_names -- tuple of module names built into this interpreter\n\
|
||||
version -- the version of this interpreter as a string\n\
|
||||
|
@ -1087,6 +1088,8 @@ _PySys_Init(void)
|
|||
PyUnicode_FromString(Py_GetExecPrefix()));
|
||||
SET_SYS_FROM_STRING("maxint",
|
||||
PyInt_FromLong(PyInt_GetMax()));
|
||||
SET_SYS_FROM_STRING("maxsize",
|
||||
PyInt_FromLong(PY_SSIZE_T_MAX));
|
||||
SET_SYS_FROM_STRING("maxunicode",
|
||||
PyInt_FromLong(PyUnicode_GetMax()));
|
||||
SET_SYS_FROM_STRING("builtin_module_names",
|
||||
|
|
Loading…
Reference in New Issue