[pypy-svn] r11717 - in pypy/dist/pypy/objspace/std: . test

arigo at codespeak.net arigo at codespeak.net
Sun May 1 19:56:09 CEST 2005


Author: arigo
Date: Sun May  1 19:56:09 2005
New Revision: 11717

Modified:
   pypy/dist/pypy/objspace/std/listobject.py
   pypy/dist/pypy/objspace/std/test/test_listobject.py
Log:
Try harder to keep to None all the items in lists after the ob_size.
This avoids unnecessary references kept around.


Modified: pypy/dist/pypy/objspace/std/listobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/listobject.py	(original)
+++ pypy/dist/pypy/objspace/std/listobject.py	Sun May  1 19:56:09 2005
@@ -288,14 +288,15 @@
         oldsize = w_list.ob_size
         delta = len2 - slicelength
         newsize = oldsize + delta
-        _list_resize(w_list, newsize)
-        w_list.ob_size = newsize
-        r = range(start+len2, newsize)
-        if delta > 0:
-            r.reverse()
-        items = w_list.ob_item
-        for i in r:
-            items[i] = items[i-delta]
+        if delta >= 0:
+            _list_resize(w_list, newsize)
+            w_list.ob_size = newsize
+            items = w_list.ob_item
+            for i in range(newsize-1, start+len2-1, -1):
+                items[i] = items[i-delta]
+        else:
+            # shrinking requires the careful memory management of _del_slice()
+            _del_slice(w_list, start, start-delta)
     elif len2 != slicelength:  # No resize for extended slices
         raise OperationError(space.w_ValueError, space.wrap("attempt to "
               "assign sequence of size %d to extended slice of size %d" %
@@ -453,7 +454,11 @@
     for i in range(ilow, w_list.ob_size - d):
         items[i] = items[i+d]
         items[i+d] = None
+    # make sure entries after ob_size-d are None, to avoid keeping references
+    # (the above loop already set to None all items[ilow+d:old_style])
     w_list.ob_size -= d
+    for i in range(w_list.ob_size, ilow + d):
+        items[i] = None
     # now we can destruct recycle safely, regardless of
     # side-effects to the list
     del recycle[:]

Modified: pypy/dist/pypy/objspace/std/test/test_listobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_listobject.py	(original)
+++ pypy/dist/pypy/objspace/std/test/test_listobject.py	Sun May  1 19:56:09 2005
@@ -266,6 +266,27 @@
         assert self.space.eq_w(self.space.le(w_list4, w_list3),
                            self.space.w_True)
 
+    def test_no_unneeded_refs(self):
+        space = self.space
+        w = space.wrap
+        w_empty = W_ListObject(space, [])
+
+        w_list = W_ListObject(space, [w(5), w(3), w(99)])
+        space.setitem(w_list, space.newslice(w(0), w(3), w(None)), w_empty)
+        assert w_list.ob_item == [None]*len(w_list.ob_item)
+
+        w_list = W_ListObject(space, [w(5), w(3), w(99)])
+        space.delitem(w_list, space.newslice(w(0), w(3), w(None)))
+        assert w_list.ob_item == [None]*len(w_list.ob_item)
+
+        w_list = W_ListObject(space, [w(5), w(3), w(99)])
+        space.call_method(w_list, 'pop')
+        assert w_list.ob_item[2] is None
+        space.call_method(w_list, 'pop')
+        assert w_list.ob_item[1] is None
+        space.call_method(w_list, 'pop')
+        assert w_list.ob_item == [None]*len(w_list.ob_item)
+
 class AppTestW_ListObject:
     def test_explicit_new_init(self):
         l = l0 = list.__new__(list)



More information about the Pypy-commit mailing list