[pypy-svn] pypy default: (kleptog) Implement PySlice_GetIndices()

amauryfa commits-noreply at bitbucket.org
Sat Feb 26 23:28:44 CET 2011


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: 
Changeset: r42311:443ddfc7ee63
Date: 2011-02-26 23:26 +0100
http://bitbucket.org/pypy/pypy/changeset/443ddfc7ee63/

Log:	(kleptog) Implement PySlice_GetIndices()

diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py
--- a/pypy/module/cpyext/stubs.py
+++ b/pypy/module/cpyext/stubs.py
@@ -2157,26 +2157,6 @@
     """Empty an existing set of all elements."""
     raise NotImplementedError
 
- at cpython_api([PyObject, Py_ssize_t, Py_ssize_t, Py_ssize_t, Py_ssize_t], rffi.INT_real, error=-1)
-def PySlice_GetIndices(space, slice, length, start, stop, step):
-    """Retrieve the start, stop and step indices from the slice object slice,
-    assuming a sequence of length length. Treats indices greater than
-    length as errors.
-    
-    Returns 0 on success and -1 on error with no exception set (unless one of
-    the indices was not None and failed to be converted to an integer,
-    in which case -1 is returned with an exception set).
-    
-    You probably do not want to use this function.  If you want to use slice
-    objects in versions of Python prior to 2.3, you would probably do well to
-    incorporate the source of PySlice_GetIndicesEx(), suitably renamed,
-    in the source of your extension.
-    
-    This function used an int type for length and an
-    int * type for start, stop, and step. This might require
-    changes in your code for properly supporting 64-bit systems."""
-    raise NotImplementedError
-
 @cpython_api([PyObjectP], lltype.Void)
 def PyString_InternInPlace(space, string):
     """Intern the argument *string in place.  The argument must be the address of a

diff --git a/pypy/module/cpyext/test/test_sliceobject.py b/pypy/module/cpyext/test/test_sliceobject.py
--- a/pypy/module/cpyext/test/test_sliceobject.py
+++ b/pypy/module/cpyext/test/test_sliceobject.py
@@ -26,6 +26,21 @@
             return rv
         assert get_indices(w(10), w(20), w(1), 200) == (10, 20, 1, 10)
 
+    def test_GetIndices(self, space, api):
+        w = space.wrap
+        def get_indices(w_start, w_stop, w_step, length):
+            w_slice = space.newslice(w_start, w_stop, w_step)
+            values = lltype.malloc(Py_ssize_tP.TO, 3, flavor='raw')
+            
+            res = api.PySlice_GetIndices(w_slice, 100, values, 
+                rffi.ptradd(values, 1), 
+                rffi.ptradd(values, 2))
+            assert res == 0
+            rv = values[0], values[1], values[2]
+            lltype.free(values, flavor='raw')
+            return rv
+        assert get_indices(w(10), w(20), w(1), 200) == (10, 20, 1)
+
 class AppTestSliceMembers(AppTestCpythonExtensionBase):
     def test_members(self):
         module = self.import_extension('foo', [

diff --git a/pypy/module/cpyext/sliceobject.py b/pypy/module/cpyext/sliceobject.py
--- a/pypy/module/cpyext/sliceobject.py
+++ b/pypy/module/cpyext/sliceobject.py
@@ -81,3 +81,29 @@
     start_p[0], stop_p[0], step_p[0], slicelength_p[0] = \
             w_slice.indices4(space, length)
     return 0
+
+ at cpython_api([PySliceObject, Py_ssize_t, Py_ssize_tP, Py_ssize_tP, Py_ssize_tP],
+                rffi.INT_real, error=-1)
+def PySlice_GetIndices(space, w_slice, length, start_p, stop_p, step_p):
+    """Retrieve the start, stop and step indices from the slice object slice,
+    assuming a sequence of length length. Treats indices greater than
+    length as errors.
+    
+    Returns 0 on success and -1 on error with no exception set (unless one of
+    the indices was not None and failed to be converted to an integer,
+    in which case -1 is returned with an exception set).
+    
+    You probably do not want to use this function.  If you want to use slice
+    objects in versions of Python prior to 2.3, you would probably do well to
+    incorporate the source of PySlice_GetIndicesEx(), suitably renamed,
+    in the source of your extension.
+    
+    This function used an int type for length and an
+    int * type for start, stop, and step. This might require
+    changes in your code for properly supporting 64-bit systems."""
+    if not PySlice_Check(space, w_slice):
+        PyErr_BadInternalCall(space)
+    assert isinstance(w_slice, W_SliceObject)
+    start_p[0], stop_p[0], step_p[0] = \
+            w_slice.indices3(space, length)
+    return 0


More information about the Pypy-commit mailing list