1. Pypy
  2. Untitled project
  3. pypy

Commits

Carl Friedrich Bolz  committed 4b254e1

issue1059 testing

make the .__dict__.clear method of builtin types raise an error. Fix popitem on
dict proxies (builtin types raise an error, normal types work normally).

  • Participants
  • Parent commits a8321d3
  • Branches default

Comments (0)

Files changed (4)

File pypy/objspace/std/dictmultiobject.py

View file
  • Ignore whitespace
             else:
                 return result
 
+    def popitem(self, w_dict):
+        space = self.space
+        iterator = self.iter(w_dict)
+        w_key, w_value = iterator.next()
+        self.delitem(w_dict, w_key)
+        return (w_key, w_value)
+
     def clear(self, w_dict):
         strategy = self.space.fromcache(EmptyDictStrategy)
         storage = strategy.get_empty_storage()

File pypy/objspace/std/dictproxyobject.py

View file
  • Ignore whitespace
 from pypy.objspace.std.dictmultiobject import W_DictMultiObject, IteratorImplementation
 from pypy.objspace.std.dictmultiobject import DictStrategy
 from pypy.objspace.std.typeobject import unwrap_cell
-from pypy.interpreter.error import OperationError
+from pypy.interpreter.error import OperationError, operationerrfmt
 
 from pypy.rlib import rerased
 
                 raise
             if not w_type.is_cpytype():
                 raise
-            # xxx obscure workaround: allow cpyext to write to type->tp_dict.
+            # xxx obscure workaround: allow cpyext to write to type->tp_dict
+            # xxx even in the case of a builtin type.
             # xxx like CPython, we assume that this is only done early after
             # xxx the type is created, and we don't invalidate any cache.
             w_type.dict_w[key] = w_value
                     for (key, w_value) in self.unerase(w_dict.dstorage).dict_w.iteritems()]
 
     def clear(self, w_dict):
-        self.unerase(w_dict.dstorage).dict_w.clear()
-        self.unerase(w_dict.dstorage).mutated(None)
+        space = self.space
+        w_type = self.unerase(w_dict.dstorage)
+        if (not space.config.objspace.std.mutable_builtintypes
+                and not w_type.is_heaptype()):
+            msg = "can't clear dictionary of type '%s'"
+            raise operationerrfmt(space.w_TypeError, msg, w_type.name)
+        w_type.dict_w.clear()
+        w_type.mutated(None)
 
 class DictProxyIteratorImplementation(IteratorImplementation):
     def __init__(self, space, strategy, dictimplementation):

File pypy/objspace/std/test/test_dictproxy.py

View file
  • Ignore whitespace
         assert NotEmpty.string == 1
         raises(TypeError, 'NotEmpty.__dict__.setdefault(15, 1)')
 
+        key, value = NotEmpty.__dict__.popitem()
+        assert (key == 'a' and value == 1) or (key == 'b' and value == 4)
+
     def test_dictproxyeq(self):
         class a(object):
             pass
         assert s1 == s2
         assert s1.startswith('{') and s1.endswith('}')
 
+    def test_immutable_dict_on_builtin_type(self):
+        raises(TypeError, "int.__dict__['a'] = 1")
+        raises(TypeError, int.__dict__.popitem)
+        raises(TypeError, int.__dict__.clear)
+
 class AppTestUserObjectMethodCache(AppTestUserObject):
     def setup_class(cls):
         cls.space = gettestobjspace(

File pypy/objspace/std/test/test_typeobject.py

View file
  • Ignore whitespace
         raises(TypeError, setattr, list, 'append', 42)
         raises(TypeError, setattr, list, 'foobar', 42)
         raises(TypeError, delattr, dict, 'keys')
-        
+        raises(TypeError, 'int.__dict__["a"] = 1')
+        raises(TypeError, 'int.__dict__.clear()')
+
     def test_nontype_in_mro(self):
         class OldStyle:
             pass