]> granicus.if.org Git - python/commitdiff
fix importing one char extension modules (closes #24328)
authorBenjamin Peterson <benjamin@python.org>
Fri, 29 May 2015 22:10:30 +0000 (17:10 -0500)
committerBenjamin Peterson <benjamin@python.org>
Fri, 29 May 2015 22:10:30 +0000 (17:10 -0500)
Lib/test/test_importlib/extension/test_loader.py
Misc/NEWS
Modules/_testmultiphase.c
Python/importdl.c

index 5813ade953fdf135b58b0582207ccb575462ae91..d82c805fbc7e5a9bbe3850245715ed96eeeffc51 100644 (file)
@@ -177,6 +177,14 @@ class MultiPhaseExtensionModuleTests(abc.LoaderTests):
         self.assertEqual(module.__name__, 'pkg.' + self.name)
         self.assertEqual(module.str_const, 'something different')
 
+    def test_load_short_name(self):
+        '''Test loading module with a one-character name'''
+        module = self.load_module_by_name('x')
+        self.assertIsInstance(module, types.ModuleType)
+        self.assertEqual(module.__name__, 'x')
+        self.assertEqual(module.str_const, 'something different')
+        assert 'x' not in sys.modules
+
     def test_load_twice(self):
         '''Test that 2 loads result in 2 module objects'''
         module1 = self.load_module_by_name(self.name)
index 3c38d3edd5bac89d8f7ea4cb49e2309f240d9b20..fbd5a51774180dca879321acc35fb9d20d0a795d 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,8 @@ Release date: 2015-07-05
 Core and Builtins
 -----------------
 
+- Issue #24328: Fix importing one character extension modules.
+
 - Issue #11205: In dictionary displays, evaluate the key before the value.
 
 - Issue #24285: Fixed regression that prevented importing extension modules
index 0d50db2f023db34a56a542374d7998e23bd2b520..7b98be2b8efe5b700ba4b79615481bd231ab80dd 100644 (file)
@@ -321,6 +321,14 @@ PyInitU_eckzbwbhc6jpgzcx415x(PyObject *spec)
     return PyModuleDef_Init(&def_nonascii_kana);
 }
 
+/*** Module with a single-character name ***/
+
+PyMODINIT_FUNC
+PyInit_x(PyObject *spec)
+{
+    return PyModuleDef_Init(&main_def);
+}
+
 /**** Testing NULL slots ****/
 
 static PyModuleDef null_slots_def = TEST_MODULE_DEF(
index 579d2c5fada8178caedc3a576b45745f295f8555..1aa585d5e811cabbb8de67003a698672b5f2798b 100644 (file)
@@ -34,10 +34,11 @@ static const char *nonascii_prefix = "PyInitU";
  */
 static PyObject *
 get_encoded_name(PyObject *name, const char **hook_prefix) {
-    char *buf;
     PyObject *tmp;
     PyObject *encoded = NULL;
-    Py_ssize_t name_len, lastdot, i;
+    PyObject *modname = NULL;
+    Py_ssize_t name_len, lastdot;
+    _Py_IDENTIFIER(replace);
 
     /* Get the short name (substring after last dot) */
     name_len = PyUnicode_GetLength(name);
@@ -71,16 +72,14 @@ get_encoded_name(PyObject *name, const char **hook_prefix) {
         }
     }
 
-    buf = PyBytes_AS_STRING(encoded);
-    assert(Py_REFCNT(encoded) == 1);
-    for (i = 0; i < PyBytes_GET_SIZE(encoded) + 1; i++) {
-        if (buf[i] == '-') {
-            buf[i] = '_';
-        }
-    }
+    /* Replace '-' by '_' */
+    modname = _PyObject_CallMethodId(encoded, &PyId_replace, "cc", '-', '_');
+    if (modname == NULL)
+        goto error;
 
     Py_DECREF(name);
-    return encoded;
+    Py_DECREF(encoded);
+    return modname;
 error:
     Py_DECREF(name);
     Py_XDECREF(encoded);