[pypy-commit] pypy py3.3: Rewrite the DictProxy type, so that it does not depend on
amauryfa
noreply at buildbot.pypy.org
Sat Apr 12 10:36:57 CEST 2014
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: py3.3
Changeset: r70600:bb19ba3f6538
Date: 2014-04-12 10:35 +0200
http://bitbucket.org/pypy/pypy/changeset/bb19ba3f6538/
Log: Rewrite the DictProxy type, so that it does not depend on
collections.abc which imports (and freezes) a lot of stdlib modules.
+Translation fixes.
diff --git a/pypy/module/cpyext/dictobject.py b/pypy/module/cpyext/dictobject.py
--- a/pypy/module/cpyext/dictobject.py
+++ b/pypy/module/cpyext/dictobject.py
@@ -5,8 +5,8 @@
from pypy.module.cpyext.pyobject import PyObject, PyObjectP, borrow_from
from pypy.module.cpyext.pyobject import RefcountState
from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
+from pypy.module.cpyext.dictproxyobject import W_DictProxyObject
from pypy.interpreter.error import OperationError
-from rpython.rlib.objectmodel import specialize
@cpython_api([], PyObject)
def PyDict_New(space):
@@ -195,25 +195,9 @@
return 0
return 1
- at specialize.memo()
-def make_frozendict(space):
- return space.appexec([], '''():
- from collections.abc import Mapping
- class FrozenDict(Mapping):
- def __init__(self, *args, **kwargs):
- self._d = dict(*args, **kwargs)
- def __iter__(self):
- return iter(self._d)
- def __len__(self):
- return len(self._d)
- def __getitem__(self, key):
- return self._d[key]
- return FrozenDict''')
-
@cpython_api([PyObject], PyObject)
def PyDictProxy_New(space, w_dict):
- w_frozendict = make_frozendict(space)
- return space.call_function(w_frozendict, w_dict)
+ return space.wrap(W_DictProxyObject(w_dict))
@cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
def _PyDict_HasOnlyStringKeys(space, w_dict):
diff --git a/pypy/module/cpyext/dictproxyobject.py b/pypy/module/cpyext/dictproxyobject.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/dictproxyobject.py
@@ -0,0 +1,61 @@
+# 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.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
+
+ 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.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")
+
+W_DictProxyObject.typedef = TypeDef(
+ 'mappingproxy',
+ __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)
+ )
diff --git a/pypy/module/cpyext/import_.py b/pypy/module/cpyext/import_.py
--- a/pypy/module/cpyext/import_.py
+++ b/pypy/module/cpyext/import_.py
@@ -53,8 +53,9 @@
@cpython_api([PyObject], PyObject)
def PyImport_ReloadModule(space, w_mod):
- from pypy.module.imp.importing import reload
- return reload(space, w_mod)
+ w_import = space.builtin.get('__import__')
+ w_imp = space.call_function(w_import, space.wrap('imp'))
+ return space.call_method(w_imp, 'reload', w_mod)
@cpython_api([CONST_STRING], PyObject)
def PyImport_AddModule(space, name):
diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py
--- a/pypy/module/imp/importing.py
+++ b/pypy/module/imp/importing.py
@@ -129,6 +129,14 @@
find_module=interp2app(W_NullImporter.find_module_w),
)
+def _prepare_module(space, w_mod, filename, pkgdir):
+ w = space.wrap
+ space.sys.setmodule(w_mod)
+ space.setattr(w_mod, w('__file__'), space.wrap(filename))
+ space.setattr(w_mod, w('__doc__'), space.w_None)
+ if pkgdir is not None:
+ space.setattr(w_mod, w('__path__'), space.newlist([w(pkgdir)]))
+
def add_module(space, w_name):
w_mod = check_sys_modules(space, w_name)
if w_mod is None:
@@ -377,6 +385,15 @@
if const is not None and isinstance(const, PyCode):
update_code_filenames(space, const, pathname, oldname)
+def _get_long(s):
+ a = ord(s[0])
+ b = ord(s[1])
+ c = ord(s[2])
+ d = ord(s[3])
+ if d >= 0x80:
+ d -= 0x100
+ return a | (b<<8) | (c<<16) | (d<<24)
+
def read_compiled_module(space, cpathname, strbuf):
""" Read a code object from a file and check it for validity """
@@ -386,3 +403,25 @@
raise oefmt(space.w_ImportError, "Non-code object in %s", cpathname)
return w_code
+ at jit.dont_look_inside
+def load_compiled_module(space, w_modulename, w_mod, cpathname, magic,
+ timestamp, source, write_paths=True):
+ """
+ Load a module from a compiled file, execute it, and return its
+ module object.
+ """
+ if magic != get_pyc_magic(space):
+ raise oefmt(space.w_ImportError, "Bad magic number in %s", cpathname)
+ #print "loading pyc file:", cpathname
+ code_w = read_compiled_module(space, cpathname, source)
+ try:
+ optimize = space.sys.get_flag('optimize')
+ except RuntimeError:
+ # during bootstrapping
+ optimize = 0
+ if optimize >= 2:
+ code_w.remove_docstrings(space)
+
+ exec_code_module(space, w_mod, code_w, cpathname, cpathname, write_paths)
+
+ return w_mod
diff --git a/pypy/module/imp/interp_imp.py b/pypy/module/imp/interp_imp.py
--- a/pypy/module/imp/interp_imp.py
+++ b/pypy/module/imp/interp_imp.py
@@ -68,7 +68,13 @@
if not space.config.objspace.usemodules.cpyext:
raise OperationError(space.w_ImportError, space.wrap(
"Not implemented"))
- importing.load_c_extension(space, filename, space.str_w(w_modulename))
+
+ # the next line is mandatory to init cpyext
+ space.getbuiltinmodule("cpyext")
+
+ from pypy.module.cpyext.api import load_extension_module
+ load_extension_module(space, filename, space.str_w(w_modulename))
+
return importing.check_sys_modules(space, w_modulename)
def new_module(space, w_name):
More information about the pypy-commit
mailing list