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