Author: Anders Hammarquist <[email protected]>
Branch:
Changeset: r55967:ad478c8c914b
Date: 2012-07-07 14:50 +0200
http://bitbucket.org/pypy/pypy/changeset/ad478c8c914b/
Log: Make import behave like CPython when a path_hook find_module()
raises ImportError: treat it as if the find_module() had returned
None
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
@@ -429,7 +429,12 @@
def find_in_path_hooks(space, w_modulename, w_pathitem):
w_importer = _getimporter(space, w_pathitem)
if w_importer is not None and space.is_true(w_importer):
- w_loader = space.call_method(w_importer, "find_module", w_modulename)
+ try:
+ w_loader = space.call_method(w_importer, "find_module",
w_modulename)
+ except OperationError, e:
+ if e.match(space, space.w_ImportError):
+ return None
+ raise
if space.is_true(w_loader):
return w_loader
diff --git a/pypy/module/imp/test/hooktest.py b/pypy/module/imp/test/hooktest.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/imp/test/hooktest.py
@@ -0,0 +1,30 @@
+import sys, imp
+
+__path__ = [ ]
+
+class Loader(object):
+ def __init__(self, file, filename, stuff):
+ self.file = file
+ self.filename = filename
+ self.stuff = stuff
+
+ def load_module(self, fullname):
+ mod = imp.load_module(fullname, self.file, self.filename, self.stuff)
+ if self.file:
+ self.file.close()
+ mod.__loader__ = self # for introspection
+ return mod
+
+class Importer(object):
+ def __init__(self, path):
+ if path not in __path__:
+ raise ImportError
+
+ def find_module(self, fullname, path=None):
+ if not fullname.startswith('hooktest'):
+ return None
+
+ _, mod_name = fullname.rsplit('.',1)
+ found = imp.find_module(mod_name, path or __path__)
+
+ return Loader(*found)
diff --git a/pypy/module/imp/test/hooktest/foo.py
b/pypy/module/imp/test/hooktest/foo.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/imp/test/hooktest/foo.py
@@ -0,0 +1,1 @@
+import errno # Any existing toplevel module
diff --git a/pypy/module/imp/test/test_import.py
b/pypy/module/imp/test/test_import.py
--- a/pypy/module/imp/test/test_import.py
+++ b/pypy/module/imp/test/test_import.py
@@ -989,8 +989,22 @@
class AppTestImportHooks(object):
def setup_class(cls):
- cls.space = gettestobjspace(usemodules=('struct',))
-
+ space = cls.space = gettestobjspace(usemodules=('struct',))
+ mydir = os.path.dirname(__file__)
+ cls.w_hooktest = space.wrap(os.path.join(mydir, 'hooktest'))
+ space.appexec([space.wrap(mydir)], """
+ (mydir):
+ import sys
+ sys.path.append(mydir)
+ """)
+
+ def teardown_class(cls):
+ cls.space.appexec([], """
+ ():
+ import sys
+ sys.path.pop()
+ """)
+
def test_meta_path(self):
tried_imports = []
class Importer(object):
@@ -1127,6 +1141,23 @@
sys.meta_path.pop()
sys.path_hooks.pop()
+ def test_path_hooks_module(self):
+ "Verify that non-sibling imports from module loaded by path hook works"
+
+ import sys
+ import hooktest
+
+ hooktest.__path__.append(self.hooktest) # Avoid importing os at
applevel
+
+ sys.path_hooks.append(hooktest.Importer)
+
+ try:
+ import hooktest.foo
+ def import_nonexisting():
+ import hooktest.errno
+ raises(ImportError, import_nonexisting)
+ finally:
+ sys.path_hooks.pop()
class AppTestPyPyExtension(object):
def setup_class(cls):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit