diff --git a/Doc/c-api/import.rst b/Doc/c-api/import.rst index f604640ebfae8d..2550ff8e224c17 100644 --- a/Doc/c-api/import.rst +++ b/Doc/c-api/import.rst @@ -327,11 +327,11 @@ Importing Modules initialization. -.. c:function:: PyObject* PyImport_GetModuleAttrString(const char *mod_name, const char *attr_name) +.. c:function:: PyObject* PyImport_GetModuleAttr(PyObject *mod_name, PyObject *attr_name) Import the module *mod_name* and get its attribute *attr_name*. - Names must be UTF-8 encoded strings. + Names must be Python :class:`str` objects. Helper function combining :c:func:`PyImport_Import` and :c:func:`PyObject_GetAttr`. For example, it can raise :exc:`ImportError` if @@ -339,3 +339,10 @@ Importing Modules exist. .. versionadded:: 3.14 + +.. c:function:: PyObject* PyImport_GetModuleAttrString(const char *mod_name, const char *attr_name) + + Similar to :c:func:`PyImport_GetModuleAttr`, but names are UTF-8 encoded + strings instead of Python :class:`str` objects. + + .. versionadded:: 3.14 diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 39c4cac2506c72..740d23ab274745 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -1301,7 +1301,8 @@ New features bit-packing Python version numbers. (Contributed by Petr Viktorin in :gh:`128629`.) -* Add :c:func:`PyImport_GetModuleAttrString` helper function to import a module +* Add :c:func:`PyImport_GetModuleAttr` and + :c:func:`PyImport_GetModuleAttrString` helper functions to import a module and get an attribute of the module. (Contributed by Victor Stinner in :gh:`128911`.) diff --git a/Include/cpython/import.h b/Include/cpython/import.h index 09b22c5940530d..7e0bdaf5b5eb01 100644 --- a/Include/cpython/import.h +++ b/Include/cpython/import.h @@ -24,6 +24,9 @@ struct _frozen { PyAPI_DATA(const struct _frozen *) PyImport_FrozenModules; +PyAPI_FUNC(PyObject*) PyImport_GetModuleAttr( + PyObject *mod_name, + PyObject *attr_name); PyAPI_FUNC(PyObject*) PyImport_GetModuleAttrString( const char *mod_name, const char *attr_name); diff --git a/Include/internal/pycore_import.h b/Include/internal/pycore_import.h index 914e460392433c..5fe60df0a92fbc 100644 --- a/Include/internal/pycore_import.h +++ b/Include/internal/pycore_import.h @@ -31,9 +31,6 @@ extern int _PyImport_FixupBuiltin( PyObject *modules ); -// Export for many shared extensions, like '_json' -PyAPI_FUNC(PyObject*) _PyImport_GetModuleAttr(PyObject *, PyObject *); - struct _import_runtime_state { /* The builtin modules (defined in config.c). */ diff --git a/Misc/NEWS.d/next/C_API/2025-01-16-12-47-01.gh-issue-128911.mHVJ4x.rst b/Misc/NEWS.d/next/C_API/2025-01-16-12-47-01.gh-issue-128911.mHVJ4x.rst index 726d9b558f794e..0021557c324421 100644 --- a/Misc/NEWS.d/next/C_API/2025-01-16-12-47-01.gh-issue-128911.mHVJ4x.rst +++ b/Misc/NEWS.d/next/C_API/2025-01-16-12-47-01.gh-issue-128911.mHVJ4x.rst @@ -1,2 +1,3 @@ -Add :c:func:`PyImport_GetModuleAttrString` helper function to import a -module and get an attribute of the module. Patch by Victor Stinner. +Add :c:func:`PyImport_GetModuleAttr` and :c:func:`PyImport_GetModuleAttrString` +helper functions to import a module and get an attribute of the module. Patch +by Victor Stinner. diff --git a/Modules/_json.c b/Modules/_json.c index a99abbe72bf7a0..dfc01df19dd26f 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -302,7 +302,7 @@ raise_errmsg(const char *msg, PyObject *s, Py_ssize_t end) /* Use JSONDecodeError exception to raise a nice looking ValueError subclass */ _Py_DECLARE_STR(json_decoder, "json.decoder"); PyObject *JSONDecodeError = - _PyImport_GetModuleAttr(&_Py_STR(json_decoder), &_Py_ID(JSONDecodeError)); + PyImport_GetModuleAttr(&_Py_STR(json_decoder), &_Py_ID(JSONDecodeError)); if (JSONDecodeError == NULL) { return; } diff --git a/Python/import.c b/Python/import.c index ab6c167dce526c..e6ffcd6b9e90cd 100644 --- a/Python/import.c +++ b/Python/import.c @@ -4174,7 +4174,7 @@ _PyImport_FiniExternal(PyInterpreterState *interp) /******************/ PyObject * -_PyImport_GetModuleAttr(PyObject *modname, PyObject *attrname) +PyImport_GetModuleAttr(PyObject *modname, PyObject *attrname) { PyObject *mod = PyImport_Import(modname); if (mod == NULL) { @@ -4197,7 +4197,7 @@ PyImport_GetModuleAttrString(const char *modname, const char *attrname) Py_DECREF(pmodname); return NULL; } - PyObject *result = _PyImport_GetModuleAttr(pmodname, pattrname); + PyObject *result = PyImport_GetModuleAttr(pmodname, pattrname); Py_DECREF(pattrname); Py_DECREF(pmodname); return result; diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 98a21571e8826c..857fc20d7c8241 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -2678,7 +2678,7 @@ create_stdio(const PyConfig *config, PyObject* io, #ifdef HAVE_WINDOWS_CONSOLE_IO /* Windows console IO is always UTF-8 encoded */ - PyTypeObject *winconsoleio_type = (PyTypeObject *)_PyImport_GetModuleAttr( + PyTypeObject *winconsoleio_type = (PyTypeObject *)PyImport_GetModuleAttr( &_Py_ID(_io), &_Py_ID(_WindowsConsoleIO)); if (winconsoleio_type == NULL) { goto error;