[pypy-commit] pypy py2-mappingproxy: Backport W_DictProxyObject from py3k
rlamy
pypy.commits at gmail.com
Tue Aug 9 10:52:37 EDT 2016
Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: py2-mappingproxy
Changeset: r86110:786fadddf616
Date: 2016-08-09 15:15 +0100
http://bitbucket.org/pypy/pypy/changeset/786fadddf616/
Log: Backport W_DictProxyObject from py3k
diff --git a/pypy/objspace/std/dictproxyobject.py b/pypy/objspace/std/dictproxyobject.py
new file mode 100644
--- /dev/null
+++ b/pypy/objspace/std/dictproxyobject.py
@@ -0,0 +1,86 @@
+# Read-only proxy for mappings. PyPy does not have a separate type for
+# type.__dict__, so PyDictProxy_New has to use a custom read-only mapping.
+
+from pypy.interpreter.baseobjspace import W_Root
+from pypy.interpreter.error import oefmt
+from pypy.interpreter.gateway import unwrap_spec, WrappedDefault
+from pypy.interpreter.typedef import TypeDef, interp2app
+
+class W_DictProxyObject(W_Root):
+ "Read-only proxy for mappings."
+
+ def __init__(self, w_mapping):
+ self.w_mapping = w_mapping
+
+ @staticmethod
+ def descr_new(space, w_type, w_mapping):
+ raise oefmt(space.w_TypeError, "Cannot create 'dictproxy' instances")
+
+ def descr_init(self, space, __args__):
+ pass
+
+ def descr_len(self, space):
+ return space.len(self.w_mapping)
+
+ def descr_getitem(self, space, w_key):
+ return space.getitem(self.w_mapping, w_key)
+
+ def descr_contains(self, space, w_key):
+ return space.contains(self.w_mapping, w_key)
+
+ def descr_iter(self, space):
+ return space.iter(self.w_mapping)
+
+ def descr_str(self, space):
+ return space.str(self.w_mapping)
+
+ def descr_repr(self, space):
+ return space.wrap("dict_proxy(%s)" %
+ (space.str_w(space.repr(self.w_mapping)),))
+
+ @unwrap_spec(w_default=WrappedDefault(None))
+ def get_w(self, space, w_key, w_default):
+ return space.call_method(self.w_mapping, "get", w_key, w_default)
+
+ def keys_w(self, space):
+ return space.call_method(self.w_mapping, "keys")
+
+ def values_w(self, space):
+ return space.call_method(self.w_mapping, "values")
+
+ def items_w(self, space):
+ return space.call_method(self.w_mapping, "items")
+
+ def copy_w(self, space):
+ return space.call_method(self.w_mapping, "copy")
+
+cmp_methods = {}
+def make_cmp_method(op):
+ def descr_op(self, space, w_other):
+ return getattr(space, op)(self.w_mapping, w_other)
+ descr_name = 'descr_' + op
+ descr_op.__name__ = descr_name
+ setattr(W_DictProxyObject, descr_name, descr_op)
+ cmp_methods['__%s__' % op] = interp2app(getattr(W_DictProxyObject, descr_name))
+
+for op in ['eq', 'ne', 'gt', 'ge', 'lt', 'le']:
+ make_cmp_method(op)
+
+
+W_DictProxyObject.typedef = TypeDef(
+ 'dictproxy',
+ __new__=interp2app(W_DictProxyObject.descr_new),
+ __init__=interp2app(W_DictProxyObject.descr_init),
+ __len__=interp2app(W_DictProxyObject.descr_len),
+ __getitem__=interp2app(W_DictProxyObject.descr_getitem),
+ __contains__=interp2app(W_DictProxyObject.descr_contains),
+ __iter__=interp2app(W_DictProxyObject.descr_iter),
+ __str__=interp2app(W_DictProxyObject.descr_str),
+ __repr__=interp2app(W_DictProxyObject.descr_repr),
+ get=interp2app(W_DictProxyObject.get_w),
+ keys=interp2app(W_DictProxyObject.keys_w),
+ values=interp2app(W_DictProxyObject.values_w),
+ items=interp2app(W_DictProxyObject.items_w),
+ copy=interp2app(W_DictProxyObject.copy_w),
+ **cmp_methods
+)
diff --git a/pypy/objspace/std/test/test_typeobject.py b/pypy/objspace/std/test/test_typeobject.py
--- a/pypy/objspace/std/test/test_typeobject.py
+++ b/pypy/objspace/std/test/test_typeobject.py
@@ -968,7 +968,6 @@
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:
@@ -1026,10 +1025,9 @@
pass
a = A()
+ d = A.__dict__
A.x = 1
- assert A.__dict__["x"] == 1
- A.__dict__['x'] = 5
- assert A.x == 5
+ assert d["x"] == 1
def test_we_already_got_one_1(self):
# Issue #2079: highly obscure: CPython complains if we say
diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -488,11 +488,13 @@
def getdict(self, space): # returning a dict-proxy!
from pypy.objspace.std.classdict import ClassDictStrategy
from pypy.objspace.std.dictmultiobject import W_DictObject
+ from pypy.objspace.std.dictproxyobject import W_DictProxyObject
if self.lazyloaders:
self._cleanup_() # force un-lazification
strategy = space.fromcache(ClassDictStrategy)
storage = strategy.erase(self)
- return W_DictObject(space, strategy, storage)
+ w_dict = W_DictObject(space, strategy, storage)
+ return W_DictProxyObject(w_dict)
def is_heaptype(self):
return self.flag_heaptype
More information about the pypy-commit
mailing list