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