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

Reply via email to