Skip to content

Commit e20056c

Browse files
committed
fix importing one char extension modules (closes python#24328)
1 parent a663121 commit e20056c

4 files changed

Lines changed: 27 additions & 10 deletions

File tree

‎Lib/test/test_importlib/extension/test_loader.py‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,14 @@ def test_load_submodule(self):
177177
self.assertEqual(module.__name__, 'pkg.' + self.name)
178178
self.assertEqual(module.str_const, 'something different')
179179

180+
def test_load_short_name(self):
181+
'''Test loading module with a one-character name'''
182+
module = self.load_module_by_name('x')
183+
self.assertIsInstance(module, types.ModuleType)
184+
self.assertEqual(module.__name__, 'x')
185+
self.assertEqual(module.str_const, 'something different')
186+
assert 'x' not in sys.modules
187+
180188
def test_load_twice(self):
181189
'''Test that 2 loads result in 2 module objects'''
182190
module1 = self.load_module_by_name(self.name)

‎Misc/NEWS‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ Release date: 2015-07-05
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #24328: Fix importing one character extension modules.
14+
1315
- Issue #11205: In dictionary displays, evaluate the key before the value.
1416

1517
- Issue #24285: Fixed regression that prevented importing extension modules

‎Modules/_testmultiphase.c‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,14 @@ PyInitU_eckzbwbhc6jpgzcx415x(PyObject *spec)
321321
return PyModuleDef_Init(&def_nonascii_kana);
322322
}
323323

324+
/*** Module with a single-character name ***/
325+
326+
PyMODINIT_FUNC
327+
PyInit_x(PyObject *spec)
328+
{
329+
return PyModuleDef_Init(&main_def);
330+
}
331+
324332
/**** Testing NULL slots ****/
325333

326334
static PyModuleDef null_slots_def = TEST_MODULE_DEF(

‎Python/importdl.c‎

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,11 @@ static const char *nonascii_prefix = "PyInitU";
3434
*/
3535
static PyObject *
3636
get_encoded_name(PyObject *name, const char **hook_prefix) {
37-
char *buf;
3837
PyObject *tmp;
3938
PyObject *encoded = NULL;
40-
Py_ssize_t name_len, lastdot, i;
39+
PyObject *modname = NULL;
40+
Py_ssize_t name_len, lastdot;
41+
_Py_IDENTIFIER(replace);
4142

4243
/* Get the short name (substring after last dot) */
4344
name_len = PyUnicode_GetLength(name);
@@ -71,16 +72,14 @@ get_encoded_name(PyObject *name, const char **hook_prefix) {
7172
}
7273
}
7374

74-
buf = PyBytes_AS_STRING(encoded);
75-
assert(Py_REFCNT(encoded) == 1);
76-
for (i = 0; i < PyBytes_GET_SIZE(encoded) + 1; i++) {
77-
if (buf[i] == '-') {
78-
buf[i] = '_';
79-
}
80-
}
75+
/* Replace '-' by '_' */
76+
modname = _PyObject_CallMethodId(encoded, &PyId_replace, "cc", '-', '_');
77+
if (modname == NULL)
78+
goto error;
8179

8280
Py_DECREF(name);
83-
return encoded;
81+
Py_DECREF(encoded);
82+
return modname;
8483
error:
8584
Py_DECREF(name);
8685
Py_XDECREF(encoded);

0 commit comments

Comments
 (0)