Commits

Amaury Forgeot d'Arc committed 5364600

Implement rdict.pop(). Always with default.

Comments (0)

Files changed (4)

pypy/annotation/unaryop.py

         return dct.dictdef.read_value()
 
     method_setdefault = method_get
+    method_pop = method_get
 
     def method_copy(dct):
         return SomeDict(dct.dictdef)

pypy/rpython/lltypesystem/rdict.py

         v_res = hop.gendirectcall(ll_setdefault, v_dict, v_key, v_default)
         return self.recast_value(hop.llops, v_res)
 
+    def rtype_method_pop(self, hop):
+        v_dict, v_key, v_default = hop.inputargs(self, self.key_repr,
+                                                 self.value_repr)
+        hop.exception_cannot_occur()
+        v_res = hop.gendirectcall(ll_dict_pop, v_dict, v_key, v_default)
+        return self.recast_value(hop.llops, v_res)
+
     def rtype_method_copy(self, hop):
         v_dict, = hop.inputargs(self)
         hop.exception_cannot_occur()
         raise KeyError
     _ll_dict_del(d, i)
 
+def ll_dict_pop(d, key, default):
+    i = ll_dict_lookup(d, key, d.keyhash(key))
+    if not i & HIGHEST_BIT:
+        value = ll_get_value(d, i)
+        _ll_dict_del(d, i)
+        return value
+    else:
+        return default
+
 @jit.dont_look_inside
 def _ll_dict_del(d, i):
     d.entries.mark_deleted(i)

pypy/rpython/ootypesystem/rdict.py

         v_res = hop.gendirectcall(ll_dict_setdefault, v_dict, v_key, v_default)
         return self.recast_value(hop.llops, v_res)
 
+    def rtype_method_pop(self, hop):
+        v_dict, v_key, v_default = hop.inputargs(self, self.key_repr,
+                                                 self.value_repr)
+        hop.exception_cannot_occur()
+        v_res = hop.gendirectcall(ll_dict_pop, v_dict, v_key, v_default)
+        return self.recast_value(hop.llops, v_res)
+
     def rtype_method_copy(self, hop):
         v_dict, = hop.inputargs(self)
         cDICT = hop.inputconst(ootype.Void, self.lowleveltype)
         d.ll_set(key, default)
         return default
 
+def ll_dict_pop(d, key, default):
+    if d.ll_contains(key):
+        value = d.ll_get(key)
+        d.ll_remove(key)
+        return value
+    else:
+        return default
+
 def _make_ll_keys_values_items(kind):
     def ll_dict_kvi(LIST, d):
         length = d.ll_length()

pypy/rpython/test/test_rdict.py

         res = self.interpret(func, ())
         assert res == 422
 
+    def test_dict_pop(self):
+        def func():
+            dic = {}
+            x1 = dic.pop('hi', 42)
+            dic['blah'] = 1
+            x2 = dic.pop('blah', 2)
+            return len(dic) * 100 + x1 * 10 + x2
+        res = self.interpret(func, ())
+        assert res == 421
+
     def test_dict_setdefault(self):
         def f():
             d = {}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.