Skip to content

Commit 403c7e2

Browse files
committed
gh-116146: Add new C-API to create builtin from spec and initfunc
1 parent be1c72a commit 403c7e2

File tree

2 files changed

+66
-19
lines changed

2 files changed

+66
-19
lines changed

Include/cpython/import.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ struct _inittab {
1010
PyAPI_DATA(struct _inittab *) PyImport_Inittab;
1111
PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab);
1212

13+
// Custom importers may use this API to initialize statically linked
14+
// extension modules directly from a spec and init function,
15+
// without needing to go through inittab
16+
PyAPI_FUNC(PyObject *)
17+
PyImport_CreateBuiltinFromSpecAndInitfunc(
18+
PyObject *spec,
19+
PyObject* (*initfunc)(void)
20+
);
21+
1322
struct _frozen {
1423
const char *name; /* ASCII encoded string */
1524
const unsigned char *code;

Python/import.c

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2362,8 +2362,27 @@ is_builtin(PyObject *name)
23622362
return 0;
23632363
}
23642364

2365+
static PyModInitFunction
2366+
lookup_inittab_initfunc(const struct _Py_ext_module_loader_info* info)
2367+
{
2368+
struct _inittab *found = NULL;
2369+
for (struct _inittab *p = INITTAB; p->name != NULL; p++) {
2370+
if (_PyUnicode_EqualToASCIIString(info->name, p->name)) {
2371+
found = p;
2372+
}
2373+
}
2374+
if (found == NULL) {
2375+
// not found
2376+
return NULL;
2377+
}
2378+
return (PyModInitFunction)found->initfunc;
2379+
}
2380+
23652381
static PyObject*
2366-
create_builtin(PyThreadState *tstate, PyObject *name, PyObject *spec)
2382+
create_builtin_ex(
2383+
PyThreadState *tstate, PyObject *name,
2384+
PyObject *spec,
2385+
PyModInitFunction initfunc)
23672386
{
23682387
struct _Py_ext_module_loader_info info;
23692388
if (_Py_ext_module_loader_info_init_for_builtin(&info, name) < 0) {
@@ -2394,25 +2413,15 @@ create_builtin(PyThreadState *tstate, PyObject *name, PyObject *spec)
23942413
_extensions_cache_delete(info.path, info.name);
23952414
}
23962415

2397-
struct _inittab *found = NULL;
2398-
for (struct _inittab *p = INITTAB; p->name != NULL; p++) {
2399-
if (_PyUnicode_EqualToASCIIString(info.name, p->name)) {
2400-
found = p;
2401-
break;
2402-
}
2403-
}
2404-
if (found == NULL) {
2405-
// not found
2406-
mod = Py_NewRef(Py_None);
2407-
goto finally;
2408-
}
2409-
2410-
PyModInitFunction p0 = (PyModInitFunction)found->initfunc;
2416+
PyModInitFunction p0 = initfunc;
24112417
if (p0 == NULL) {
2412-
/* Cannot re-init internal module ("sys" or "builtins") */
2413-
assert(is_core_module(tstate->interp, info.name, info.path));
2414-
mod = import_add_module(tstate, info.name);
2415-
goto finally;
2418+
p0 = lookup_inittab_initfunc(&info);
2419+
if (p0 == NULL) {
2420+
/* Cannot re-init internal module ("sys" or "builtins") */
2421+
assert(is_core_module(tstate->interp, info.name, info.path));
2422+
mod = import_add_module(tstate, info.name);
2423+
goto finally;
2424+
}
24162425
}
24172426

24182427
#ifdef Py_GIL_DISABLED
@@ -2438,6 +2447,35 @@ create_builtin(PyThreadState *tstate, PyObject *name, PyObject *spec)
24382447
return mod;
24392448
}
24402449

2450+
static PyObject*
2451+
create_builtin(PyThreadState *tstate, PyObject *name, PyObject *spec)
2452+
{
2453+
return create_builtin_ex(tstate, name, spec, NULL);
2454+
}
2455+
2456+
PyObject*
2457+
PyImport_CreateBuiltinFromSpecAndInitfunc(
2458+
PyObject *spec, PyObject* (*initfunc)(void))
2459+
{
2460+
PyThreadState *tstate = _PyThreadState_GET();
2461+
2462+
PyObject *name = PyObject_GetAttrString(spec, "name");
2463+
if (name == NULL) {
2464+
return NULL;
2465+
}
2466+
2467+
if (!PyUnicode_Check(name)) {
2468+
PyErr_Format(PyExc_TypeError,
2469+
"name must be string, not %.200s",
2470+
Py_TYPE(name)->tp_name);
2471+
Py_DECREF(name);
2472+
return NULL;
2473+
}
2474+
2475+
PyObject *mod = create_builtin_ex(tstate, name, spec, initfunc);
2476+
Py_DECREF(name);
2477+
return mod;
2478+
}
24412479

24422480
/*****************************/
24432481
/* the builtin modules table */

0 commit comments

Comments
 (0)