[pypy-svn] r11540 - in pypy/dist/pypy/objspace: . test

arigo at codespeak.net arigo at codespeak.net
Wed Apr 27 18:55:56 CEST 2005


Author: arigo
Date: Wed Apr 27 18:55:56 2005
New Revision: 11540

Modified:
   pypy/dist/pypy/objspace/descroperation.py
   pypy/dist/pypy/objspace/test/test_descroperation.py
Log:
More __getslice__() support.


Modified: pypy/dist/pypy/objspace/descroperation.py
==============================================================================
--- pypy/dist/pypy/objspace/descroperation.py	(original)
+++ pypy/dist/pypy/objspace/descroperation.py	Wed Apr 27 18:55:56 2005
@@ -180,13 +180,20 @@
                    space.wrap("iterator has no next() method"))
         return space.get_and_call_function(w_descr, w_obj)
 
-    def _oldstyle_slice_range(space, w_key):
+    def _oldstyle_slice_range(space, w_obj, w_key):
         w_start = space.getattr(w_key, space.wrap('start'))
         w_stop  = space.getattr(w_key, space.wrap('stop'))
         if space.is_w(w_start, space.w_None):
             w_start = space.wrap(0)
+        elif space.is_true(space.lt(w_start, space.wrap(0))):
+            w_start = space.add(w_start, space.len(w_obj))
+            # NB. the language ref is inconsistent with the new-style class
+            # behavior when w_obj doesn't implement __len__(), so we just
+            # ignore this case.
         if space.is_w(w_stop, space.w_None):
             w_stop = space.wrap(sys.maxint)
+        elif space.is_true(space.lt(w_stop, space.wrap(0))):
+            w_stop = space.add(w_stop, space.len(w_obj))
         return w_start, w_stop
 
     def getitem(space, w_obj, w_key):
@@ -194,7 +201,7 @@
             if space.is_w(space.getattr(w_key, space.wrap('step')), space.w_None):
                 w_descr = space.lookup(w_obj, '__getslice__')
                 if w_descr is not None:
-                    w_start, w_stop = space._oldstyle_slice_range(w_key)
+                    w_start, w_stop = space._oldstyle_slice_range(w_obj, w_key)
                     return space.get_and_call_function(w_descr, w_obj,
                                                        w_start, w_stop)
         w_descr = space.lookup(w_obj, '__getitem__')
@@ -208,7 +215,7 @@
             if space.is_w(space.getattr(w_key, space.wrap('step')), space.w_None):
                 w_descr = space.lookup(w_obj, '__setslice__')
                 if w_descr is not None:
-                    w_start, w_stop = space._oldstyle_slice_range(w_key)
+                    w_start, w_stop = space._oldstyle_slice_range(w_obj, w_key)
                     return space.get_and_call_function(w_descr, w_obj,
                                                        w_start, w_stop,
                                                        w_val)                    
@@ -223,7 +230,7 @@
             if space.is_w(space.getattr(w_key, space.wrap('step')), space.w_None):
                 w_descr = space.lookup(w_obj, '__delslice__')
                 if w_descr is not None:
-                    w_start, w_stop = space._oldstyle_slice_range(w_key)
+                    w_start, w_stop = space._oldstyle_slice_range(w_obj, w_key)
                     return space.get_and_call_function(w_descr, w_obj,
                                                        w_start, w_stop)
         w_descr = space.lookup(w_obj, '__delitem__')

Modified: pypy/dist/pypy/objspace/test/test_descroperation.py
==============================================================================
--- pypy/dist/pypy/objspace/test/test_descroperation.py	(original)
+++ pypy/dist/pypy/objspace/test/test_descroperation.py	Wed Apr 27 18:55:56 2005
@@ -6,9 +6,10 @@
         class Sq(object):
             def __getslice__(self, start, stop):
                 return (start, stop)
-
             def __getitem__(self, key):
                 return "booh"
+            def __len__(self):
+                return 100
 
         sq = Sq()
 
@@ -17,14 +18,19 @@
         assert sq[1:] == (1, sys.maxint)
         assert sq[:3] == (0, 3)
         assert sq[:] == (0, sys.maxint)
+        # negative indices
+        assert sq[-1:3] == (99, 3)
+        assert sq[1:-3] == (1, 97)
+        assert sq[-1:-3] == (99, 97)
 
     def test_setslice(self):
         class Sq(object):
             def __setslice__(self, start, stop, sequence):
                 ops.append((start, stop, sequence))
-
             def __setitem__(self, key, value):
                 raise AssertionError, key
+            def __len__(self):
+                return 100
 
         sq = Sq()
         ops = []
@@ -35,9 +41,9 @@
 
         import sys
         assert ops == [
-            (-5, 3,          'hello'),
+            (95, 3,          'hello'),
             (12, sys.maxint, 'world'),
-            (0,  -1,         'spam'),
+            (0,  99,         'spam'),
             (0,  sys.maxint, 'egg'),
             ]
 
@@ -45,9 +51,10 @@
         class Sq(object):
             def __delslice__(self, start, stop):
                 ops.append((start, stop))
-
             def __delitem__(self, key):
                 raise AssertionError, key
+            def __len__(self):
+                return 100
 
         sq = Sq()
         ops = []
@@ -58,8 +65,8 @@
 
         import sys
         assert ops == [
-            (5,   -3),
-            (-12, sys.maxint),
+            (5,   97),
+            (88,  sys.maxint),
             (0,   1),
             (0,   sys.maxint),
             ]



More information about the Pypy-commit mailing list