Author: Lukas Diekmann <[email protected]>
Branch:
Changeset: r44443:e05258a73ff3
Date: 2011-04-06 18:34 +0200
http://bitbucket.org/pypy/pypy/changeset/e05258a73ff3/
Log: Fixed cpyext to work with W_SmallTupleObjects
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
@@ -5,6 +5,7 @@
from pypy.rpython.lltypesystem import rffi, lltype
class TestTupleObject(BaseApiTest):
+ #XXX these tests do not test both W_SmallTupleObject and W_TupleObject
def test_tupleobject(self, space, api):
assert not api.PyTuple_Check(space.w_None)
assert api.PyTuple_SetItem(space.w_None, 0, space.w_None) == -1
@@ -20,11 +21,11 @@
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
+ assert space.int_w(space.len(py_tuple)) == 2
api._PyTuple_Resize(ar, 10)
py_tuple = from_ref(space, ar[0])
- assert len(py_tuple.wrappeditems) == 10
+ assert space.int_w(space.len(py_tuple)) == 10
api.Py_DecRef(ar[0])
lltype.free(ar, flavor='raw')
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
@@ -19,25 +19,28 @@
if not PyTuple_Check(space, w_t):
# XXX this should also steal a reference, test it!!!
PyErr_BadInternalCall(space)
- assert isinstance(w_t, W_TupleObject)
- w_t.wrappeditems[pos] = w_obj
+ _setitem_tuple(w_t, pos, w_obj)
Py_DecRef(space, w_obj) # SetItem steals a reference!
return 0
+def _setitem_tuple(w_t, pos, w_obj):
+ if isinstance(w_t, W_TupleObject):
+ w_t.wrappeditems[pos] = w_obj
+ elif isinstance(w_t, W_SmallTupleObject):
+ w_t.setitem(pos, w_obj)
+
@cpython_api([PyObject, Py_ssize_t], PyObject)
def PyTuple_GetItem(space, w_t, pos):
if not PyTuple_Check(space, w_t):
PyErr_BadInternalCall(space)
- assert isinstance(w_t, W_TupleObject)
- w_obj = w_t.wrappeditems[pos]
+ w_obj = space.getitem(w_t, space.wrap(pos))
return borrow_from(w_t, w_obj)
@cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL)
def PyTuple_GET_SIZE(space, w_t):
"""Return the size of the tuple p, which must be non-NULL and point to a
tuple;
no error checking is performed. """
- assert isinstance(w_t, W_TupleObject)
- return len(w_t.wrappeditems)
+ return space.int_w(space.len(w_t))
@cpython_api([PyObject], Py_ssize_t, error=-1)
def PyTuple_Size(space, ref):
@@ -63,15 +66,14 @@
py_tuple = from_ref(space, ref[0])
if not PyTuple_Check(space, py_tuple):
PyErr_BadInternalCall(space)
- assert isinstance(py_tuple, W_TupleObject)
py_newtuple = PyTuple_New(space, newsize)
to_cp = newsize
- oldsize = len(py_tuple.wrappeditems)
+ oldsize = space.int_w(space.len(py_tuple))
if oldsize < newsize:
to_cp = oldsize
for i in range(to_cp):
- py_newtuple.wrappeditems[i] = py_tuple.wrappeditems[i]
+ _setitem_tuple(py_newtuple, i, space.getitem(py_tuple, space.wrap(i)))
Py_DecRef(space, ref[0])
ref[0] = make_ref(space, py_newtuple)
return 0
diff --git a/pypy/objspace/std/smalltupleobject.py
b/pypy/objspace/std/smalltupleobject.py
--- a/pypy/objspace/std/smalltupleobject.py
+++ b/pypy/objspace/std/smalltupleobject.py
@@ -29,6 +29,9 @@
def eq(self, space, w_other):
raise NotImplementedError
+ def setitem(self, index, w_item):
+ raise NotImplementedError
+
def make_specialized_class(n):
iter_n = unrolling_iterable(range(n))
class cls(W_SmallTupleObject):
@@ -53,6 +56,13 @@
return getattr(self,'w_value%s' % i)
raise IndexError
+ def setitem(self, index, w_item):
+ for i in iter_n:
+ if index == i:
+ setattr(self, 'w_value%s' % i, w_item)
+ return
+ raise IndexError
+
def eq(self, space, w_other):
if self.length() != w_other.length():
return space.w_False
diff --git a/pypy/objspace/std/test/test_smalltupleobject.py
b/pypy/objspace/std/test/test_smalltupleobject.py
--- a/pypy/objspace/std/test/test_smalltupleobject.py
+++ b/pypy/objspace/std/test/test_smalltupleobject.py
@@ -76,3 +76,11 @@
assert not normalspace.is_true(normalspace.eq(w_tuple, w_smalltuple))
assert smallspace.is_true(smallspace.eq(w_tuple, w_smalltuple))
assert smallspace.is_true(smallspace.eq(normalspace.hash(w_tuple),
smallspace.hash(w_smalltuple)))
+
+ def test_setitem(self):
+ w_smalltuple = self.space.newtuple([self.space.wrap(1),
self.space.wrap(2)])
+ w_smalltuple.setitem(0, self.space.wrap(5))
+ list_w = w_smalltuple.tolist()
+ assert len(list_w) == 2
+ assert self.space.eq_w(list_w[0], self.space.wrap(5))
+ assert self.space.eq_w(list_w[1], self.space.wrap(2))
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit