Author: Armin Rigo <[email protected]>
Branch:
Changeset: r90062:943aa7094f15
Date: 2017-02-12 09:46 +0100
http://bitbucket.org/pypy/pypy/changeset/943aa7094f15/
Log: dict.pop() on a key with a strange __eq__ could crash pypy
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
@@ -237,6 +237,14 @@
except KeyError:
space.raise_key_error(w_key)
+ def internal_delitem(self, w_key):
+ try:
+ self.delitem(w_key)
+ except KeyError:
+ raise oefmt(self.space.w_RuntimeError,
+ "an internal 'del' on the dictionary failed to find "
+ "the key")
+
def descr_reversed(self, space):
raise oefmt(space.w_TypeError,
"argument to reversed() must be a sequence")
@@ -369,7 +377,7 @@
else:
space.raise_key_error(w_key)
else:
- self.delitem(w_key)
+ self.internal_delitem(w_key)
return w_item
def descr_popitem(self, space):
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
@@ -735,6 +735,31 @@
setattr(a, s, 123)
assert holder.seen is s
+ def test_internal_delitem(self):
+ class K:
+ def __hash__(self):
+ return 42
+ def __eq__(self, other):
+ if is_equal[0]:
+ is_equal[0] -= 1
+ return True
+ return False
+ is_equal = [0]
+ k1 = K()
+ k2 = K()
+ d = {k1: 1, k2: 2}
+ k3 = K()
+ is_equal = [1]
+ try:
+ x = d.pop(k3)
+ except RuntimeError:
+ # This used to give a Fatal RPython error: KeyError.
+ # Now at least it should raise an app-level RuntimeError,
+ # or just work.
+ assert len(d) == 2
+ else:
+ assert (x == 1 or x == 2) and len(d) == 1
+
class AppTestDictViews:
def test_dictview(self):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit