[pypy-svn] r74479 - in pypy/trunk/pypy/module/cpyext: . test

agaynor at codespeak.net agaynor at codespeak.net
Tue May 11 11:46:58 CEST 2010


Author: agaynor
Date: Tue May 11 11:46:57 2010
New Revision: 74479

Modified:
   pypy/trunk/pypy/module/cpyext/stubs.py
   pypy/trunk/pypy/module/cpyext/test/test_tupleobject.py
   pypy/trunk/pypy/module/cpyext/tupleobject.py
Log:
Implement _PyTuple_Resize for cpyext.

Modified: pypy/trunk/pypy/module/cpyext/stubs.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/stubs.py	(original)
+++ pypy/trunk/pypy/module/cpyext/stubs.py	Tue May 11 11:46:57 2010
@@ -2997,25 +2997,6 @@
     changes in your code for properly supporting 64-bit systems."""
     raise NotImplementedError
 
- at cpython_api([PyObjectP, Py_ssize_t], rffi.INT_real, error=-1)
-def _PyTuple_Resize(space, p, newsize):
-    """Can be used to resize a tuple.  newsize will be the new length of the tuple.
-    Because tuples are supposed to be immutable, this should only be used if there
-    is only one reference to the object.  Do not use this if the tuple may already
-    be known to some other part of the code.  The tuple will always grow or shrink
-    at the end.  Think of this as destroying the old tuple and creating a new one,
-    only more efficiently.  Returns 0 on success. Client code should never
-    assume that the resulting value of *p will be the same as before calling
-    this function. If the object referenced by *p is replaced, the original
-    *p is destroyed.  On failure, returns -1 and sets *p to NULL, and
-    raises MemoryError or SystemError.
-    
-    Removed unused third parameter, last_is_sticky.
-    
-    This function used an int type for newsize. This might
-    require changes in your code for properly supporting 64-bit systems."""
-    raise NotImplementedError
-
 @cpython_api([], rffi.INT_real, error=CANNOT_FAIL)
 def PyTuple_ClearFreeList(space, ):
     """Clear the free list. Return the total number of freed items.

Modified: pypy/trunk/pypy/module/cpyext/test/test_tupleobject.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/test/test_tupleobject.py	(original)
+++ pypy/trunk/pypy/module/cpyext/test/test_tupleobject.py	Tue May 11 11:46:57 2010
@@ -1,6 +1,8 @@
 import py
 
+from pypy.module.cpyext.pyobject import PyObject, PyObjectP, make_ref, from_ref
 from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.rpython.lltypesystem import rffi, lltype
 
 class TestTupleObject(BaseApiTest):
     def test_tupleobject(self, space, api):
@@ -11,3 +13,18 @@
         assert api.PyTuple_GET_SIZE(atuple) == 3
         raises(TypeError, api.PyTuple_Size(space.newlist([])))
         api.PyErr_Clear()
+    
+    def test_tuple_resize(self, space, api):
+        py_tuple = api.PyTuple_New(3)
+        ar = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
+        ar[0] = rffi.cast(PyObject, make_ref(space, py_tuple))
+        api._PyTuple_Resize(ar, 2)
+        py_tuple = from_ref(space, ar[0])
+        assert len(py_tuple.wrappeditems) == 2
+        
+        api._PyTuple_Resize(ar, 10)
+        py_tuple = from_ref(space, ar[0])
+        assert len(py_tuple.wrappeditems) == 10
+        
+        api.Py_DecRef(ar[0])
+        lltype.free(ar, flavor='raw')

Modified: pypy/trunk/pypy/module/cpyext/tupleobject.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/tupleobject.py	(original)
+++ pypy/trunk/pypy/module/cpyext/tupleobject.py	Tue May 11 11:46:57 2010
@@ -2,7 +2,8 @@
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.module.cpyext.api import (cpython_api, Py_ssize_t, CANNOT_FAIL,
                                     build_type_checkers)
-from pypy.module.cpyext.pyobject import PyObject, Py_DecRef, borrow_from
+from pypy.module.cpyext.pyobject import (PyObject, PyObjectP, Py_DecRef,
+    borrow_from, make_ref, from_ref)
 from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
 from pypy.objspace.std.tupleobject import W_TupleObject
 
@@ -45,3 +46,29 @@
         raise OperationError(space.w_TypeError,
                              space.wrap("expected tuple object"))
     return PyTuple_GET_SIZE(space, ref)
+
+
+ at cpython_api([PyObjectP, Py_ssize_t], rffi.INT_real, error=-1)
+def _PyTuple_Resize(space, ref, newsize):
+    """Can be used to resize a tuple.  newsize will be the new length of the tuple.
+    Because tuples are supposed to be immutable, this should only be used if there
+    is only one reference to the object.  Do not use this if the tuple may already
+    be known to some other part of the code.  The tuple will always grow or shrink
+    at the end.  Think of this as destroying the old tuple and creating a new one,
+    only more efficiently.  Returns 0 on success. Client code should never
+    assume that the resulting value of *p will be the same as before calling
+    this function. If the object referenced by *p is replaced, the original
+    *p is destroyed.  On failure, returns -1 and sets *p to NULL, and
+    raises MemoryError or SystemError."""
+    py_tuple = from_ref(space, ref[0])
+    py_newtuple = PyTuple_New(space, newsize)
+    
+    to_cp = newsize
+    oldsize = len(py_tuple.wrappeditems)
+    if oldsize < newsize:
+        to_cp = oldsize
+    for i in range(to_cp):
+        py_newtuple.wrappeditems[i] = py_tuple.wrappeditems[i]
+    Py_DecRef(space, ref[0])
+    ref[0] = make_ref(space, py_newtuple)
+    return 0



More information about the Pypy-commit mailing list