Author: Carl Friedrich Bolz-Tereick <[email protected]>
Branch: 
Changeset: r94612:353420330f35
Date: 2018-05-18 10:10 +0200
http://bitbucket.org/pypy/pypy/changeset/353420330f35/

Log:    cleanup in dict implementation: don't use has_* flags, put fallback
        implementations into base methods instead

diff --git a/pypy/objspace/std/dictmultiobject.py 
b/pypy/objspace/std/dictmultiobject.py
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -270,13 +270,7 @@
         """Not exposed directly to app-level, but via __pypy__.reversed_dict().
         """
         strategy = self.get_strategy()
-        if strategy.has_iterreversed:
-            it = strategy.iterreversed(self)
-            return W_DictMultiIterKeysObject(space, it)
-        else:
-            # fall-back
-            w_keys = self.w_keys()
-            return space.call_method(w_keys, '__reversed__')
+        return strategy.iterreversed(self)
 
     def nondescr_delitem_if_value_is(self, space, w_key, w_value):
         """Not exposed directly to app-level, but used by
@@ -306,32 +300,7 @@
         """Not exposed directly to app-level, but via __pypy__.move_to_end().
         """
         strategy = self.get_strategy()
-        if strategy.has_move_to_end:
-            strategy.move_to_end(self, w_key, last_flag)
-        else:
-            # fall-back
-            w_value = self.getitem(w_key)
-            if w_value is None:
-                space.raise_key_error(w_key)
-            else:
-                self.internal_delitem(w_key)
-                if last_flag:
-                    self.setitem(w_key, w_value)
-                else:
-                    # *very slow* fall-back
-                    keys_w = []
-                    values_w = []
-                    iteratorimplementation = self.iteritems()
-                    while True:
-                        w_k, w_v = iteratorimplementation.next_item()
-                        if w_k is None:
-                            break
-                        keys_w.append(w_k)
-                        values_w.append(w_v)
-                    self.clear()
-                    self.setitem(w_key, w_value)
-                    for i in range(len(keys_w)):
-                        self.setitem(keys_w[i], values_w[i])
+        strategy.move_to_end(self, w_key, last_flag)
 
     def nondescr_popitem_first(self, space):
         """Not exposed directly to app-level, but via __pypy__.popitem_first().
@@ -358,21 +327,10 @@
         otherwise KeyError is raised
         """
         strategy = self.get_strategy()
-        if strategy.has_pop:
-            try:
-                return strategy.pop(self, w_key, w_default)
-            except KeyError:
-                raise space.raise_key_error(w_key)
-        # fall-back
-        w_item = self.getitem(w_key)
-        if w_item is None:
-            if w_default is not None:
-                return w_default
-            else:
-                space.raise_key_error(w_key)
-        else:
-            self.internal_delitem(w_key)
-            return w_item
+        try:
+            return strategy.pop(self, w_key, w_default)
+        except KeyError:
+            raise space.raise_key_error(w_key)
 
     def descr_popitem(self, space):
         """D.popitem() -> (k, v), remove and return some (key, value) pair as
@@ -612,7 +570,6 @@
         raise NotImplementedError
 
     has_iterreversed = False
-    has_move_to_end = False
     has_pop = False
     # ^^^ no default implementation available for these methods
 
@@ -627,6 +584,48 @@
     def prepare_update(self, w_dict, num_extra):
         pass
 
+    def move_to_end(self, w_dict, w_key, last_flag):
+        # fall-back
+        w_value = w_dict.getitem(w_key)
+        if w_value is None:
+            self.space.raise_key_error(w_key)
+        else:
+            w_dict.internal_delitem(w_key)
+            if last_flag:
+                w_dict.setitem(w_key, w_value)
+            else:
+                # *very slow* fall-back
+                keys_w = []
+                values_w = []
+                iteratorimplementation = w_dict.iteritems()
+                while True:
+                    w_k, w_v = iteratorimplementation.next_item()
+                    if w_k is None:
+                        break
+                    keys_w.append(w_k)
+                    values_w.append(w_v)
+                w_dict.clear()
+                w_dict.setitem(w_key, w_value)
+                for i in range(len(keys_w)):
+                    w_dict.setitem(keys_w[i], values_w[i])
+
+
+    def pop(self, w_dict, w_key, w_default):
+        # fall-back
+        w_item = w_dict.getitem(w_key)
+        if w_item is None:
+            if w_default is not None:
+                return w_default
+            else:
+                raise KeyError
+        else:
+            w_dict.internal_delitem(w_key)
+            return w_item
+
+    def iterreversed(self, w_dict):
+        # fall-back if getiterreversed is not present
+        w_keys = self.w_keys(w_dict)
+        return self.space.call_method(w_keys, '__reversed__')
 
 class EmptyDictStrategy(DictStrategy):
     erase, unerase = rerased.new_erasing_pair("empty")
@@ -724,6 +723,12 @@
     def view_as_kwargs(self, w_dict):
         return ([], [])
 
+    def move_to_end(self, w_dict, w_key, last_flag):
+        self.space.raise_key_error(w_key)
+
+    def pop(self, w_dict, w_key, w_default):
+        raise KeyError
+
     # ---------- iterator interface ----------------
 
     def getiterkeys(self, w_dict):
@@ -881,15 +886,10 @@
 
     if hasattr(dictimpl, 'getiterreversed'):
         def iterreversed(self, w_dict):
-            return IterClassReversed(self.space, self, w_dict)
+            return W_DictMultiIterKeysObject(
+                    self.space,
+                    IterClassReversed(self.space, self, w_dict))
         dictimpl.iterreversed = iterreversed
-        dictimpl.has_iterreversed = True
-
-    if hasattr(dictimpl, 'move_to_end'):
-        dictimpl.has_move_to_end = True
-
-    if hasattr(dictimpl, 'pop'):
-        dictimpl.has_pop = True
 
     @jit.look_inside_iff(lambda self, w_dict, w_updatedict:
                          w_dict_unrolling_heuristic(w_dict))
diff --git a/pypy/objspace/std/test/test_dictmultiobject.py 
b/pypy/objspace/std/test/test_dictmultiobject.py
--- a/pypy/objspace/std/test/test_dictmultiobject.py
+++ b/pypy/objspace/std/test/test_dictmultiobject.py
@@ -227,6 +227,26 @@
         raises(KeyError, d.pop, "abc")
         assert len(d) == 2
 
+    def test_pop_kwargs(self):
+        def kw(**d): return d
+        d = kw(o=2, t=4)
+        dd = d.copy()
+        result = dd.pop("o")
+        assert result == 2
+        assert len(dd) == 1
+        dd = d.copy()
+        result = dd.pop("o", 44)
+        assert result == 2
+        assert len(dd) == 1
+        result = dd.pop("o", 44)
+        assert result == 44
+        assert len(dd) == 1
+        raises(KeyError, dd.pop, "33")
+
+        assert d.pop("abc", None) is None
+        raises(KeyError, d.pop, "abc")
+        assert len(d) == 2
+
     def test_has_key(self):
         d = {1: 2, 3: 4}
         assert d.has_key(1)
@@ -262,7 +282,8 @@
 
     def test_reversed_dict(self):
         import __pypy__
-        for d in [{}, {1: 2, 3: 4, 5: 6}, {"a": 5, "b": 2, "c": 6}]:
+        def kw(**d): return d
+        for d in [{}, {1: 2, 3: 4, 5: 6}, {"a": 5, "b": 2, "c": 6}, kw(a=1, 
b=2)]:
             assert list(__pypy__.reversed_dict(d)) == d.keys()[::-1]
         raises(TypeError, __pypy__.reversed_dict, 42)
 
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to