]> granicus.if.org Git - python/commitdiff
Issue #15902: Fix imp.load_module() to accept None as a file when
authorBrett Cannon <brett@python.org>
Fri, 3 May 2013 14:37:08 +0000 (10:37 -0400)
committerBrett Cannon <brett@python.org>
Fri, 3 May 2013 14:37:08 +0000 (10:37 -0400)
trying to load an extension module.

While at it, also add a proper unittest.skipIf() guard to another test
involving imp.load_dynamic().

Lib/imp.py
Lib/test/test_imp.py
Misc/NEWS

index 6d156d3115c53e248a5264a7683625ca41f030aa..40869f5ac06c992fb274f280396f6a2f08e8fce5 100644 (file)
@@ -168,7 +168,7 @@ def load_module(name, file, filename, details):
         warnings.simplefilter('ignore')
         if mode and (not mode.startswith(('r', 'U')) or '+' in mode):
             raise ValueError('invalid file open mode {!r}'.format(mode))
-        elif file is None and type_ in {PY_SOURCE, PY_COMPILED, C_EXTENSION}:
+        elif file is None and type_ in {PY_SOURCE, PY_COMPILED}:
             msg = 'file object required for import (type code {})'.format(type_)
             raise ValueError(msg)
         elif type_ == PY_SOURCE:
@@ -176,7 +176,11 @@ def load_module(name, file, filename, details):
         elif type_ == PY_COMPILED:
             return load_compiled(name, filename, file)
         elif type_ == C_EXTENSION and load_dynamic is not None:
-            return load_dynamic(name, filename, file)
+            if file is None:
+                with open(filename, 'rb') as opened_file:
+                    return load_dynamic(name, filename, opened_file)
+            else:
+                return load_dynamic(name, filename, file)
         elif type_ == PKG_DIRECTORY:
             return load_package(name, filename)
         elif type_ == C_BUILTIN:
index 72ae145f68204cc3fd5773e7cafa62a3b26b8826..2b2bbd3c1621fbb26cee71cffcaf6a9c414107aa 100644 (file)
@@ -208,6 +208,8 @@ class ImportTests(unittest.TestCase):
             self.assertIsNot(orig_getenv, new_os.getenv)
 
     @support.cpython_only
+    @unittest.skipIf(not hasattr(imp, 'load_dynamic'),
+                     'imp.load_dynamic() required')
     def test_issue15828_load_extensions(self):
         # Issue 15828 picked up that the adapter between the old imp API
         # and importlib couldn't handle C extensions
@@ -230,6 +232,19 @@ class ImportTests(unittest.TestCase):
         self.assertIn(path, err.exception.path)
         self.assertEqual(name, err.exception.name)
 
+    @support.cpython_only
+    @unittest.skipIf(not hasattr(imp, 'load_dynamic'),
+                     'imp.load_dynamic() required')
+    def test_load_module_extension_file_is_None(self):
+        # When loading an extension module and the file is None, open one
+        # on the behalf of imp.load_dynamic().
+        # Issue #15902
+        name = '_heapq'
+        found = imp.find_module(name)
+        assert found[2][2] == imp.C_EXTENSION
+        found[0].close()
+        imp.load_module(name, None, *found[1:])
+
 
 class ReloadTests(unittest.TestCase):
 
index db0c594d5fd2f4ed11600f884c54bdbc749c67ec..e4a92bf2b49458f12970b9e9ef82690ac616f238 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -44,6 +44,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #15902: Fix imp.load_module() accepting None as a file when loading an
+  extension module.
+
 - Issue #17802: Fix an UnboundLocalError in html.parser.  Initial tests by
   Thomas Barlow.