Author: Armin Rigo <[email protected]>
Branch: cpyext-gc-support
Changeset: r80360:d6427723a4a6
Date: 2015-10-20 20:10 +0200
http://bitbucket.org/pypy/pypy/changeset/d6427723a4a6/
Log: finish tuples
diff --git a/pypy/module/cpyext/test/test_tupleobject.py
b/pypy/module/cpyext/test/test_tupleobject.py
--- a/pypy/module/cpyext/test/test_tupleobject.py
+++ b/pypy/module/cpyext/test/test_tupleobject.py
@@ -74,16 +74,16 @@
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))
+ ar[0] = py_tuple
api._PyTuple_Resize(ar, 2)
- py_tuple = from_ref(space, ar[0])
- assert space.int_w(space.len(py_tuple)) == 2
-
+ py_tuple = ar[0]
+ assert api.PyTuple_Size(py_tuple) == 2
+
api._PyTuple_Resize(ar, 10)
- py_tuple = from_ref(space, ar[0])
- assert space.int_w(space.len(py_tuple)) == 10
-
- api.Py_DecRef(ar[0])
+ py_tuple = ar[0]
+ assert api.PyTuple_Size(py_tuple) == 10
+
+ api.Py_DecRef(py_tuple)
lltype.free(ar, flavor='raw')
def test_getslice(self, space, api):
diff --git a/pypy/module/cpyext/tupleobject.py
b/pypy/module/cpyext/tupleobject.py
--- a/pypy/module/cpyext/tupleobject.py
+++ b/pypy/module/cpyext/tupleobject.py
@@ -69,7 +69,7 @@
py_tuple = new_pyobj(PyTupleObjectStruct, _PyTuple_Type(space), size)
for i in range(size):
py_tuple.c_ob_item[i] = lltype.nullptr(PyObject.TO)
- return py_tuple
+ return rffi.cast(PyObject, py_tuple)
@cpython_api([PyObject, Py_ssize_t, PyObject], rffi.INT_real, error=-1)
def PyTuple_SetItem(space, py_t, pos, py_obj):
@@ -108,7 +108,6 @@
@cpython_api([PyObjectP, Py_ssize_t], rffi.INT_real, error=-1)
def _PyTuple_Resize(space, ref, newsize):
- ZZZ
"""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
@@ -119,24 +118,29 @@
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])
- if not PyTuple_Check(space, py_tuple):
+ py_t = ref[0]
+ if not PyTuple_Check(space, py_t) or py_t.c_ob_refcnt != 1:
PyErr_BadInternalCall(space)
- py_newtuple = PyTuple_New(space, newsize)
-
- to_cp = newsize
- oldsize = space.int_w(space.len(py_tuple))
- if oldsize < newsize:
- to_cp = oldsize
- for i in range(to_cp):
- _setitem_tuple(py_newtuple, i, space.getitem(py_tuple, space.wrap(i)))
- Py_DecRef(space, ref[0])
- ref[0] = make_ref(space, py_newtuple)
+
+ py_oldtuple = rffi.cast(PyTupleObject, py_t)
+ py_newtuple = rffi.cast(PyTupleObject, PyTuple_New(space, newsize))
+
+ oldsize = py_oldtuple.c_ob_size
+ if oldsize > newsize:
+ to_copy = newsize
+ for i in range(to_copy, oldsize):
+ Py_DecRef(space, py_oldtuple.c_ob_item[i])
+ else:
+ to_copy = oldsize
+ for i in range(to_copy):
+ py_newtuple.c_ob_item[i] = py_oldtuple.c_ob_item[i]
+
+ ref[0] = rffi.cast(PyObject, py_newtuple)
+ Py_DecRef(space, py_oldtuple)
return 0
@cpython_api([PyObject, Py_ssize_t, Py_ssize_t], PyObject)
def PyTuple_GetSlice(space, w_obj, low, high):
- ZZZ
"""Take a slice of the tuple pointed to by p from low to high and return it
as a new tuple.
"""
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit