Author: Carl Friedrich Bolz-Tereick <[email protected]>
Branch: expose-jsonmap
Changeset: r97945:35f2d7155ef8
Date: 2019-11-03 14:45 +0100
http://bitbucket.org/pypy/pypy/changeset/35f2d7155ef8/
Log: switch away from the jsondict strategy if the map is blocked
diff --git a/pypy/objspace/std/jsondict.py b/pypy/objspace/std/jsondict.py
--- a/pypy/objspace/std/jsondict.py
+++ b/pypy/objspace/std/jsondict.py
@@ -55,12 +55,18 @@
def is_correct_type(self, w_obj):
space = self.space
- return space.is_w(space.type(w_obj), space.w_unicode)
+ # This is a bit of a hack (but probably a good one): when the state of
+ # our jsonmap is blocked, we consider nothing to match type-wise. That
+ # way we use the code paths that switch us to a different strategy.
+ return space.is_w(space.type(w_obj), space.w_unicode) and not
self.jsonmap.is_state_blocked()
def _never_equal_to(self, w_lookup_type):
return False
def length(self, w_dict):
+ if self.jsonmap.is_state_blocked():
+ self.switch_to_unicode_strategy(w_dict)
+ return w_dict.length()
return len(self.unerase(w_dict.dstorage))
def getitem(self, w_dict, w_key):
@@ -81,6 +87,8 @@
def setitem(self, w_dict, w_key, w_value):
if self.is_correct_type(w_key):
+ if jit.isconstant(w_key):
+ jit.promote(self)
storage_w = self.unerase(w_dict.dstorage)
index = self.jsonmap.get_index(w_key)
if index != -1:
diff --git a/pypy/objspace/std/test/test_jsondict.py
b/pypy/objspace/std/test/test_jsondict.py
--- a/pypy/objspace/std/test/test_jsondict.py
+++ b/pypy/objspace/std/test/test_jsondict.py
@@ -111,3 +111,64 @@
str(d)
repr(d)
+
+class TestJsonDictBlockedJsonMap(object):
+ def make_jsondict(self):
+ from pypy.module._pypyjson import interp_decoder
+ from pypy.objspace.std.jsondict import from_values_and_jsonmap
+ space = self.space
+ w_a = self.space.newutf8("a", 1)
+ w_b = self.space.newutf8("b", 1)
+ base = interp_decoder.Terminator(space)
+ m1 = base.get_next(w_a, 'a"', 0, 2, base)
+ m2 = m1.get_next(w_b, 'b"', 0, 2, base)
+
+ w_d = from_values_and_jsonmap(space, [w_a, w_b], m2)
+ return base, m2, w_d, w_a, w_b
+
+ def test_getitem(self):
+ space = self.space
+ base, m2, w_d, w_a, w_b = self.make_jsondict()
+ assert space.getitem(w_d, w_a) is w_a
+ assert space.getitem(w_d, w_b) is w_b
+
+ m2.mark_blocked(base)
+ # accessing a dict with a blocked strategy will switch to
+ # UnicodeDictStrategy
+ assert w_d.dstrategy is m2.strategy_instance
+ assert space.getitem(w_d, w_a) is w_a
+ assert space.getitem(w_d, w_b) is w_b
+ assert w_d.dstrategy is not m2.strategy_instance
+
+ def test_setitem(self):
+ space = self.space
+ base, m2, w_d, w_a, w_b = self.make_jsondict()
+ space.setitem(w_d, w_a, w_b)
+ space.setitem(w_d, w_b, w_a)
+
+ m2.mark_blocked(base)
+ assert w_d.dstrategy is m2.strategy_instance
+ space.setitem(w_d, w_a, w_b)
+ space.setitem(w_d, w_b, w_a)
+ assert w_d.dstrategy is not m2.strategy_instance
+
+ def test_len(self):
+ space = self.space
+ base, m2, w_d, w_a, w_b = self.make_jsondict()
+ assert space.len_w(w_d) == 2
+
+ m2.mark_blocked(base)
+ assert w_d.dstrategy is m2.strategy_instance
+ assert space.len_w(w_d) == 2
+ assert w_d.dstrategy is not m2.strategy_instance
+
+ def test_setdefault(self):
+ base, m2, w_d, w_a, w_b = self.make_jsondict()
+ assert w_d.setdefault(w_a, None) is w_a
+ assert w_d.setdefault(w_b, None) is w_b
+
+ m2.mark_blocked(base)
+ assert w_d.dstrategy is m2.strategy_instance
+ assert w_d.setdefault(w_a, None) is w_a
+ assert w_d.setdefault(w_b, None) is w_b
+ assert w_d.dstrategy is not m2.strategy_instance
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit