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

elmom at codespeak.net elmom at codespeak.net
Wed Oct 17 21:44:11 CEST 2007


Author: elmom
Date: Wed Oct 17 21:44:10 2007
New Revision: 47520

Modified:
   pypy/dist/pypy/objspace/std/listmultiobject.py
   pypy/dist/pypy/objspace/std/test/test_listmultiobject.py
Log:
* This commit adds framework to test that the different list implementations
  are really used. I was prompted to add this since for a big part, the
  implementations weren't really used, propably to such extent that speed
  figures are affected at least a bit. IOW, after the included fixes,
  the implementations are even slower :).

* In this commit is also a little fix for a bug in the
  ChunkList impl. revealed by the added testing.

* Next I'll commit tests for the BList implementation...


Modified: pypy/dist/pypy/objspace/std/listmultiobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/listmultiobject.py	(original)
+++ pypy/dist/pypy/objspace/std/listmultiobject.py	Wed Oct 17 21:44:10 2007
@@ -10,9 +10,9 @@
 
 # ListImplementations
 
-# An empty list always is an EmptyListImplementation.
+# An empty list is always an EmptyListImplementation.
 #
-# RDictImplementation -- standard implementation
+# RListImplementation -- standard implementation
 # StrListImplementation -- lists consisting only of strings
 # ChunkedListImplementation -- when having set the withchunklist option
 # SmartResizableListImplementation -- when having set the
@@ -87,7 +87,7 @@
         for i in range(slicelength):
             res_w[i] = self.getitem(start)
             start += step
-        return RListImplementation(self.space, res_w)
+        return make_implementation(self.space, res_w)
 
     def delitem_slice_step(self, start, stop, step, slicelength):
         n = self.length()
@@ -368,8 +368,8 @@
         length = self._length
 
         self._grow()
-        for j in range(length - 1, 0, -1):
-            self.setitem(j + 1, self.getitem(j))
+        for j in range(length, i, -1):
+            self.setitem(j, self.getitem(j-1))
         self.setitem(i, w_item)
 
         return self
@@ -399,13 +399,7 @@
 class EmptyListImplementation(ListImplementation):
     def make_list_with_one_item(self, w_item):
         space = self.space
-        if space.config.objspace.std.withfastslice:
-            return SliceTrackingListImplementation(space, [w_item])
-        w_type = space.type(w_item)
-        if space.is_w(w_type, space.w_str):
-            strlist = [space.str_w(w_item)]
-            return StrListImplementation(space, strlist)
-        return RListImplementation(space, [w_item])
+        return make_implementation_with_one_item(space, w_item)
 
     def length(self):
         return 0
@@ -834,6 +828,23 @@
         else:
             return RListImplementation(space, list_w)
 
+def make_implementation_with_one_item(space, w_item):
+        if space.config.objspace.std.withfastslice:
+            return SliceTrackingListImplementation(space, [w_item])
+        if space.config.objspace.std.withsmartresizablelist:
+            from pypy.objspace.std.smartresizablelist import \
+                SmartResizableListImplementation
+            impl = SmartResizableListImplementation(space)
+            impl.append(w_item)
+            return impl
+        if space.config.objspace.std.withchunklist:
+            return ChunkedListImplementation(space, [w_item])
+        w_type = space.type(w_item)
+        if space.is_w(w_type, space.w_str):
+            strlist = [space.str_w(w_item)]
+            return StrListImplementation(space, strlist)
+        return RListImplementation(space, [w_item])
+
 def convert_list_w(space, list_w):
     if not list_w:
         impl = space.fromcache(State).empty_impl
@@ -884,7 +895,7 @@
     if w_iterable is not EMPTY_LIST:
         list_w = space.unpackiterable(w_iterable)
         if list_w:
-            w_list.implementation = RListImplementation(space, list_w)
+            w_list.implementation = make_implementation(space, list_w)
             return
     w_list.implementation = space.fromcache(State).empty_impl
 
@@ -1304,9 +1315,8 @@
             sorterclass = CustomKeySort
         else: 
             sorterclass = SimpleSort
-    impl = w_list.implementation.to_rlist()
-    w_list.implementation = impl
-    items = impl.list_w
+    impl=w_list.implementation
+    items = impl.get_list_w()
     sorter = sorterclass(items, impl.length())
     sorter.space = space
     sorter.w_cmp = w_cmp
@@ -1349,8 +1359,7 @@
         mucked = w_list.implementation.length() > 0
 
         # put the items back into the list
-        impl.list_w = sorter.list
-        w_list.implementation = impl
+        w_list.implementation = make_implementation(space, sorter.list)
 
     if mucked:
         raise OperationError(space.w_ValueError,

Modified: pypy/dist/pypy/objspace/std/test/test_listmultiobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_listmultiobject.py	(original)
+++ pypy/dist/pypy/objspace/std/test/test_listmultiobject.py	Wed Oct 17 21:44:10 2007
@@ -2,13 +2,51 @@
 from pypy.objspace.std.listmultiobject import W_ListMultiObject, \
     SliceTrackingListImplementation
 from pypy.conftest import gettestobjspace
-from pypy.objspace.std.test import test_listobject
+from pypy.objspace.std.test.test_listobject import AppTestW_ListObject
 from pypy.objspace.std.test.test_dictmultiobject import FakeSpace
 from pypy.objspace.std.test.test_rangeobject import AppTestRangeListObject
 
-class AppTest_ListMultiObject(test_listobject.AppTestW_ListObject):
+class BaseAppTest_ListMultiObject(AppTestW_ListObject):
+
     def setup_class(cls):
-        cls.space = gettestobjspace(**{"objspace.std.withmultilist": True})
+        self._setup_class(cls)
+
+    @staticmethod
+    def _setup_class(cls, conf_switch='withmultilist', impl_tag=''):
+        cls.space = gettestobjspace(**{"objspace.std."+conf_switch: True})
+        cls.w_impl_used = cls.space.appexec([cls.space.wrap(impl_tag)],
+                                            """(impl_tag):
+            import __pypy__
+            def impl_used(obj, tag=''):
+                if not tag:
+                    if impl_tag:
+                        tag=impl_tag
+                    else:
+                        #import py.test
+                        #py.test.skip('test not enabled (impl_tag not set)')
+                        return True #XXX This hack because the above
+                                    #    doesn't work...
+                return tag in __pypy__.internal_repr(obj)
+            return impl_used
+        """)
+        
+    def test_implementation_is_used(self):
+        l = ["1", "2", "3", "4", "5"]
+        assert self.impl_used(l)
+        l = list(["1", "2", "3", "4", "5"])
+        assert self.impl_used(l)
+        l=[]
+        l.append('a')
+        assert self.impl_used(l)
+        l = ["6", "8", "3", "1", "5"]
+        l.sort()
+        assert self.impl_used(l)
+        # These few here ^ would fail before, but for good coverage,
+        # all the list methods etc. should be tested also...
+
+class AppTest_ListMultiObject(BaseAppTest_ListMultiObject):
+    def setup_class(cls):
+        BaseAppTest_ListMultiObject._setup_class(cls)
 
     def test_slice_with_step(self):
         l = range(20)
@@ -17,9 +55,8 @@
         assert l2 == range(1, 19, 2)
 
     def test_strlist_literal(self):
-        import __pypy__
         l = ["1", "2", "3", "4", "5"]
-        assert "StrListImplementation" in __pypy__.internal_repr(l)
+        assert self.impl_used(l, "StrListImplementation")
 
     def test_strlist_delitem(self):
         l = ["1", "2"]
@@ -27,14 +64,13 @@
         assert l == ["2"]
 
     def test_strlist_append(self):
-        import __pypy__
         l = []
         l.append("a")
-        assert "StrListImplementation" in __pypy__.internal_repr(l)
+        assert self.impl_used(l, "StrListImplementation")
         l.extend(["b", "c", "d"])
         l += ["e", "f"]
         assert l == ["a", "b", "c", "d", "e", "f"]
-        assert "StrListImplementation" in __pypy__.internal_repr(l)
+        assert self.impl_used(l, "StrListImplementation")
 
 class AppTestRangeImplementation(AppTestRangeListObject):
 
@@ -52,39 +88,36 @@
         pass # won't work with multilists
 
 
-class AppTest_FastSlice(test_listobject.AppTestW_ListObject):
+class AppTest_FastSlice(BaseAppTest_ListMultiObject):
     def setup_class(cls):
-        cls.space = gettestobjspace(**{"objspace.std.withfastslice": True})
+        BaseAppTest_ListMultiObject._setup_class(cls, 'withfastslice')
 
     def test_lazy_slice(self):
-        import __pypy__
         l = [i for i in range(100)] # force it to not be a range impl
         l2 = l[1:-1]
-        assert "SliceTrackingListImplementation" in __pypy__.internal_repr(l)
-        assert "SliceListImplementation" in __pypy__.internal_repr(l2)
+        assert self.impl_used(l, "SliceTrackingListImplementation")
+        assert self.impl_used(l2, "SliceListImplementation")
         result = 0
         for i in l2:
             result += i
         # didn't force l2
-        assert "SliceListImplementation" in __pypy__.internal_repr(l2)
+        assert self.impl_used(l2, "SliceListImplementation")
         # force l2:
         l2.append(10)
         assert l2 == range(1, 99) + [10]
 
     def test_append_extend_dont_force(self):
-        import __pypy__
         l = [i for i in range(100)] # force it to not be a range impl
         l2 = l[1:-1]
-        assert "SliceTrackingListImplementation" in __pypy__.internal_repr(l)
-        assert "SliceListImplementation" in __pypy__.internal_repr(l2)
+        assert self.impl_used(l, "SliceTrackingListImplementation")
+        assert self.impl_used(l2, "SliceListImplementation")
         l.append(100)
         l.extend(range(101, 110))
         assert l == range(110)
-        assert "SliceTrackingListImplementation" in __pypy__.internal_repr(l)
-        assert "SliceListImplementation" in __pypy__.internal_repr(l2)
+        assert self.impl_used(l, "SliceTrackingListImplementation")
+        assert self.impl_used(l2, "SliceListImplementation")
 
     def test_slice_of_slice(self):
-        import __pypy__
         l = [i for i in range(100)] # force it to not be a range impl
         l2 = l[1:-1]
         l3 = l2[1:-1]
@@ -92,17 +125,17 @@
         assert l2 == range(1, 99)
         assert l3 == range(2, 98)
         assert l4 == range(3, 97)
-        assert "SliceListImplementation" in __pypy__.internal_repr(l4)
+        assert self.impl_used(l4, "SliceListImplementation")
         l2[3] = 4
-        assert "SliceListImplementation" not in __pypy__.internal_repr(l2)
-        assert "SliceListImplementation" in __pypy__.internal_repr(l4)
+        assert not self.impl_used(l2, "SliceListImplementation")
+        assert self.impl_used(l4, "SliceListImplementation")
 
     def test_delitem_to_empty(self):
         import __pypy__
         l = [i for i in range(100)] # force it to not be a range impl
         l1 = l[1:-1]
         del l1[:]
-        assert "EmptyListImplementation" in __pypy__.internal_repr(l1)
+        assert self.impl_used(l1, "EmptyListImplementation")
 
 class TestSliceListImplementation(object):
     def setup_method(self,method):
@@ -119,10 +152,10 @@
         impl2 = impl2.setitem(2, 5)
         assert impl2.getitem(2) == 5
 
-class AppTest_SmartListObject(test_listobject.AppTestW_ListObject):
+class AppTest_SmartListObject(BaseAppTest_ListMultiObject):
     def setup_class(cls):
-        cls.space = gettestobjspace(**{
-            "objspace.std.withsmartresizablelist": True})
+        BaseAppTest_ListMultiObject._setup_class(cls, 'withsmartresizablelist',
+                                                 'SmartResizableList')
 
 
 def _set_chunk_size_bits(bits):
@@ -135,10 +168,11 @@
         return old_value
     return -1
 
-class AppTest_ChunkListObject(test_listobject.AppTestW_ListObject):
+class AppTest_ChunkListObject(BaseAppTest_ListMultiObject):
 
     def setup_class(cls):
-        cls.space = gettestobjspace(**{"objspace.std.withchunklist": True})
+        BaseAppTest_ListMultiObject._setup_class(cls, 'withchunklist',
+                                                 'ChunkedList')
         cls.chunk_size_bits = _set_chunk_size_bits(2)
 
     def teardown_class(cls):



More information about the Pypy-commit mailing list