Author: Jasper.Schulz <jasper.b.sch...@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): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit