[pypy-commit] pypy stmgc-c7: stmdict.keys() and similar methods

arigo noreply at buildbot.pypy.org
Sun Feb 1 12:03:41 CET 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: stmgc-c7
Changeset: r75625:707dcfba2317
Date: 2015-02-01 12:03 +0100
http://bitbucket.org/pypy/pypy/changeset/707dcfba2317/

Log:	stmdict.keys() and similar methods

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
@@ -138,6 +138,69 @@
         entry.object = lltype.cast_opaque_ptr(llmemory.GCREF, narray)
         return w_default
 
+    def get_length(self):
+        array, count = self.h.list()
+        try:
+            total_length_times_two = 0
+            for i in range(count):
+                subarray = lltype.cast_opaque_ptr(PARRAY, array[i].object)
+                assert subarray
+                total_length_times_two += len(subarray)
+        finally:
+            self.h.freelist(array)
+        return total_length_times_two >> 1
+
+    def get_keys_values_w(self, offset):
+        array, count = self.h.list()
+        try:
+            result_list_w = []
+            for i in range(count):
+                subarray = lltype.cast_opaque_ptr(PARRAY, array[i].object)
+                assert subarray
+                j = offset
+                limit = len(subarray)
+                while j < limit:
+                    w_item = cast_gcref_to_instance(W_Root, subarray[j])
+                    result_list_w.append(w_item)
+                    j += 2
+        finally:
+            self.h.freelist(array)
+        return result_list_w
+
+    def get_items_w(self, space):
+        array, count = self.h.list()
+        try:
+            result_list_w = []
+            for i in range(count):
+                subarray = lltype.cast_opaque_ptr(PARRAY, array[i].object)
+                assert subarray
+                j = 0
+                limit = len(subarray)
+                while j < limit:
+                    w_key = cast_gcref_to_instance(W_Root, subarray[j])
+                    w_value = cast_gcref_to_instance(W_Root, subarray[j + 1])
+                    result_list_w.append(space.newtuple([w_key, w_value]))
+                    j += 2
+        finally:
+            self.h.freelist(array)
+        return result_list_w
+
+    def len_w(self, space):
+        return space.wrap(self.get_length())
+
+    def iter_w(self, space):
+        # not a real lazy iterator!
+        return space.iter(self.keys_w(space))
+
+    def keys_w(self, space):
+        return space.newlist(self.get_keys_values_w(offset=0))
+
+    def values_w(self, space):
+        return space.newlist(self.get_keys_values_w(offset=1))
+
+    def items_w(self, space):
+        return space.newlist(self.get_items_w(space))
+
 
 def W_STMDict___new__(space, w_subtype):
     r = space.allocate_instance(W_STMDict, w_subtype)
@@ -153,4 +216,10 @@
     __contains__ = interp2app(W_STMDict.contains_w),
     get = interp2app(W_STMDict.get_w),
     setdefault = interp2app(W_STMDict.setdefault_w),
+
+    __len__  = interp2app(W_STMDict.len_w),
+    __iter__ = interp2app(W_STMDict.iter_w),
+    keys     = interp2app(W_STMDict.keys_w),
+    values   = interp2app(W_STMDict.values_w),
+    items    = interp2app(W_STMDict.items_w),
     )
diff --git a/pypy/module/pypystm/stmset.py b/pypy/module/pypystm/stmset.py
--- a/pypy/module/pypystm/stmset.py
+++ b/pypy/module/pypystm/stmset.py
@@ -94,6 +94,39 @@
     def discard_w(self, space, w_key):
         self.try_remove(space, w_key)
 
+    def get_length(self):
+        array, count = self.h.list()
+        try:
+            total_length = 0
+            for i in range(count):
+                subarray = lltype.cast_opaque_ptr(PARRAY, array[i].object)
+                assert subarray
+                total_length += len(subarray)
+        finally:
+            self.h.freelist(array)
+        return total_length
+
+    def get_items_w(self):
+        array, count = self.h.list()
+        try:
+            result_list_w = []
+            for i in range(count):
+                subarray = lltype.cast_opaque_ptr(PARRAY, array[i].object)
+                assert subarray
+                for j in range(len(subarray)):
+                    w_item = cast_gcref_to_instance(W_Root, subarray[j])
+                    result_list_w.append(w_item)
+        finally:
+            self.h.freelist(array)
+        return result_list_w
+
+    def len_w(self, space):
+        return space.wrap(self.get_length())
+
+    def iter_w(self, space):
+        # not a real lazy iterator!
+        return space.iter(space.newlist(self.get_items_w()))
+
 
 def W_STMSet___new__(space, w_subtype):
     r = space.allocate_instance(W_STMSet, w_subtype)
@@ -107,4 +140,7 @@
     add = interp2app(W_STMSet.add_w),
     remove = interp2app(W_STMSet.remove_w),
     discard = interp2app(W_STMSet.discard_w),
+
+    __len__ = interp2app(W_STMSet.len_w),
+    __iter__ = interp2app(W_STMSet.iter_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
@@ -70,3 +70,34 @@
         assert d[42] == "hello"
         assert d.get(42L) == "hello"
         assert d.get(42.001) is None
+
+    def test_list_from_dict(self):
+        import pypystm
+        d = pypystm.stmdict()
+        assert len(d) == 0
+        assert tuple(d) == ()
+        d[42.5] = "foo"
+        d[42.0] = ["bar"]
+        assert sorted(d) == [42.0, 42.5]
+        assert len(d) == 2
+        del d[42]
+        assert len(d) == 1
+        assert list(d) == [42.5]
+        #
+        class Key(object):
+            def __hash__(self):
+                return hash(42.5)
+        key3 = Key()
+        d[key3] = "other"
+        assert len(d) == 2
+        items = list(d)
+        assert items == [42.5, key3] or items == [key3, 42.5]
+
+    def test_keys_values_items(self):
+        import pypystm
+        d = pypystm.stmdict()
+        d[42.5] = "bar"
+        d[42.0] = "foo"
+        assert sorted(d.keys()) == [42.0, 42.5]
+        assert sorted(d.values()) == ["bar", "foo"]
+        assert sorted(d.items()) == [(42.0, "foo"), (42.5, "bar")]
diff --git a/pypy/module/pypystm/test/test_stmset.py b/pypy/module/pypystm/test/test_stmset.py
--- a/pypy/module/pypystm/test/test_stmset.py
+++ b/pypy/module/pypystm/test/test_stmset.py
@@ -62,3 +62,24 @@
         assert 42 in s
         assert 42L in s
         assert 42.001 not in s
+
+    def test_list_from_set(self):
+        import pypystm
+        s = pypystm.stmset()
+        assert len(s) == 0
+        assert tuple(s) == ()
+        s.add(42.5)
+        s.add(42.0)
+        assert sorted(s) == [42.0, 42.5]
+        assert len(s) == 2
+        s.remove(42.0)
+        assert list(s) == [42.5]
+        #
+        class Key(object):
+            def __hash__(self):
+                return hash(42.5)
+        key3 = Key()
+        s.add(key3)
+        assert len(s) == 2
+        items = list(s)
+        assert items == [42.5, key3] or items == [key3, 42.5]


More information about the pypy-commit mailing list