[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