Author: Armin Rigo <ar...@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) +@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) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit