Author: Armin Rigo <[email protected]>
Branch: stmgc-c7
Changeset: r75626:b4c5f43782f1
Date: 2015-02-01 13:44 +0100
http://bitbucket.org/pypy/pypy/changeset/b4c5f43782f1/

Log:    stmdict.pop()

diff --git a/pypy/module/pypystm/stmdict.py b/pypy/module/pypystm/stmdict.py
--- a/pypy/module/pypystm/stmdict.py
+++ b/pypy/module/pypystm/stmdict.py
@@ -43,6 +43,25 @@
         for i in range(length):
             dest[dest_start + i] = source[source_start + i]
 
+def pop_from_entry(entry, space, w_key):
+    array = lltype.cast_opaque_ptr(PARRAY, entry.object)
+    if not array:
+        return None
+    i = find_equal_item(space, array, w_key)
+    if i < 0:
+        return None
+    # found
+    w_value = cast_gcref_to_instance(W_Root, array[i + 1])
+    L = len(array) - 2
+    if L == 0:
+        narray = lltype.nullptr(ARRAY)
+    else:
+        narray = lltype.malloc(ARRAY, L)
+        ll_arraycopy(array, narray, 0, 0, i)
+        ll_arraycopy(array, narray, i + 2, i, L - i)
+    entry.object = lltype.cast_opaque_ptr(llmemory.GCREF, narray)
+    return w_value
+
 
 class W_STMDict(W_Root):
 
@@ -82,21 +101,8 @@
     def delitem_w(self, space, w_key):
         hkey = space.hash_w(w_key)
         entry = self.h.lookup(hkey)
-        array = lltype.cast_opaque_ptr(PARRAY, entry.object)
-        if array:
-            i = find_equal_item(space, array, w_key)
-            if i >= 0:
-                # found
-                L = len(array) - 2
-                if L == 0:
-                    narray = lltype.nullptr(ARRAY)
-                else:
-                    narray = lltype.malloc(ARRAY, L)
-                    ll_arraycopy(array, narray, 0, 0, i)
-                    ll_arraycopy(array, narray, i + 2, i, L - i)
-                entry.object = lltype.cast_opaque_ptr(llmemory.GCREF, narray)
-                return
-        space.raise_key_error(w_key)
+        if pop_from_entry(entry, space, w_key) is None:
+            space.raise_key_error(w_key)
 
     def contains_w(self, space, w_key):
         hkey = space.hash_w(w_key)
@@ -117,6 +123,17 @@
                 return cast_gcref_to_instance(W_Root, array[i + 1])
         return w_default
 
+    def pop_w(self, space, w_key, w_default=None):
+        hkey = space.hash_w(w_key)
+        entry = self.h.lookup(hkey)
+        w_value = pop_from_entry(entry, space, w_key)
+        if w_value is not None:
+            return w_value
+        elif w_default is not None:
+            return w_default
+        else:
+            space.raise_key_error(w_key)
+
     @unwrap_spec(w_default=WrappedDefault(None))
     def setdefault_w(self, space, w_key, w_default):
         hkey = space.hash_w(w_key)
@@ -215,6 +232,7 @@
     __delitem__ = interp2app(W_STMDict.delitem_w),
     __contains__ = interp2app(W_STMDict.contains_w),
     get = interp2app(W_STMDict.get_w),
+    pop = interp2app(W_STMDict.pop_w),
     setdefault = interp2app(W_STMDict.setdefault_w),
 
     __len__  = interp2app(W_STMDict.len_w),
diff --git a/pypy/module/pypystm/test/test_stmdict.py 
b/pypy/module/pypystm/test/test_stmdict.py
--- a/pypy/module/pypystm/test/test_stmdict.py
+++ b/pypy/module/pypystm/test/test_stmdict.py
@@ -101,3 +101,18 @@
         assert sorted(d.keys()) == [42.0, 42.5]
         assert sorted(d.values()) == ["bar", "foo"]
         assert sorted(d.items()) == [(42.0, "foo"), (42.5, "bar")]
+
+    def test_pop(self):
+        import pypystm
+        d = pypystm.stmdict()
+        raises(KeyError, d.pop, 42.0)
+        assert d.pop(42.0, "foo") == "foo"
+        raises(KeyError, "d[42.0]")
+        d[42.0] = "bar"
+        res = d.pop(42.0)
+        assert res == "bar"
+        raises(KeyError, "d[42.0]")
+        d[42.0] = "bar"
+        res = d.pop(42.0, "foo")
+        assert res == "bar"
+        raises(KeyError, "d[42.0]")
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to