Author: Ronan Lamy <ronan.l...@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 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit