[Python-checkins] cpython: Issue #15828: Restore support for C extension modules in imp.load_module()

georg.brandl python-checkins at python.org
Sun Sep 9 11:19:06 CEST 2012


http://hg.python.org/cpython/rev/4f6f59303146
changeset:   78902:4f6f59303146
user:        Nick Coghlan <ncoghlan at gmail.com>
date:        Sat Sep 01 00:13:45 2012 +1000
summary:
  Issue #15828: Restore support for C extension modules in imp.load_module()

files:
  Lib/imp.py              |   6 ++++--
  Lib/test/test_imp.py    |  29 +++++++++++++++++++++++++++++
  Lib/test/test_import.py |  19 -------------------
  Misc/NEWS               |   2 ++
  4 files changed, 35 insertions(+), 21 deletions(-)


diff --git a/Lib/imp.py b/Lib/imp.py
--- a/Lib/imp.py
+++ b/Lib/imp.py
@@ -153,13 +153,15 @@
         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 @@
         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)
 
 
diff --git a/Lib/test/test_imp.py b/Lib/test/test_imp.py
--- a/Lib/test/test_imp.py
+++ b/Lib/test/test_imp.py
@@ -186,6 +186,35 @@
         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
diff --git a/Lib/test/test_import.py b/Lib/test/test_import.py
--- a/Lib/test/test_import.py
+++ b/Lib/test/test_import.py
@@ -149,25 +149,6 @@
 
         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)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -18,6 +18,8 @@
 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.
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list