[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