]> granicus.if.org Git - python/commitdiff
Issue #15828: Restore support for C extension modules in imp.load_module()
authorNick Coghlan <ncoghlan@gmail.com>
Fri, 31 Aug 2012 14:13:45 +0000 (00:13 +1000)
committerNick Coghlan <ncoghlan@gmail.com>
Fri, 31 Aug 2012 14:13:45 +0000 (00:13 +1000)
Lib/imp.py
Lib/test/test_imp.py
Lib/test/test_import.py
Misc/NEWS

index 80b04c83ed06adbe32dc72086e653ead3822fd53..da9c84ee39d962ad32637a9488bf895950713290 100644 (file)
@@ -153,13 +153,15 @@ 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}:
+        elif file is None and type_ in {PY_SOURCE, PY_COMPILED, C_EXTENSION}:
             msg = 'file object required for import (type code {})'.format(type_)
             raise ValueError(msg)
         elif type_ == PY_SOURCE:
             return load_source(name, filename, file)
         elif type_ == PY_COMPILED:
             return load_compiled(name, filename, file)
+        elif type_ == C_EXTENSION:
+            return load_dynamic(name, filename, file)
         elif type_ == PKG_DIRECTORY:
             return load_package(name, filename)
         elif type_ == C_BUILTIN:
@@ -167,7 +169,7 @@ def load_module(name, file, filename, details):
         elif type_ == PY_FROZEN:
             return init_frozen(name)
         else:
-            msg =  "Don't know how to import {} (type code {}".format(name, type_)
+            msg =  "Don't know how to import {} (type code {})".format(name, type_)
             raise ImportError(msg, name=name)
 
 
index a660278c9c722fdea74c9add4560a58c803d5ce4..20e5608e81b54be626c5ab372c1cd237f2951760 100644 (file)
@@ -186,6 +186,35 @@ class ImportTests(unittest.TestCase):
         self.assertRaises(SyntaxError,
                           imp.find_module, "badsyntax_pep3120", [path])
 
+    def test_load_from_source(self):
+        # Verify that the imp module can correctly load and find .py files
+        # XXX (ncoghlan): It would be nice to use support.CleanImport
+        # here, but that breaks because the os module registers some
+        # handlers in copy_reg on import. Since CleanImport doesn't
+        # revert that registration, the module is left in a broken
+        # state after reversion. Reinitialising the module contents
+        # and just reverting os.environ to its previous state is an OK
+        # workaround
+        orig_path = os.path
+        orig_getenv = os.getenv
+        with support.EnvironmentVarGuard():
+            x = imp.find_module("os")
+            self.addCleanup(x[0].close)
+            new_os = imp.load_module("os", *x)
+            self.assertIs(os, new_os)
+            self.assertIs(orig_path, new_os.path)
+            self.assertIsNot(orig_getenv, new_os.getenv)
+
+    @support.cpython_only
+    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
+        example = "_heapq"
+        x = imp.find_module(example)
+        self.addCleanup(x[0].close)
+        mod = imp.load_module(example, *x)
+        self.assertEqual(mod.__name__, example)
+
     def test_load_dynamic_ImportError_path(self):
         # Issue #1559549 added `name` and `path` attributes to ImportError
         # in order to provide better detail. Issue #10854 implemented those
index 60447dc26bc6a36149cf2ab3f136e7460657e23f..19863b936af5d7178ab3fe9b46b64dacc5020a18 100644 (file)
@@ -149,25 +149,6 @@ class ImportTests(unittest.TestCase):
 
         self.assertEqual(oct(stat.S_IMODE(stat_info.st_mode)), oct(mode))
 
-    def test_imp_module(self):
-        # Verify that the imp module can correctly load and find .py files
-        # XXX (ncoghlan): It would be nice to use support.CleanImport
-        # here, but that breaks because the os module registers some
-        # handlers in copy_reg on import. Since CleanImport doesn't
-        # revert that registration, the module is left in a broken
-        # state after reversion. Reinitialising the module contents
-        # and just reverting os.environ to its previous state is an OK
-        # workaround
-        orig_path = os.path
-        orig_getenv = os.getenv
-        with EnvironmentVarGuard():
-            x = imp.find_module("os")
-            self.addCleanup(x[0].close)
-            new_os = imp.load_module("os", *x)
-            self.assertIs(os, new_os)
-            self.assertIs(orig_path, new_os.path)
-            self.assertIsNot(orig_getenv, new_os.getenv)
-
     def test_bug7732(self):
         source = TESTFN + '.py'
         os.mkdir(source)
index 946ac46467a422fad7b865f0656b47f7122017f3..ccf60c26eb2ed12e4e521d6acbf3c4489bdd3d79 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -18,6 +18,8 @@ Core and Builtins
 Library
 -------
 
+- Issue #15828: Restore support for C extensions in imp.load_module().
+
 - Issue #15340: Fix importing the random module when /dev/urandom cannot
   be opened.  This was a regression caused by the hash randomization patch.