Author: Armin Rigo <[email protected]>
Branch: rdict-experiments-3
Changeset: r67296:879f9a355048
Date: 2013-10-10 16:36 +0200
http://bitbucket.org/pypy/pypy/changeset/879f9a355048/

Log:    (fijal, arigo)

        dict.pop()

diff --git a/rpython/rtyper/lltypesystem/rdict.py 
b/rpython/rtyper/lltypesystem/rdict.py
--- a/rpython/rtyper/lltypesystem/rdict.py
+++ b/rpython/rtyper/lltypesystem/rdict.py
@@ -334,15 +334,15 @@
         r_tuple = hop.r_result
         cTUPLE = hop.inputconst(lltype.Void, r_tuple.lowleveltype)
         hop.exception_is_here()
-        return hop.gendirectcall(ll_popitem, cTUPLE, v_dict)
+        return hop.gendirectcall(ll_dict_popitem, cTUPLE, v_dict)
 
     def rtype_method_pop(self, hop):
         if hop.nb_args == 2:
             v_args = hop.inputargs(self, self.key_repr)
-            target = ll_pop
+            target = ll_dict_pop
         elif hop.nb_args == 3:
             v_args = hop.inputargs(self, self.key_repr, self.value_repr)
-            target = ll_pop_default
+            target = ll_dict_pop_default
         hop.exception_is_here()
         v_res = hop.gendirectcall(target, *v_args)
         return self.recast_value(hop.llops, v_res)
@@ -1093,7 +1093,7 @@
         assert index != -1
     return index
 
-def ll_popitem(ELEM, dic):
+def ll_dict_popitem(ELEM, dic):
     i = _ll_getnextitem(dic)
     entry = dic.entries[i]
     r = lltype.malloc(ELEM.TO)
@@ -1102,17 +1102,18 @@
     _ll_dict_del(dic, r_uint(i))
     return r
 
-def ll_pop(dic, key):
-    i = ll_dict_lookup(dic, key, dic.keyhash(key))
-    if not i & HIGHEST_BIT:
-        value = ll_get_value(dic, r_uint(i))
-        _ll_dict_del(dic, r_uint(i))
-        return value
-    else:
+def ll_dict_pop(dic, key):
+    index = dic.lookup_function(dic, key, dic.keyhash(key), FLAG_DELETE)
+    if index == -1:
         raise KeyError
+    value = dic.entries[index].value
+    _ll_dict_del(dic, index)
+    return value
 
-def ll_pop_default(dic, key, dfl):
-    try:
-        return ll_pop(dic, key)
-    except KeyError:
+def ll_dict_pop_default(dic, key, dfl):
+    index = dic.lookup_function(dic, key, dic.keyhash(key), FLAG_DELETE)
+    if index == -1:
         return dfl
+    value = dic.entries[index].value
+    _ll_dict_del(dic, index)
+    return value
diff --git a/rpython/rtyper/test/test_rdict.py 
b/rpython/rtyper/test/test_rdict.py
--- a/rpython/rtyper/test/test_rdict.py
+++ b/rpython/rtyper/test/test_rdict.py
@@ -162,13 +162,13 @@
         rdict.ll_dict_setitem(ll_d, llstr("j"), 2)
         TUP = lltype.Ptr(lltype.GcStruct('x', ('item0', lltype.Ptr(rstr.STR)),
                                               ('item1', lltype.Signed)))
-        ll_elem = rdict.ll_popitem(TUP, ll_d)
+        ll_elem = rdict.ll_dict_popitem(TUP, ll_d)
         assert hlstr(ll_elem.item0) == "j"
         assert ll_elem.item1 == 2
-        ll_elem = rdict.ll_popitem(TUP, ll_d)
+        ll_elem = rdict.ll_dict_popitem(TUP, ll_d)
         assert hlstr(ll_elem.item0) == "k"
         assert ll_elem.item1 == 1
-        py.test.raises(KeyError, rdict.ll_popitem, TUP, ll_d)
+        py.test.raises(KeyError, rdict.ll_dict_popitem, TUP, ll_d)
 
     def test_direct_enter_and_del(self):
         def eq(a, b):
@@ -241,6 +241,26 @@
         for key, value in [("k", 8), ("i", 7), ("j", 6)]:
             assert rdict.ll_dict_getitem(ll_d1, llstr(key)) == value
 
+    def test_pop(self):
+        DICT = self._get_str_dict()
+        ll_d = rdict.ll_newdict(DICT)
+        rdict.ll_dict_setitem(ll_d, llstr("k"), 5)
+        rdict.ll_dict_setitem(ll_d, llstr("j"), 6)
+        assert rdict.ll_dict_pop(ll_d, llstr("k")) == 5
+        assert rdict.ll_dict_pop(ll_d, llstr("j")) == 6
+        py.test.raises(KeyError, rdict.ll_dict_pop, ll_d, llstr("k"))
+        py.test.raises(KeyError, rdict.ll_dict_pop, ll_d, llstr("j"))
+
+    def test_pop_default(self):
+        DICT = self._get_str_dict()
+        ll_d = rdict.ll_newdict(DICT)
+        rdict.ll_dict_setitem(ll_d, llstr("k"), 5)
+        rdict.ll_dict_setitem(ll_d, llstr("j"), 6)
+        assert rdict.ll_dict_pop_default(ll_d, llstr("k"), 42) == 5
+        assert rdict.ll_dict_pop_default(ll_d, llstr("j"), 41) == 6
+        assert rdict.ll_dict_pop_default(ll_d, llstr("k"), 40) == 40
+        assert rdict.ll_dict_pop_default(ll_d, llstr("j"), 39) == 39
+
 class TestRDictDirectDummyKey(TestRDictDirect):
     class dummykeyobj:
         ll_dummy_value = llstr("dupa")
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to