Skip to content

Commit

Permalink
Rename to PyImport_ImportModuleAttr()
Browse files Browse the repository at this point in the history
  • Loading branch information
vstinner committed Jan 26, 2025
1 parent 4fc2e10 commit 22d4856
Show file tree
Hide file tree
Showing 34 changed files with 85 additions and 85 deletions.
6 changes: 3 additions & 3 deletions Doc/c-api/import.rst
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ Importing Modules
initialization.
.. c:function:: PyObject* PyImport_GetModuleAttr(PyObject *mod_name, PyObject *attr_name)
.. c:function:: PyObject* PyImport_ImportModuleAttr(PyObject *mod_name, PyObject *attr_name)
Import the module *mod_name* and get its attribute *attr_name*.
Expand All @@ -340,9 +340,9 @@ Importing Modules
.. versionadded:: 3.14
.. c:function:: PyObject* PyImport_GetModuleAttrString(const char *mod_name, const char *attr_name)
.. c:function:: PyObject* PyImport_ImportModuleAttrString(const char *mod_name, const char *attr_name)
Similar to :c:func:`PyImport_GetModuleAttr`, but names are UTF-8 encoded
Similar to :c:func:`PyImport_ImportModuleAttr`, but names are UTF-8 encoded
strings instead of Python :class:`str` objects.
.. versionadded:: 3.14
12 changes: 6 additions & 6 deletions Doc/data/refcounts.dat
Original file line number Diff line number Diff line change
Expand Up @@ -3053,10 +3053,10 @@ _Py_c_sum:Py_complex:::
_Py_c_sum:Py_complex:left::
_Py_c_sum:Py_complex:right::

PyImport_GetModuleAttr:PyObject*::+1:
PyImport_GetModuleAttr:PyObject*:mod_name:0:
PyImport_GetModuleAttr:PyObject*:attr_name:0:
PyImport_ImportModuleAttr:PyObject*::+1:
PyImport_ImportModuleAttr:PyObject*:mod_name:0:
PyImport_ImportModuleAttr:PyObject*:attr_name:0:

PyImport_GetModuleAttrString:PyObject*::+1:
PyImport_GetModuleAttrString:const char *:mod_name::
PyImport_GetModuleAttrString:const char *:attr_name::
PyImport_ImportModuleAttrString:PyObject*::+1:
PyImport_ImportModuleAttrString:const char *:mod_name::
PyImport_ImportModuleAttrString:const char *:attr_name::
4 changes: 2 additions & 2 deletions Doc/whatsnew/3.14.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1301,8 +1301,8 @@ New features
bit-packing Python version numbers.
(Contributed by Petr Viktorin in :gh:`128629`.)

* Add :c:func:`PyImport_GetModuleAttr` and
:c:func:`PyImport_GetModuleAttrString` helper functions to import a module
* Add :c:func:`PyImport_ImportModuleAttr` and
:c:func:`PyImport_ImportModuleAttrString` helper functions to import a module
and get an attribute of the module.
(Contributed by Victor Stinner in :gh:`128911`.)

Expand Down
4 changes: 2 additions & 2 deletions Include/cpython/import.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ struct _frozen {

PyAPI_DATA(const struct _frozen *) PyImport_FrozenModules;

PyAPI_FUNC(PyObject*) PyImport_GetModuleAttr(
PyAPI_FUNC(PyObject*) PyImport_ImportModuleAttr(
PyObject *mod_name,
PyObject *attr_name);
PyAPI_FUNC(PyObject*) PyImport_GetModuleAttrString(
PyAPI_FUNC(PyObject*) PyImport_ImportModuleAttrString(
const char *mod_name,
const char *attr_name);
46 changes: 23 additions & 23 deletions Lib/test/test_capi/test_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,58 +318,58 @@ def test_executecodemoduleobject(self):
# CRASHES execute_code_func(NULL, code, NULL, NULL)
# CRASHES execute_code_func(name, NULL, NULL, NULL)

def check_getmoduleattr(self, getmoduleattr):
self.assertIs(getmoduleattr('sys', 'argv'), sys.argv)
self.assertIs(getmoduleattr('types', 'ModuleType'), types.ModuleType)
def check_importmoduleattr(self, importmoduleattr):
self.assertIs(importmoduleattr('sys', 'argv'), sys.argv)
self.assertIs(importmoduleattr('types', 'ModuleType'), types.ModuleType)

# module name containing a dot
attr = getmoduleattr('email.message', 'Message')
attr = importmoduleattr('email.message', 'Message')
from email.message import Message
self.assertIs(attr, Message)

with self.assertRaises(ImportError):
# nonexistent module
getmoduleattr('nonexistentmodule', 'attr')
importmoduleattr('nonexistentmodule', 'attr')
with self.assertRaises(AttributeError):
# nonexistent attribute
getmoduleattr('sys', 'nonexistentattr')
importmoduleattr('sys', 'nonexistentattr')
with self.assertRaises(AttributeError):
# attribute name containing a dot
getmoduleattr('sys', 'implementation.name')
importmoduleattr('sys', 'implementation.name')

def test_getmoduleattr(self):
# Test PyImport_GetModuleAttr()
getmoduleattr = _testcapi.PyImport_GetModuleAttr
self.check_getmoduleattr(getmoduleattr)
def test_importmoduleattr(self):
# Test PyImport_ImportModuleAttr()
importmoduleattr = _testcapi.PyImport_ImportModuleAttr
self.check_importmoduleattr(importmoduleattr)

# Invalid module name type
for mod_name in (object(), 123, b'bytes'):
with self.subTest(mod_name=mod_name):
with self.assertRaises(TypeError):
getmoduleattr(mod_name, "attr")
importmoduleattr(mod_name, "attr")

# Invalid attribute name type
for attr_name in (object(), 123, b'bytes'):
with self.subTest(attr_name=attr_name):
with self.assertRaises(TypeError):
getmoduleattr("sys", attr_name)
importmoduleattr("sys", attr_name)

with self.assertRaises(SystemError):
getmoduleattr(NULL, "argv")
# CRASHES getmoduleattr("sys", NULL)
importmoduleattr(NULL, "argv")
# CRASHES importmoduleattr("sys", NULL)

def test_getmoduleattrstring(self):
# Test PyImport_GetModuleAttrString()
getmoduleattr = _testcapi.PyImport_GetModuleAttrString
self.check_getmoduleattr(getmoduleattr)
def test_importmoduleattrstring(self):
# Test PyImport_ImportModuleAttrString()
importmoduleattr = _testcapi.PyImport_ImportModuleAttrString
self.check_importmoduleattr(importmoduleattr)

with self.assertRaises(UnicodeDecodeError):
getmoduleattr(b"sys\xff", "argv")
importmoduleattr(b"sys\xff", "argv")
with self.assertRaises(UnicodeDecodeError):
getmoduleattr("sys", b"argv\xff")
importmoduleattr("sys", b"argv\xff")

# CRASHES getmoduleattr(NULL, "argv")
# CRASHES getmoduleattr("sys", NULL)
# CRASHES importmoduleattr(NULL, "argv")
# CRASHES importmoduleattr("sys", NULL)

# TODO: test PyImport_GetImporter()
# TODO: test PyImport_ReloadModule()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Add :c:func:`PyImport_GetModuleAttr` and :c:func:`PyImport_GetModuleAttrString`
Add :c:func:`PyImport_ImportModuleAttr` and :c:func:`PyImport_ImportModuleAttrString`
helper functions to import a module and get an attribute of the module. Patch
by Victor Stinner.
2 changes: 1 addition & 1 deletion Modules/_ctypes/callbacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
if (context == NULL)
context = PyUnicode_InternFromString("_ctypes.DllGetClassObject");

func = PyImport_GetModuleAttrString("ctypes", "DllGetClassObject");
func = PyImport_ImportModuleAttrString("ctypes", "DllGetClassObject");
if (!func) {
PyErr_WriteUnraisable(context ? context : Py_None);
/* There has been a warning before about this already */
Expand Down
2 changes: 1 addition & 1 deletion Modules/_ctypes/stgdict.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ PyCStructUnionType_update_stginfo(PyObject *type, PyObject *fields, int isStruct
goto error;
}

PyObject *layout_func = PyImport_GetModuleAttrString("ctypes._layout",
PyObject *layout_func = PyImport_ImportModuleAttrString("ctypes._layout",
"get_layout");
if (!layout_func) {
goto error;
Expand Down
2 changes: 1 addition & 1 deletion Modules/_cursesmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ _PyCursesCheckFunction(int called, const char *funcname)
if (called == TRUE) {
return 1;
}
PyObject *exc = PyImport_GetModuleAttrString("_curses", "error");
PyObject *exc = PyImport_ImportModuleAttrString("_curses", "error");
if (exc != NULL) {
PyErr_Format(exc, "must call %s() first", funcname);
Py_DECREF(exc);
Expand Down
6 changes: 3 additions & 3 deletions Modules/_datetimemodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1839,7 +1839,7 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
assert(object && format && timetuple);
assert(PyUnicode_Check(format));

PyObject *strftime = PyImport_GetModuleAttrString("time", "strftime");
PyObject *strftime = PyImport_ImportModuleAttrString("time", "strftime");
if (strftime == NULL) {
return NULL;
}
Expand Down Expand Up @@ -2021,7 +2021,7 @@ static PyObject *
time_time(void)
{
PyObject *result = NULL;
PyObject *time = PyImport_GetModuleAttrString("time", "time");
PyObject *time = PyImport_ImportModuleAttrString("time", "time");

if (time != NULL) {
result = PyObject_CallNoArgs(time);
Expand All @@ -2039,7 +2039,7 @@ build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
PyObject *struct_time;
PyObject *result;

struct_time = PyImport_GetModuleAttrString("time", "struct_time");
struct_time = PyImport_ImportModuleAttrString("time", "struct_time");
if (struct_time == NULL) {
return NULL;
}
Expand Down
2 changes: 1 addition & 1 deletion Modules/_decimal/_decimal.c
Original file line number Diff line number Diff line change
Expand Up @@ -3464,7 +3464,7 @@ pydec_format(PyObject *dec, PyObject *context, PyObject *fmt, decimal_state *sta
PyObject *u;

if (state->PyDecimal == NULL) {
state->PyDecimal = PyImport_GetModuleAttrString("_pydecimal", "Decimal");
state->PyDecimal = PyImport_ImportModuleAttrString("_pydecimal", "Decimal");
if (state->PyDecimal == NULL) {
return NULL;
}
Expand Down
4 changes: 2 additions & 2 deletions Modules/_elementtree.c
Original file line number Diff line number Diff line change
Expand Up @@ -4392,7 +4392,7 @@ module_exec(PyObject *m)
CREATE_TYPE(m, st->Element_Type, &element_spec);
CREATE_TYPE(m, st->XMLParser_Type, &xmlparser_spec);

st->deepcopy_obj = PyImport_GetModuleAttrString("copy", "deepcopy");
st->deepcopy_obj = PyImport_ImportModuleAttrString("copy", "deepcopy");
if (st->deepcopy_obj == NULL) {
goto error;
}
Expand All @@ -4402,7 +4402,7 @@ module_exec(PyObject *m)
goto error;

/* link against pyexpat */
if (!(st->expat_capsule = PyImport_GetModuleAttrString("pyexpat", "expat_CAPI")))
if (!(st->expat_capsule = PyImport_ImportModuleAttrString("pyexpat", "expat_CAPI")))
goto error;
if (!(st->expat_capi = PyCapsule_GetPointer(st->expat_capsule, PyExpat_CAPSULE_NAME)))
goto error;
Expand Down
2 changes: 1 addition & 1 deletion Modules/_json.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_ImportModuleAttr(&_Py_STR(json_decoder), &_Py_ID(JSONDecodeError));
if (JSONDecodeError == NULL) {
return;
}
Expand Down
6 changes: 3 additions & 3 deletions Modules/_lsprof.c
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,7 @@ _lsprof_Profiler_enable_impl(ProfilerObject *self, int subcalls,
return NULL;
}

PyObject* monitoring = PyImport_GetModuleAttrString("sys", "monitoring");
PyObject* monitoring = PyImport_ImportModuleAttrString("sys", "monitoring");
if (!monitoring) {
return NULL;
}
Expand Down Expand Up @@ -857,7 +857,7 @@ _lsprof_Profiler_disable_impl(ProfilerObject *self)
}
if (self->flags & POF_ENABLED) {
PyObject* result = NULL;
PyObject* monitoring = PyImport_GetModuleAttrString("sys", "monitoring");
PyObject* monitoring = PyImport_ImportModuleAttrString("sys", "monitoring");

if (!monitoring) {
return NULL;
Expand Down Expand Up @@ -973,7 +973,7 @@ profiler_init_impl(ProfilerObject *self, PyObject *timer, double timeunit,
Py_XSETREF(self->externalTimer, Py_XNewRef(timer));
self->tool_id = PY_MONITORING_PROFILER_ID;

PyObject* monitoring = PyImport_GetModuleAttrString("sys", "monitoring");
PyObject* monitoring = PyImport_ImportModuleAttrString("sys", "monitoring");
if (!monitoring) {
return -1;
}
Expand Down
2 changes: 1 addition & 1 deletion Modules/_operator.c
Original file line number Diff line number Diff line change
Expand Up @@ -1868,7 +1868,7 @@ methodcaller_reduce(methodcallerobject *mc, PyObject *Py_UNUSED(ignored))
PyObject *constructor;
PyObject *newargs[2];

partial = PyImport_GetModuleAttrString("functools", "partial");
partial = PyImport_ImportModuleAttrString("functools", "partial");
if (!partial)
return NULL;

Expand Down
4 changes: 2 additions & 2 deletions Modules/_pickle.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ _Pickle_InitState(PickleState *st)
}
Py_CLEAR(compat_pickle);

st->codecs_encode = PyImport_GetModuleAttrString("codecs", "encode");
st->codecs_encode = PyImport_ImportModuleAttrString("codecs", "encode");
if (st->codecs_encode == NULL) {
goto error;
}
Expand All @@ -373,7 +373,7 @@ _Pickle_InitState(PickleState *st)
goto error;
}

st->partial = PyImport_GetModuleAttrString("functools", "partial");
st->partial = PyImport_ImportModuleAttrString("functools", "partial");
if (!st->partial)
goto error;

Expand Down
2 changes: 1 addition & 1 deletion Modules/_sqlite/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -1994,7 +1994,7 @@ pysqlite_connection_iterdump_impl(pysqlite_Connection *self,
return NULL;
}

PyObject *iterdump = PyImport_GetModuleAttrString(MODULE_NAME ".dump", "_iterdump");
PyObject *iterdump = PyImport_ImportModuleAttrString(MODULE_NAME ".dump", "_iterdump");
if (!iterdump) {
if (!PyErr_Occurred()) {
PyErr_SetString(self->OperationalError,
Expand Down
2 changes: 1 addition & 1 deletion Modules/_sqlite/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ static int
load_functools_lru_cache(PyObject *module)
{
pysqlite_state *state = pysqlite_get_state(module);
state->lru_cache = PyImport_GetModuleAttrString("functools", "lru_cache");
state->lru_cache = PyImport_ImportModuleAttrString("functools", "lru_cache");
if (state->lru_cache == NULL) {
return -1;
}
Expand Down
2 changes: 1 addition & 1 deletion Modules/_sre/sre.c
Original file line number Diff line number Diff line change
Expand Up @@ -1169,7 +1169,7 @@ compile_template(_sremodulestate *module_state,
/* delegate to Python code */
PyObject *func = module_state->compile_template;
if (func == NULL) {
func = PyImport_GetModuleAttrString("re", "_compile_template");
func = PyImport_ImportModuleAttrString("re", "_compile_template");
if (func == NULL) {
return NULL;
}
Expand Down
12 changes: 6 additions & 6 deletions Modules/_testcapi/import.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "parts.h"
#include "util.h"

// Test PyImport_GetModuleAttr()
// Test PyImport_ImportModuleAttr()
static PyObject *
pyimport_getmoduleattr(PyObject *self, PyObject *args)
{
Expand All @@ -12,11 +12,11 @@ pyimport_getmoduleattr(PyObject *self, PyObject *args)
NULLABLE(mod_name);
NULLABLE(attr_name);

return PyImport_GetModuleAttr(mod_name, attr_name);
return PyImport_ImportModuleAttr(mod_name, attr_name);
}


// Test PyImport_GetModuleAttrString()
// Test PyImport_ImportModuleAttrString()
static PyObject *
pyimport_getmoduleattrstring(PyObject *self, PyObject *args)
{
Expand All @@ -26,13 +26,13 @@ pyimport_getmoduleattrstring(PyObject *self, PyObject *args)
return NULL;
}

return PyImport_GetModuleAttrString(mod_name, attr_name);
return PyImport_ImportModuleAttrString(mod_name, attr_name);
}


static PyMethodDef test_methods[] = {
{"PyImport_GetModuleAttr", pyimport_getmoduleattr, METH_VARARGS},
{"PyImport_GetModuleAttrString", pyimport_getmoduleattrstring, METH_VARARGS},
{"PyImport_ImportModuleAttr", pyimport_getmoduleattr, METH_VARARGS},
{"PyImport_ImportModuleAttrString", pyimport_getmoduleattrstring, METH_VARARGS},
{NULL},
};

Expand Down
8 changes: 4 additions & 4 deletions Modules/_zoneinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,7 @@ zoneinfo_reduce(PyObject *obj_self, PyObject *unused)
if (self->source == SOURCE_FILE) {
// Objects constructed from files cannot be pickled.
PyObject *pickle_error =
PyImport_GetModuleAttrString("pickle", "PicklingError");
PyImport_ImportModuleAttrString("pickle", "PicklingError");
if (pickle_error == NULL) {
return NULL;
}
Expand Down Expand Up @@ -2554,7 +2554,7 @@ static PyObject *
new_weak_cache(void)
{
PyObject *WeakValueDictionary =
PyImport_GetModuleAttrString("weakref", "WeakValueDictionary");
PyImport_ImportModuleAttrString("weakref", "WeakValueDictionary");
if (WeakValueDictionary == NULL) {
return NULL;
}
Expand Down Expand Up @@ -2732,12 +2732,12 @@ zoneinfomodule_exec(PyObject *m)

/* Populate imports */
state->_tzpath_find_tzfile =
PyImport_GetModuleAttrString("zoneinfo._tzpath", "find_tzfile");
PyImport_ImportModuleAttrString("zoneinfo._tzpath", "find_tzfile");
if (state->_tzpath_find_tzfile == NULL) {
goto error;
}

state->io_open = PyImport_GetModuleAttrString("io", "open");
state->io_open = PyImport_ImportModuleAttrString("io", "open");
if (state->io_open == NULL) {
goto error;
}
Expand Down
Loading

0 comments on commit 22d4856

Please sign in to comment.