[pypy-commit] pypy dummy-importlib: add enough logic to import packages and modules inside packages
antocuni
pypy.commits at gmail.com
Thu Dec 19 19:37:32 EST 2019
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: dummy-importlib
Changeset: r98334:98132b9252a9
Date: 2019-12-19 14:47 +0100
http://bitbucket.org/pypy/pypy/changeset/98132b9252a9/
Log: add enough logic to import packages and modules inside packages
diff --git a/pypy/module/_dummy_importlib/interp_import.py b/pypy/module/_dummy_importlib/interp_import.py
--- a/pypy/module/_dummy_importlib/interp_import.py
+++ b/pypy/module/_dummy_importlib/interp_import.py
@@ -16,8 +16,8 @@
raise OperationError(space.w_ImportError, space.newtext(modname + '\n' + err))
- at unwrap_spec(name='text0', level=int)
-def importhook(space, name, w_globals=None,
+ at unwrap_spec(modname='text0', level=int)
+def importhook(space, modname, w_globals=None,
w_locals=None, w_fromlist=None, level=0):
"""
NOT_RPYTHON
@@ -26,33 +26,63 @@
non-rpython tricks to implement it :)
"""
assert level == 0
- if name in space.builtin_modules:
- return space.getbuiltinmodule(name)
+ if modname in space.builtin_modules:
+ return space.getbuiltinmodule(modname)
w_path = space.sys.get('path')
+ parts = modname.split('.')
+ if parts[-1] == '':
+ del parts[-1]
+
+ ## if modname == 'dummypkg.mod':
+ ## import pdb;pdb.set_trace()
+ w_mod = None
+ w_firstmod = None
+ for part in parts:
+ w_mod = load_part(space, part, w_mod)
+ if w_mod and w_firstmod is None:
+ w_firstmod = w_mod
+
+ if w_mod is None:
+ raise_ImportError(space, modname)
+ return w_firstmod
+
+def load_part(space, modname, w_parent):
+ if w_parent is None:
+ w_path = space.sys.get('path')
+ else:
+ w_path = space.getattr(w_parent, space.newtext('__path__'))
+ #
+ w_mod = load_part_in_path(space, modname, w_path)
+ if w_mod is not None and w_parent is not None:
+ space.setattr(w_parent, space.newtext(modname), w_mod)
+ return w_mod
+
+def load_part_in_path(space, modname, w_path):
for w_item in space.unpackiterable(w_path):
item = space.fsdecode_w(w_item)
d = py.path.local(item)
#
- pyfile = d.join(name + '.py')
+ pyfile = d.join(modname + '.py')
if pyfile.check(file=True):
- return import_pyfile(space, name, pyfile)
+ return load_pyfile(space, modname, pyfile)
#
- pydir = d.join(name)
+ pydir = d.join(modname)
pyinit = pydir.join('__init__.py')
if pydir.check(dir=True) and pyinit.check(file=True):
- return import_pyfile(space, name, pyinit)
+ return load_pyfile(space, modname, pyinit, modpath=str(pydir))
+ return None
- raise_ImportError(name)
-
-
-def import_pyfile(space, modulename, pyfile):
+def load_pyfile(space, modname, pyfile, modpath=None):
ec = space.getexecutioncontext()
source = pyfile.read()
code_w = ec.compiler.compile(source, str(pyfile), 'exec', 0)
- w_mod = add_module(space, space.newtext(modulename))
+ w_mod = add_module(space, space.newtext(modname))
space.setitem(space.sys.get('modules'), w_mod.w_name, w_mod)
space.setitem(w_mod.w_dict, space.newtext('__name__'), w_mod.w_name)
+ if modpath:
+ w_path = space.newlist([space.newtext(modpath)])
+ space.setitem(w_mod.w_dict, space.newtext('__path__'), w_path)
code_w.exec_code(space, w_mod.w_dict, w_mod.w_dict)
- assert check_sys_modules_w(space, modulename)
+ assert check_sys_modules_w(space, modname)
return w_mod
diff --git a/pypy/module/_dummy_importlib/test/test__dummy_importlib.py b/pypy/module/_dummy_importlib/test/test__dummy_importlib.py
--- a/pypy/module/_dummy_importlib/test/test__dummy_importlib.py
+++ b/pypy/module/_dummy_importlib/test/test__dummy_importlib.py
@@ -18,21 +18,23 @@
def setup_method(self, meth):
space = self.space
- self.w_thisidr = space.newtext(str(THISDIR))
- space.appexec([self.w_thisidr], """(dir):
+ self.w_thisdir = space.newtext(str(THISDIR))
+ space.appexec([self.w_thisdir], """(dir):
import sys
sys.path.append(dir)
""")
-
def teardown_method(self, meth):
space = self.space
- space.appexec([self.w_thisidr], """(dir):
+ space.appexec([self.w_thisdir], """(dir):
import sys
if dir in sys.path:
sys.path.remove(dir)
""")
+ def test_ImportError(self):
+ raises(ImportError, "import i_dont_exist")
+
def test_import_builtin(self):
import sys
assert sys.__name__ == 'sys'
@@ -43,9 +45,21 @@
assert sys is sys2
def test_import_lib_pypy(self):
+ import sys
import _structseq
+ assert _structseq.__name__ == '_structseq'
assert hasattr(_structseq, 'structseq_new')
+ assert sys.modules['_structseq'] is _structseq
def test_import_package(self):
+ import sys
import dummypkg
+ assert dummypkg.__name__ == 'dummypkg'
+ assert dummypkg.__path__ == [self.thisdir + '/' + 'dummypkg']
assert dummypkg.FOO == 42
+ assert sys.modules['dummypkg'] is dummypkg
+
+ def test_import_package_dot_mod(self):
+ import dummypkg.mod
+ assert dummypkg.FOO == 42
+ assert dummypkg.mod.BAR == 43
More information about the pypy-commit
mailing list