[pypy-commit] pypy keys_with_hash: delitem_with_hash

arigo noreply at buildbot.pypy.org
Tue Sep 1 11:41:16 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: keys_with_hash
Changeset: r79343:f09d931056ab
Date: 2015-09-01 11:33 +0200
http://bitbucket.org/pypy/pypy/changeset/f09d931056ab/

Log:	delitem_with_hash

diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py
--- a/rpython/annotator/unaryop.py
+++ b/rpython/annotator/unaryop.py
@@ -479,6 +479,10 @@
         return pair(self, s_key).getitem()
     method_getitem_with_hash.can_only_throw = _dict_can_only_throw_keyerror
 
+    def method_delitem_with_hash(self, s_key, s_hash):
+        pair(self, s_key).delitem()
+    method_delitem_with_hash.can_only_throw = _dict_can_only_throw_keyerror
+
 @op.contains.register(SomeString)
 @op.contains.register(SomeUnicodeString)
 def contains_String(annotator, string, char):
diff --git a/rpython/rlib/objectmodel.py b/rpython/rlib/objectmodel.py
--- a/rpython/rlib/objectmodel.py
+++ b/rpython/rlib/objectmodel.py
@@ -833,6 +833,16 @@
         return d[key]
     return d.getitem_with_hash(key, h)
 
+ at specialize.call_location()
+def delitem_with_hash(d, key, h):
+    """Same as 'del d[key]'.  The extra argument is the hash.  Use this only
+    if you got the hash just now from some other ..._with_hash() function."""
+    if not we_are_translated():
+        assert _expected_hash(d, key) == h
+        del d[key]
+        return
+    d.delitem_with_hash(key, h)
+
 # ____________________________________________________________
 
 def import_from_mixin(M, special_methods=['__init__', '__del__']):
diff --git a/rpython/rlib/test/test_objectmodel.py b/rpython/rlib/test/test_objectmodel.py
--- a/rpython/rlib/test/test_objectmodel.py
+++ b/rpython/rlib/test/test_objectmodel.py
@@ -636,6 +636,21 @@
     res = interpret(f, [27])
     assert res == 42
 
+def test_delitem_with_hash():
+    def f(i):
+        d = {i+.5: 42, i+.6: -612}
+        delitem_with_hash(d, i+.5, compute_hash(i+.5))
+        try:
+            delitem_with_hash(d, i+.5, compute_hash(i+.5))
+        except KeyError:
+            pass
+        else:
+            raise AssertionError
+        return 0
+
+    f(29)
+    interpret(f, [27])
+
 def test_rdict_with_hash():
     def f(i):
         d = r_dict(strange_key_eq, strange_key_hash)
diff --git a/rpython/rtyper/lltypesystem/rordereddict.py b/rpython/rtyper/lltypesystem/rordereddict.py
--- a/rpython/rtyper/lltypesystem/rordereddict.py
+++ b/rpython/rtyper/lltypesystem/rordereddict.py
@@ -389,6 +389,14 @@
                                   v_dict, v_key, v_hash)
         return self.recast_value(hop.llops, v_res)
 
+    def rtype_method_delitem_with_hash(self, hop):
+        v_dict, v_key, v_hash = hop.inputargs(
+            self, self.key_repr, lltype.Signed)
+        if not self.custom_eq_hash:
+            hop.has_implicit_exception(KeyError)  # record that we know about it
+        hop.exception_is_here()
+        hop.gendirectcall(ll_dict_delitem_with_hash, v_dict, v_key, v_hash)
+
 class __extend__(pairtype(OrderedDictRepr, rmodel.Repr)):
 
     def rtype_getitem((r_dict, r_key), hop):
@@ -404,7 +412,7 @@
         if not r_dict.custom_eq_hash:
             hop.has_implicit_exception(KeyError)   # record that we know about it
         hop.exception_is_here()
-        return hop.gendirectcall(ll_dict_delitem, v_dict, v_key)
+        hop.gendirectcall(ll_dict_delitem, v_dict, v_key)
 
     def rtype_setitem((r_dict, r_key), hop):
         v_dict, v_key, v_value = hop.inputargs(r_dict, r_dict.key_repr, r_dict.value_repr)
@@ -778,6 +786,12 @@
         raise KeyError
     _ll_dict_del(d, index)
 
+def ll_dict_delitem_with_hash(d, key, hash):
+    index = d.lookup_function(d, key, hash, FLAG_DELETE)
+    if index < 0:
+        raise KeyError
+    _ll_dict_del(d, index)
+
 @jit.look_inside_iff(lambda d, i: jit.isvirtual(d) and jit.isconstant(i))
 def _ll_dict_del(d, index):
     d.entries.mark_deleted(index)


More information about the pypy-commit mailing list