[pypy-commit] pypy py35-getbuiltin: Good: we don't update sys.modules anymore in baseobjspace.py

amauryfa pypy.commits at gmail.com
Sat Oct 1 13:26:45 EDT 2016


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: py35-getbuiltin
Changeset: r87500:9bd1f653a930
Date: 2016-10-01 19:25 +0200
http://bitbucket.org/pypy/pypy/changeset/9bd1f653a930/

Log:	Good: we don't update sys.modules anymore in baseobjspace.py

	Add a workaround for a limitation of importlib._bootstrap, which
	does not correctly supports builtin submodules.

diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -644,10 +644,8 @@
         if self.config.objspace.usemodules.cpyext:
             from pypy.module.cpyext.state import State
             self.fromcache(State).build_api(self)
-        w_modules = self.sys.get('modules')
         for name in ('sys', '_imp', '_frozen_importlib', 'builtins'):
             mod = self.getbuiltinmodule(name)
-            self.setitem(w_modules, mod.w_name, mod)
         for mod in self.builtin_modules.values():
             mod.setup_after_space_initialization()
 
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
@@ -10,6 +10,7 @@
 from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.baseobjspace import W_Root, CannotHaveLock
 from pypy.interpreter.eval import Code
+from pypy.interpreter.mixedmodule import MixedModule
 from pypy.interpreter.pycode import PyCode
 from rpython.rlib import streamio, jit
 from rpython.rlib.streamio import StreamErrors
@@ -80,7 +81,11 @@
         lock.acquire_lock()
 
         if modulename in space.builtin_modules:
-            return space.getbuiltinmodule(modulename)
+            w_mod = space.getbuiltinmodule(modulename)
+            space.setitem(space.sys.get('modules'),
+                          space.wrap(modulename), w_mod)
+            install_mixed_submodules(space, w_mod)
+            return w_mod
 
         ec = space.getexecutioncontext()
         with open(os.path.join(lib_pypy, modulename + '.py')) as fp:
@@ -98,6 +103,22 @@
     return w_mod
 
 
+def install_mixed_submodules(space, w_mod):
+    # The pure-Python importlib does not support builtin submodules:
+    # when doing e.g. 'import pyexpat.errors':
+    # - to be considered a package, pyexpact.__path__ has to be set
+    # - the BuiltinImporter requires that pyexpat.__path__ is None
+    # - but at startup, _spec_from_module() tries a list(module.__path__)...
+    #
+    # In pyexpat.c, CPython explicitly adds the submodules to sys.path.
+    if not isinstance(w_mod, MixedModule):
+        return
+    for w_submodule in w_mod.submodules_w:
+        space.setitem(space.sys.get('modules'),
+                      w_submodule.w_name, w_submodule)
+        install_mixed_submodules(space, w_submodule)
+
+
 class _WIN32Path(object):
     def __init__(self, path):
         self.path = path
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
@@ -71,7 +71,8 @@
     return space.getbuiltinmodule(name, force_init=True, reuse=reuse)
 
 def exec_builtin(space, w_mod):
-    return  # Until we really support ModuleDef
+    # Not a lot to do until we really support ModuleDef
+    importing.install_mixed_submodules(space, w_mod)
 
 def init_frozen(space, w_name):
     return None


More information about the pypy-commit mailing list