[pypy-svn] r54740 - in pypy/dist/pypy/objspace/std: . test

antocuni at codespeak.net antocuni at codespeak.net
Wed May 14 20:50:12 CEST 2008


Author: antocuni
Date: Wed May 14 20:50:09 2008
New Revision: 54740

Modified:
   pypy/dist/pypy/objspace/std/dicttype.py
   pypy/dist/pypy/objspace/std/test/test_dictobject.py
Log:
when a subclass of dict overrides __setitem__, CPython doesn't always
call it, even in a completely inconsistent way. This checkin makes
pypy as buggy as CPython

 --This line, and those below, will be ignored--

M    std/dicttype.py
M    std/test/test_dictobject.py


Modified: pypy/dist/pypy/objspace/std/dicttype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/dicttype.py	(original)
+++ pypy/dist/pypy/objspace/std/dicttype.py	Wed May 14 20:50:09 2008
@@ -57,13 +57,17 @@
 # gateway is imported in the stdtypedef module
 app = gateway.applevel('''
 
+    # in the following functions we use dict.__setitem__ instead of
+    # d[k]=...  because when a subclass of dict override __setitem__,
+    # CPython does not call it when doing builtin operations.
+
     def update1(d, o):
         if hasattr(o, 'keys'):
             for k in o.keys():
-                d[k] = o[k]
+                dict.__setitem__(d, k, o[k])
         else:
             for k,v in o:
-                d[k] = v
+                dict.__setitem__(d, k, v)
 
     def update(d, *args, **kwargs):
         len_args = len(args)
@@ -93,7 +97,7 @@
         if k in d:
             return d[k]
         else:
-            d[k] = v
+            dict.__setitem__(d, k, v)
             return v
 
     def pop(d, k, defaults):     # XXX defaults is actually *defaults

Modified: pypy/dist/pypy/objspace/std/test/test_dictobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_dictobject.py	(original)
+++ pypy/dist/pypy/objspace/std/test/test_dictobject.py	Wed May 14 20:50:09 2008
@@ -355,6 +355,25 @@
         assert repr(D()) == 'hi'
         assert str(D()) == 'hi'
 
+    def test_overridden_setitem(self):
+        class D(dict):
+            def __setitem__(self, key, value):
+                dict.__setitem__(self, key, 42)
+        d = D([('x', 'foo')], y = 'bar')
+        assert d['x'] == 'foo'
+        assert d['y'] == 'bar'
+        d.setdefault('z', 'baz')
+        assert d['z'] == 'baz'
+        d.update({'w': 'foobar'})
+        assert d['w'] == 'foobar'
+        d = d.copy()
+        assert d['x'] == 'foo'
+
+        d3 = D.fromkeys(['x', 'y'], 'foo')
+        assert d3['x'] == 42
+        assert d3['y'] == 42
+
+
 # the minimal 'space' needed to use a W_DictObject
 class FakeSpace:
     def hash_w(self, obj):



More information about the Pypy-commit mailing list