Author: Alex Gaynor <[email protected]>
Branch: 
Changeset: r45282:ac31a98dad24
Date: 2011-07-02 10:26 -0700
http://bitbucket.org/pypy/pypy/changeset/ac31a98dad24/

Log:    Added popitem() to module dictionaries, and fixed a bug with
        degenerating them when there are invalidated cells.

diff --git a/pypy/objspace/std/celldict.py b/pypy/objspace/std/celldict.py
--- a/pypy/objspace/std/celldict.py
+++ b/pypy/objspace/std/celldict.py
@@ -139,12 +139,24 @@
         for k, cell in iterator():
             cell.invalidate()
 
+    def popitem(self, w_dict):
+        # This is O(n) if called repeatadly, you probably shouldn't be on a
+        # Module's dict though
+        for k, cell in self.unerase(w_dict.dstorage).iteritems():
+            if cell.w_value is not None:
+                w_value = cell.w_value
+                cell.invalidate()
+                return self.space.wrap(k), w_value
+        else:
+            raise KeyError
+
     def switch_to_object_strategy(self, w_dict):
         d = self.unerase(w_dict.dstorage)
         strategy = self.space.fromcache(ObjectDictStrategy)
         d_new = strategy.unerase(strategy.get_empty_storage())
         for key, cell in d.iteritems():
-            d_new[self.space.wrap(key)] = cell.w_value
+            if cell.w_value is not None:
+                d_new[self.space.wrap(key)] = cell.w_value
         w_dict.strategy = strategy
         w_dict.dstorage = strategy.erase(d_new)
 
diff --git a/pypy/objspace/std/test/test_celldict.py 
b/pypy/objspace/std/test/test_celldict.py
--- a/pypy/objspace/std/test/test_celldict.py
+++ b/pypy/objspace/std/test/test_celldict.py
@@ -38,3 +38,31 @@
         assert d.getitem("a") is None
         assert d.getcell("a", False) is acell
         assert d.length() == 0
+
+class AppTestCellDict(object):
+    OPTIONS = {"objspace.std.withcelldict": True}
+
+    def setup_class(cls):
+        strategy = ModuleDictStrategy(cls.space)
+        storage = strategy.get_empty_storage()
+        cls.w_d = W_DictMultiObject(cls.space, strategy, storage)
+
+    def test_popitem(self):
+        import __pypy__
+
+        d = self.d
+        assert "ModuleDict" in __pypy__.internal_repr(d)
+        raises(KeyError, d.popitem)
+        d["a"] = 3
+        x = d.popitem()
+        assert x == ("a", 3)
+
+    def test_degenerate(self):
+        import __pypy__
+
+        d = self.d
+        assert "ModuleDict" in __pypy__.internal_repr(d)
+        d["a"] = 3
+        del d["a"]
+        d[object()] = 5
+        assert d.values() == [5]
\ No newline at end of file
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to