[pypy-commit] pypy reorder-map-attributes: (cfbolz, jbs): fixed error with inserting two attributes without reordering

jbs pypy.commits at gmail.com
Fri Feb 12 07:40:06 EST 2016


Author: Jasper.Schulz <jasper.b.schulz at gmail.com>
Branch: reorder-map-attributes
Changeset: r82177:bf4e8b1d6198
Date: 2016-02-12 12:39 +0000
http://bitbucket.org/pypy/pypy/changeset/bf4e8b1d6198/

Log:	(cfbolz, jbs): fixed error with inserting two attributes without
	reordering

diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py
--- a/pypy/objspace/std/mapdict.py
+++ b/pypy/objspace/std/mapdict.py
@@ -20,7 +20,6 @@
 # note: we use "x * NUM_DIGITS_POW2" instead of "x << NUM_DIGITS" because
 # we want to propagate knowledge that the result cannot be negative
 
-NOT_REORDERED, JUST_REORDERED, SOMEWHERE_REORDERED = range(3)
 
 class AbstractAttribute(object):
     _immutable_fields_ = ['terminator']
@@ -221,21 +220,22 @@
                 else:
                     attr._switch_map_and_write_storage(obj, w_value)
                     stack_index = localstack_index
+                    
+                    if not stack_index:
+                        return
+                    
+                    # add the first attribute of the stack without reordering
+                    # to prevent an endless loop
+                    stack_index += -1
+                    next_map = stack_maps[stack_index]
+                    w_value = stack_values[stack_index]
+                    obj._get_mapdict_map()._add_attr_without_reordering(
+                        obj, next_map.name, next_map.index, w_value)
+
                     break
 
             if not stack_index:
                 return
-            
-            # add the first attribute of the stack without reordering
-            # to prevent an endless loop
-            stack_index += -1
-            next_map = stack_maps[stack_index]
-            w_value = stack_values[stack_index]
-            obj._get_mapdict_map()._add_attr_without_reordering(
-                obj, next_map.name, next_map.index, w_value)
-
-            if not stack_index:
-                return
 
             # readd all other values from the stack (with reordering)
             # the last element of the stack will be the new current
diff --git a/pypy/objspace/std/test/test_mapdict.py b/pypy/objspace/std/test/test_mapdict.py
--- a/pypy/objspace/std/test/test_mapdict.py
+++ b/pypy/objspace/std/test/test_mapdict.py
@@ -171,6 +171,23 @@
     assert obj.map is obj5.map
     assert obj.map is obj6.map
 
+def test_insert_different_orders_4():
+    cls = Class()
+    obj = cls.instantiate()
+    obj2 = cls.instantiate()
+    
+    obj.setdictvalue(space, "a", 10)
+    obj.setdictvalue(space, "b", 20)
+    obj.setdictvalue(space, "c", 30)
+    obj.setdictvalue(space, "d", 40)
+
+    obj2.setdictvalue(space, "d", 50)
+    obj2.setdictvalue(space, "c", 50)
+    obj2.setdictvalue(space, "b", 50)
+    obj2.setdictvalue(space, "a", 50)
+
+    assert obj.map is obj2.map
+
 def test_bug_stack_overflow_insert_attributes():
     cls = Class()
     obj = cls.instantiate()
@@ -182,16 +199,20 @@
     from itertools import permutations
     cls = Class()
     seen_maps = {}
-    for i, attributes in enumerate(permutations("abcdef")):
-        obj = cls.instantiate()
-        key = ""
-        for j, attr in enumerate(attributes):
-            obj.setdictvalue(space, attr, i*10+j)
-            key = "".join(sorted(key+attr))
-            if key in seen_maps:
-                assert obj.map is seen_maps[key]
-            else:
-                seen_maps[key] = obj.map
+    for preexisting in ['', 'x', 'xy']:
+        for i, attributes in enumerate(permutations("abcdef")):
+            obj = cls.instantiate()
+            for i, attr in enumerate(preexisting):
+                obj.setdictvalue(space, attr, i*1000)
+            key = preexisting
+            for j, attr in enumerate(attributes):
+                obj.setdictvalue(space, attr, i*10+j)
+                key = "".join(sorted(key+attr))
+                if key in seen_maps:
+                    assert obj.map is seen_maps[key]
+                else:
+                    seen_maps[key] = obj.map
+
     print len(seen_maps)
 
 def test_attr_immutability(monkeypatch):


More information about the pypy-commit mailing list