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

Reply via email to