Skip to content

Commit 7f792ea

Browse files
itamarometa-codesync[bot]
authored andcommitted
Backport gh-116146: Add C-API to create module from spec and initfunc
Summary: Backport the upstream Native Python C-API, so we can start using it in 3.14 Reviewed By: jermenkoo Differential Revision: D87190522 fbshipit-source-id: 193fc9a0d2afcfb29ad7ac2e1137afbcca9296d6
1 parent ba95076 commit 7f792ea

File tree

2 files changed

+42
-19
lines changed

2 files changed

+42
-19
lines changed

Include/cpython/import.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,21 @@ PyAPI_FUNC(PyObject*) PyImport_ImportModuleAttrString(
3939
const char *mod_name,
4040
const char *attr_name);
4141

42+
// Custom importers may use this API to initialize statically linked
43+
// extension modules directly from a spec and init function,
44+
// without needing to go through inittab
45+
PyAPI_FUNC(PyObject *) PyImport_CreateModuleFromInitfunc(
46+
PyObject *spec,
47+
PyObject *(*initfunc)(void));
48+
4249
// START META PATCH (expose C API to call a module init function for statically linked extensions)
4350
// Custom importers may use this API to initialize statically linked
4451
// extension modules directly from a spec and init function,
4552
// without needing to go through inittab
53+
// TODO: migrate to the upstream version, PyImport_CreateModuleFromInitfunc, and delete this
4654
PyAPI_FUNC(PyObject *)
4755
_Ci_PyImport_CreateBuiltinFromSpecAndInitfunc(
4856
PyObject *spec,
4957
PyObject* (*initfunc)(void)
5058
);
51-
5259
// END META PATCH

Python/import.c

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2355,28 +2355,20 @@ is_builtin(PyObject *name)
23552355
return 0;
23562356
}
23572357

2358-
2359-
// START META PATCH
23602358
static PyModInitFunction
23612359
lookup_inittab_initfunc(const struct _Py_ext_module_loader_info* info)
23622360
{
2363-
struct _inittab *found = NULL;
23642361
for (struct _inittab *p = INITTAB; p->name != NULL; p++) {
23652362
if (_PyUnicode_EqualToASCIIString(info->name, p->name)) {
2366-
found = p;
2363+
return (PyModInitFunction)p->initfunc;
23672364
}
23682365
}
2369-
if (found == NULL) {
2370-
// not found
2371-
return NULL;
2372-
}
2373-
return (PyModInitFunction)found->initfunc;
2366+
// not found
2367+
return NULL;
23742368
}
23752369

2376-
2377-
23782370
static PyObject*
2379-
create_builtin_ex(
2371+
create_builtin(
23802372
PyThreadState *tstate, PyObject *name,
23812373
PyObject *spec,
23822374
PyModInitFunction initfunc)
@@ -2444,12 +2436,36 @@ create_builtin_ex(
24442436
return mod;
24452437
}
24462438

2447-
static PyObject*
2448-
create_builtin(PyThreadState *tstate, PyObject *name, PyObject *spec)
2439+
PyObject*
2440+
PyImport_CreateModuleFromInitfunc(
2441+
PyObject *spec, PyObject *(*initfunc)(void))
24492442
{
2450-
return create_builtin_ex(tstate, name, spec, NULL);
2443+
if (initfunc == NULL) {
2444+
PyErr_BadInternalCall();
2445+
return NULL;
2446+
}
2447+
2448+
PyThreadState *tstate = _PyThreadState_GET();
2449+
2450+
PyObject *name = PyObject_GetAttr(spec, &_Py_ID(name));
2451+
if (name == NULL) {
2452+
return NULL;
2453+
}
2454+
2455+
if (!PyUnicode_Check(name)) {
2456+
PyErr_Format(PyExc_TypeError,
2457+
"spec name must be string, not %T", name);
2458+
Py_DECREF(name);
2459+
return NULL;
2460+
}
2461+
2462+
PyObject *mod = create_builtin(tstate, name, spec, initfunc);
2463+
Py_DECREF(name);
2464+
return mod;
24512465
}
24522466

2467+
// START META PATCH
2468+
// TODO: migrate to the upstream version, PyImport_CreateModuleFromInitfunc, and delete this
24532469
PyObject*
24542470
_Ci_PyImport_CreateBuiltinFromSpecAndInitfunc(
24552471
PyObject *spec, PyObject* (*initfunc)(void))
@@ -2469,7 +2485,7 @@ _Ci_PyImport_CreateBuiltinFromSpecAndInitfunc(
24692485
return NULL;
24702486
}
24712487

2472-
PyObject *mod = create_builtin_ex(tstate, name, spec, initfunc);
2488+
PyObject *mod = create_builtin(tstate, name, spec, initfunc);
24732489
Py_DECREF(name);
24742490
return mod;
24752491
}
@@ -3243,7 +3259,7 @@ bootstrap_imp(PyThreadState *tstate)
32433259
}
32443260

32453261
// Create the _imp module from its definition.
3246-
PyObject *mod = create_builtin(tstate, name, spec);
3262+
PyObject *mod = create_builtin(tstate, name, spec, NULL);
32473263
Py_CLEAR(name);
32483264
Py_DECREF(spec);
32493265
if (mod == NULL) {
@@ -5802,7 +5818,7 @@ _imp_create_builtin(PyObject *module, PyObject *spec)
58025818
return NULL;
58035819
}
58045820

5805-
PyObject *mod = create_builtin(tstate, name, spec);
5821+
PyObject *mod = create_builtin(tstate, name, spec, NULL);
58065822
Py_DECREF(name);
58075823
return mod;
58085824
}

0 commit comments

Comments
 (0)