[Python-checkins] r53044 - in python/branches/p3yk-noslice: Lib/UserString.py Lib/test/string_tests.py Lib/test/test_array.py Lib/test/test_buffer.py Lib/test/test_bytes.py Lib/test/test_mmap.py Lib/test/test_structseq.py Lib/test/test_userstring.py TODO
thomas.wouters
python-checkins at python.org
Sat Dec 16 10:01:35 CET 2006
Author: thomas.wouters
Date: Sat Dec 16 10:01:33 2006
New Revision: 53044
Modified:
python/branches/p3yk-noslice/Lib/UserString.py
python/branches/p3yk-noslice/Lib/test/string_tests.py
python/branches/p3yk-noslice/Lib/test/test_array.py
python/branches/p3yk-noslice/Lib/test/test_buffer.py
python/branches/p3yk-noslice/Lib/test/test_bytes.py
python/branches/p3yk-noslice/Lib/test/test_mmap.py
python/branches/p3yk-noslice/Lib/test/test_structseq.py
python/branches/p3yk-noslice/Lib/test/test_userstring.py
python/branches/p3yk-noslice/TODO
Log:
- Add/expand tests for extended slicing in stringtypes, array, buffer,
structseq, mmap
- Clean up test for extended slicing of bytes
- Fix bug in slice assignment/deletion of UserString.MutableString
- Add support for step=-1 to UserString.MutableString slicing
- Update TODO
Modified: python/branches/p3yk-noslice/Lib/UserString.py
==============================================================================
--- python/branches/p3yk-noslice/Lib/UserString.py (original)
+++ python/branches/p3yk-noslice/Lib/UserString.py Sat Dec 16 10:01:33 2006
@@ -178,8 +178,14 @@
elif not isinstance(sub, basestring):
sub = str(sub)
start, stop, step = index.indices(len(self.data))
- if step != 1:
+ if step == -1:
+ start, stop = stop+1, start+1
+ sub = sub[::-1]
+ elif step != 1:
+ # XXX(twouters): I guess we should be reimplementing
+ # the extended slice assignment/deletion algorithm here...
raise TypeError, "invalid step in slicing assignment"
+ start = min(start, stop)
self.data = self.data[:start] + sub + self.data[stop:]
else:
if index < 0:
@@ -189,8 +195,12 @@
def __delitem__(self, index):
if isinstance(index, slice):
start, stop, step = index.indices(len(self.data))
- if step != 1:
- raise TypeError, "invalid step in slicing assignment"
+ if step == -1:
+ start, stop = stop+1, start+1
+ elif step != 1:
+ # XXX(twouters): see same block in __setitem__
+ raise TypeError, "invalid step in slicing deletion"
+ start = min(start, stop)
self.data = self.data[:start] + self.data[stop:]
else:
if index < 0:
Modified: python/branches/p3yk-noslice/Lib/test/string_tests.py
==============================================================================
--- python/branches/p3yk-noslice/Lib/test/string_tests.py (original)
+++ python/branches/p3yk-noslice/Lib/test/string_tests.py Sat Dec 16 10:01:33 2006
@@ -907,10 +907,21 @@
self.checkequal(u'abc', 'abc', '__getitem__', slice(0, 1000))
self.checkequal(u'a', 'abc', '__getitem__', slice(0, 1))
self.checkequal(u'', 'abc', '__getitem__', slice(0, 0))
- # FIXME What about negative indices? This is handled differently by [] and __getitem__(slice)
self.checkraises(TypeError, 'abc', '__getitem__', 'def')
+ def test_extended_getslice(self):
+ # Test extended slicing by comparing with list slicing.
+ s = string.ascii_letters + string.digits
+ indices = (0, None, 1, 3, 41, -1, -2, -37)
+ for start in indices:
+ for stop in indices:
+ # Skip step 0 (invalid)
+ for step in indices[1:]:
+ L = list(s)[start:stop:step]
+ self.checkequal(u"".join(L), s, '__getitem__',
+ slice(start, stop, step))
+
def test_mul(self):
self.checkequal('', 'abc', '__mul__', -1)
self.checkequal('', 'abc', '__mul__', 0)
Modified: python/branches/p3yk-noslice/Lib/test/test_array.py
==============================================================================
--- python/branches/p3yk-noslice/Lib/test/test_array.py (original)
+++ python/branches/p3yk-noslice/Lib/test/test_array.py Sat Dec 16 10:01:33 2006
@@ -455,6 +455,18 @@
array.array(self.typecode)
)
+ def test_extended_getslice(self):
+ # Test extended slicing by comparing with list slicing
+ # (Assumes list conversion works correctly, too)
+ a = array.array(self.typecode, self.example)
+ indices = (0, None, 1, 3, 19, 100, -1, -2, -31, -100)
+ for start in indices:
+ for stop in indices:
+ # Everything except the initial 0 (invalid step)
+ for step in indices[1:]:
+ self.assertEqual(list(a[start:stop:step]),
+ list(a)[start:stop:step])
+
def test_setslice(self):
a = array.array(self.typecode, self.example)
a[:1] = a
@@ -544,6 +556,26 @@
self.assertRaises(TypeError, a.__setitem__, slice(0, 0), b)
self.assertRaises(TypeError, a.__setitem__, slice(0, 1), b)
+ def test_extended_set_del_slice(self):
+ indices = (0, None, 1, 3, 19, 100, -1, -2, -31, -100)
+ for start in indices:
+ for stop in indices:
+ # Everything except the initial 0 (invalid step)
+ for step in indices[1:]:
+ a = array.array(self.typecode, self.example)
+ L = list(a)
+ # Make sure we have a slice of exactly the right length,
+ # but with (hopefully) different data.
+ data = L[start:stop:step]
+ data.reverse()
+ L[start:stop:step] = data
+ a[start:stop:step] = array.array(self.typecode, data)
+ self.assertEquals(a, array.array(self.typecode, L))
+
+ del L[start:stop:step]
+ del a[start:stop:step]
+ self.assertEquals(a, array.array(self.typecode, L))
+
def test_index(self):
example = 2*self.example
a = array.array(self.typecode, example)
Modified: python/branches/p3yk-noslice/Lib/test/test_buffer.py
==============================================================================
--- python/branches/p3yk-noslice/Lib/test/test_buffer.py (original)
+++ python/branches/p3yk-noslice/Lib/test/test_buffer.py Sat Dec 16 10:01:33 2006
@@ -37,6 +37,20 @@
self.failIf(a == b)
self.assertRaises(TypeError, lambda: a < b)
+ def test_extended_getslice(self):
+ # Test extended slicing by comparing with list slicing.
+ s = "".join(chr(c) for c in list(range(255, -1, -1)))
+ b = bytes(s)
+ indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300)
+ for start in indices:
+ for stop in indices:
+ # Skip step 0 (invalid)
+ for step in indices[1:]:
+ self.assertEqual(b[start:stop:step],
+ buffer(s[start:stop:step]))
+
+
+
def test_main():
test_support.run_unittest(BufferTests)
Modified: python/branches/p3yk-noslice/Lib/test/test_bytes.py
==============================================================================
--- python/branches/p3yk-noslice/Lib/test/test_bytes.py (original)
+++ python/branches/p3yk-noslice/Lib/test/test_bytes.py Sat Dec 16 10:01:33 2006
@@ -164,14 +164,15 @@
self.assertEqual(b[-100:5], by("Hello"))
def test_extended_getslice(self):
- L = range(20)
+ # Test extended slicing by comparing with list slicing.
+ L = list(range(255))
b = bytes(L)
- indices = (None, 1, 5, 11, 19, 100, -1, -2, -5, -11, -19, -100)
+ indices = (0, None, 1, 3, 19, 100, -1, -2, -31, -100)
for start in indices:
for stop in indices:
- for step in indices:
- idx = slice(start, stop, step)
- self.assertEqual(b[idx], bytes(L[idx]))
+ # Skip step 0 (invalid)
+ for step in indices[1:]:
+ self.assertEqual(b[start:stop:step], bytes(L[start:stop:step]))
def test_regexps(self):
def by(s):
@@ -250,32 +251,23 @@
self.assertEqual(b, bytes([0, 1, 2, 42, 42, 42, 3, 4, 5, 6, 7, 8, 9]))
def test_extended_set_del_slice(self):
- indices = (None, 1, 5, 11, 19, 100, -1, -2, -5, -11, -19, -100)
+ indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300)
for start in indices:
- for step in indices:
- for stop in indices:
- L = list(range(20))
+ for stop in indices:
+ # Skip invalid step 0
+ for step in indices[1:]:
+ L = list(range(255))
b = bytes(L)
-
- idx = slice(start, stop, step)
- start, stop, step = idx.indices(len(L))
- # This is taken from Pyslice_GetIndicesEx(),
- # and should probably be exposed to Python
- if ((step < 0 and start <= stop) or
- (step > 0 and start >= stop)):
- slicelen = 0
- elif step < 0:
- slicelen = (stop - start + 1) // step + 1
- else:
- slicelen = (stop - start - 1) // step + 1
-
- data = list(range(100, 100 + slicelen))
- L[idx] = data
- b[idx] = data
+ # Make sure we have a slice of exactly the right length,
+ # but with different data.
+ data = L[start:stop:step]
+ data.reverse()
+ L[start:stop:step] = data
+ b[start:stop:step] = data
self.assertEquals(b, bytes(L))
- del L[idx]
- del b[idx]
+ del L[start:stop:step]
+ del b[start:stop:step]
self.assertEquals(b, bytes(L))
def test_setslice_trap(self):
Modified: python/branches/p3yk-noslice/Lib/test/test_mmap.py
==============================================================================
--- python/branches/p3yk-noslice/Lib/test/test_mmap.py (original)
+++ python/branches/p3yk-noslice/Lib/test/test_mmap.py Sat Dec 16 10:01:33 2006
@@ -306,6 +306,40 @@
m[x] = ch = chr(x & 255)
self.assertEqual(m[x], ch)
+ def test_extended_getslice(self):
+ # Test extended slicing by comparing with list slicing.
+ s = "".join(chr(c) for c in list(range(255, -1, -1)))
+ m = mmap.mmap(-1, len(s))
+ m[:] = s
+ self.assertEqual(m[:], s)
+ indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300)
+ for start in indices:
+ for stop in indices:
+ # Skip step 0 (invalid)
+ for step in indices[1:]:
+ self.assertEqual(m[start:stop:step],
+ s[start:stop:step])
+
+ def test_extended_set_del_slice(self):
+ # Test extended slicing by comparing with list slicing.
+ s = "".join(chr(c) for c in list(range(255, -1, -1)))
+ m = mmap.mmap(-1, len(s))
+ indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300)
+ for start in indices:
+ for stop in indices:
+ # Skip invalid step 0
+ for step in indices[1:]:
+ m[:] = s
+ self.assertEqual(m[:], s)
+ L = list(s)
+ # Make sure we have a slice of exactly the right length,
+ # but with different data.
+ data = L[start:stop:step]
+ data = "".join(reversed(data))
+ L[start:stop:step] = data
+ m[start:stop:step] = data
+ self.assertEquals(m[:], "".join(L))
+
def test_main():
run_unittest(MmapTests)
Modified: python/branches/p3yk-noslice/Lib/test/test_structseq.py
==============================================================================
--- python/branches/p3yk-noslice/Lib/test/test_structseq.py (original)
+++ python/branches/p3yk-noslice/Lib/test/test_structseq.py Sat Dec 16 10:01:33 2006
@@ -97,6 +97,18 @@
t = time.gmtime()
x = t.__reduce__()
+ def test_extended_getslice(self):
+ # Test extended slicing by comparing with list slicing.
+ t = time.gmtime()
+ L = list(t)
+ indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300)
+ for start in indices:
+ for stop in indices:
+ # Skip step 0 (invalid)
+ for step in indices[1:]:
+ self.assertEqual(list(t[start:stop:step]),
+ L[start:stop:step])
+
def test_main():
test_support.run_unittest(StructSeqTest)
Modified: python/branches/p3yk-noslice/Lib/test/test_userstring.py
==============================================================================
--- python/branches/p3yk-noslice/Lib/test/test_userstring.py (original)
+++ python/branches/p3yk-noslice/Lib/test/test_userstring.py Sat Dec 16 10:01:33 2006
@@ -3,6 +3,7 @@
# UserString instances should behave similar to builtin string objects.
import unittest
+import string
from test import test_support, string_tests
from UserString import UserString, MutableString
@@ -88,6 +89,28 @@
del s[-1:10]
self.assertEqual(s, "fo")
+ def test_extended_set_del_slice(self):
+ indices = (0, None, 1, 3, 19, 100, -1, -2, -31, -100)
+ orig = string.ascii_letters + string.digits
+ for start in indices:
+ for stop in indices:
+ # Use indices[1:] when MutableString can handle real
+ # extended slices
+ for step in (None, 1, -1):
+ s = self.type2test(orig)
+ L = list(orig)
+ # Make sure we have a slice of exactly the right length,
+ # but with (hopefully) different data.
+ data = L[start:stop:step]
+ data.reverse()
+ L[start:stop:step] = data
+ s[start:stop:step] = "".join(data)
+ self.assertEquals(s, "".join(L))
+
+ del L[start:stop:step]
+ del s[start:stop:step]
+ self.assertEquals(s, "".join(L))
+
def test_immutable(self):
s = self.type2test("foobar")
s2 = s.immutable()
Modified: python/branches/p3yk-noslice/TODO
==============================================================================
--- python/branches/p3yk-noslice/TODO (original)
+++ python/branches/p3yk-noslice/TODO Sat Dec 16 10:01:33 2006
@@ -2,15 +2,14 @@
TODO in slice removal:
- Clean up compilerpackage's code now that SLICE opcodes are gone
- - Add tests for the extended slicing abilities of:
- buffer
- mmap.mmap
- structseq
- - Add actual *extended* slicing to ctypes objects
+ - Add non-step-1 slicing to ctypes objects
+ - Add non-step-1 slice assignment to UserString.MutableString
- Make list's mp_[ass_]subscr not depend on list_[ass]slice
- Remove slice API (or emulate it ontop of sliceobject API)
- Further remove slice/ass_slice PySequenceMethod hooks
- Figure out what to do with PyMapping_Check (it uses the presence of the
classic slicing hook to tell sequences-with-extended-slicing from
mappings.)
-
+ - Refactor slice handling logic from all the sequency types into a single
+ location? Might need some funky macros to make work...
+ - Submit type enhancements to trunk, rest to p3yk
More information about the Python-checkins
mailing list