Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Include/internal/pycore_modsupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ extern PyObject ** _Py_VaBuildStack(
Py_ssize_t *p_nargs);

extern PyObject* _PyModule_CreateInitialized(PyModuleDef*, int apiver);
extern PyObject *_PyModule_CreateInitializedImmortalMethods(PyModuleDef* module, int module_api_version);

// Export for '_curses' shared extension
PyAPI_FUNC(int) _PyArg_ParseStack(
Expand Down Expand Up @@ -91,6 +92,8 @@ PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywords(
_PyArg_UnpackKeywords((args), (nargs), (kwargs), (kwnames), (parser), \
(minpos), (maxpos), (minkw), (varpos), (buf)))

extern int _PyModule_AddFunctionsImmortal(PyObject *m, PyMethodDef *functions);

#ifdef __cplusplus
}
#endif
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Nearly all builtin functions are now immortal.
47 changes: 40 additions & 7 deletions Objects/moduleobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ check_api_version(const char *name, int module_api_version)
}

static int
_add_methods_to_object(PyObject *module, PyObject *name, PyMethodDef *functions)
_add_methods_to_object(PyObject *module, PyObject *name, PyMethodDef *functions, int immortalize_methods)
{
PyObject *func;
PyMethodDef *fdef;
Expand All @@ -188,7 +188,12 @@ _add_methods_to_object(PyObject *module, PyObject *name, PyMethodDef *functions)
if (func == NULL) {
return -1;
}
_PyObject_SetDeferredRefcount(func);
if (immortalize_methods) {
_Py_SetImmortal(func);
}
else {
_PyObject_SetDeferredRefcount(func);
}
if (PyObject_SetAttrString(module, fdef->ml_name, func) != 0) {
Py_DECREF(func);
return -1;
Expand All @@ -210,8 +215,10 @@ PyModule_Create2(PyModuleDef* module, int module_api_version)
return _PyModule_CreateInitialized(module, module_api_version);
}

PyObject *
_PyModule_CreateInitialized(PyModuleDef* module, int module_api_version)
typedef int (*module_addfunctions_ptr)(PyObject *, PyMethodDef *);

static PyObject *
module_createinitialized_impl(PyModuleDef* module, int module_api_version, module_addfunctions_ptr module_addfunctions)
{
const char* name;
PyModuleObject *m;
Expand Down Expand Up @@ -245,7 +252,7 @@ _PyModule_CreateInitialized(PyModuleDef* module, int module_api_version)
}

if (module->m_methods != NULL) {
if (PyModule_AddFunctions((PyObject *) m, module->m_methods) != 0) {
if (module_addfunctions((PyObject *) m, module->m_methods) != 0) {
Py_DECREF(m);
return NULL;
}
Expand All @@ -263,6 +270,18 @@ _PyModule_CreateInitialized(PyModuleDef* module, int module_api_version)
return (PyObject*)m;
}

PyObject *
_PyModule_CreateInitialized(PyModuleDef* module, int module_api_version)
{
return module_createinitialized_impl(module, module_api_version, PyModule_AddFunctions);
}

PyObject *
_PyModule_CreateInitializedImmortalMethods(PyModuleDef* module, int module_api_version)
{
return module_createinitialized_impl(module, module_api_version, _PyModule_AddFunctionsImmortal);
}

PyObject *
PyModule_FromDefAndSpec2(PyModuleDef* def, PyObject *spec, int module_api_version)
{
Expand Down Expand Up @@ -422,7 +441,7 @@ PyModule_FromDefAndSpec2(PyModuleDef* def, PyObject *spec, int module_api_versio
}

if (def->m_methods != NULL) {
ret = _add_methods_to_object(m, nameobj, def->m_methods);
ret = _add_methods_to_object(m, nameobj, def->m_methods, 0);
if (ret != 0) {
goto error;
}
Expand Down Expand Up @@ -535,7 +554,21 @@ PyModule_AddFunctions(PyObject *m, PyMethodDef *functions)
return -1;
}

res = _add_methods_to_object(m, name, functions);
res = _add_methods_to_object(m, name, functions, 0);
Py_DECREF(name);
return res;
}

int
_PyModule_AddFunctionsImmortal(PyObject *m, PyMethodDef *functions)
{
int res;
PyObject *name = PyModule_GetNameObject(m);
if (name == NULL) {
return -1;
}

res = _add_methods_to_object(m, name, functions, 1);
Py_DECREF(name);
return res;
}
Expand Down
2 changes: 1 addition & 1 deletion Python/bltinmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -3414,7 +3414,7 @@ _PyBuiltin_Init(PyInterpreterState *interp)

const PyConfig *config = _PyInterpreterState_GetConfig(interp);

mod = _PyModule_CreateInitialized(&builtinsmodule, PYTHON_API_VERSION);
mod = _PyModule_CreateInitializedImmortalMethods(&builtinsmodule, PYTHON_API_VERSION);
if (mod == NULL)
return NULL;
#ifdef Py_GIL_DISABLED
Expand Down
Loading