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

Reply via email to