https://github.com/python/cpython/commit/dc804ffb2f7cfaf60916b36f3d5cac9c00e4f1ea
commit: dc804ffb2f7cfaf60916b36f3d5cac9c00e4f1ea
branch: main
author: Victor Stinner <vstin...@python.org>
committer: vstinner <vstin...@python.org>
date: 2025-02-05T11:03:58+01:00
summary:

gh-128911: Use PyImport_ImportModuleAttr() function (#129657)

* Replace PyImport_ImportModule() + PyObject_GetAttr() with
  PyImport_ImportModuleAttr().
* Replace PyImport_ImportModule() + PyObject_GetAttrString() with
  PyImport_ImportModuleAttrString().

files:
M Modules/_ctypes/callbacks.c
M Modules/_ctypes/stgdict.c
M Modules/_testcapi/code.c
M Modules/_testcapimodule.c
M Modules/main.c
M Python/crossinterp.c
M Python/pythonrun.c

diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c
index b84bd25af8ec2c..6dd6f6ec56d008 100644
--- a/Modules/_ctypes/callbacks.c
+++ b/Modules/_ctypes/callbacks.c
@@ -551,31 +551,19 @@ STDAPI DllGetClassObject(REFCLSID rclsid,
 
 long Call_CanUnloadNow(void)
 {
-    PyObject *mod, *func, *result;
-    long retval;
-
-    mod = PyImport_ImportModule("ctypes");
-    if (!mod) {
-/*              OutputDebugString("Could not import ctypes"); */
-        /* We assume that this error can only occur when shutting
-           down, so we silently ignore it */
-        PyErr_Clear();
-        return E_FAIL;
-    }
-    /* Other errors cannot be raised, but are printed to stderr */
-    func = PyObject_GetAttrString(mod, "DllCanUnloadNow");
-    Py_DECREF(mod);
+    PyObject *func = PyImport_ImportModuleAttrString("ctypes",
+                                                     "DllCanUnloadNow");
     if (!func) {
         goto error;
     }
 
-    result = _PyObject_CallNoArgs(func);
+    PyObject *result = _PyObject_CallNoArgs(func);
     Py_DECREF(func);
     if (!result) {
         goto error;
     }
 
-    retval = PyLong_AsLong(result);
+    long retval = PyLong_AsLong(result);
     if (PyErr_Occurred()) {
         Py_DECREF(result);
         goto error;
diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c
index d63a46a3bc23d2..05239d85c44d2c 100644
--- a/Modules/_ctypes/stgdict.c
+++ b/Modules/_ctypes/stgdict.c
@@ -258,7 +258,7 @@ PyCStructUnionType_update_stginfo(PyObject *type, PyObject 
*fields, int isStruct
     }
 
     PyObject *layout_func = PyImport_ImportModuleAttrString("ctypes._layout",
-                                                          "get_layout");
+                                                            "get_layout");
     if (!layout_func) {
         goto error;
     }
diff --git a/Modules/_testcapi/code.c b/Modules/_testcapi/code.c
index c0193489b6f340..94f752c9726189 100644
--- a/Modules/_testcapi/code.c
+++ b/Modules/_testcapi/code.c
@@ -47,7 +47,6 @@ static PyObject *
 test_code_extra(PyObject* self, PyObject *Py_UNUSED(callable))
 {
     PyObject *result = NULL;
-    PyObject *test_module = NULL;
     PyObject *test_func = NULL;
 
     // Get or initialize interpreter-specific code object storage index
@@ -62,11 +61,8 @@ test_code_extra(PyObject* self, PyObject 
*Py_UNUSED(callable))
 
     // Get a function to test with
     // This can be any Python function. Use `test.test_misc.testfunction`.
-    test_module = PyImport_ImportModule("test.test_capi.test_misc");
-    if (!test_module) {
-        goto finally;
-    }
-    test_func = PyObject_GetAttrString(test_module, "testfunction");
+    test_func = PyImport_ImportModuleAttrString("test.test_capi.test_misc",
+                                                "testfunction");
     if (!test_func) {
         goto finally;
     }
@@ -102,7 +98,6 @@ test_code_extra(PyObject* self, PyObject 
*Py_UNUSED(callable))
     }
     result = Py_NewRef(Py_None);
 finally:
-    Py_XDECREF(test_module);
     Py_XDECREF(test_func);
     return result;
 }
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 09e74fd3cf20af..c84646ccf03fa7 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -1057,15 +1057,10 @@ test_pep3118_obsolete_write_locks(PyObject* self, 
PyObject *Py_UNUSED(ignored))
     if (ret != -1 || match == 0)
         goto error;
 
-    PyObject *mod_io = PyImport_ImportModule("_io");
-    if (mod_io == NULL) {
-        return NULL;
-    }
-
     /* bytesiobuf_getbuffer() */
-    PyTypeObject *type = (PyTypeObject *)PyObject_GetAttrString(
-            mod_io, "_BytesIOBuffer");
-    Py_DECREF(mod_io);
+    PyTypeObject *type = (PyTypeObject *)PyImport_ImportModuleAttrString(
+        "_io",
+        "_BytesIOBuffer");
     if (type == NULL) {
         return NULL;
     }
diff --git a/Modules/main.c b/Modules/main.c
index 5bb1de2d04d30c..f8a2438cdd0d93 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -314,25 +314,19 @@ pymain_start_pyrepl_no_main(void)
 static int
 pymain_run_module(const wchar_t *modname, int set_argv0)
 {
-    PyObject *module, *runpy, *runmodule, *runargs, *result;
+    PyObject *module, *runmodule, *runargs, *result;
     if (PySys_Audit("cpython.run_module", "u", modname) < 0) {
         return pymain_exit_err_print();
     }
-    runpy = PyImport_ImportModule("runpy");
-    if (runpy == NULL) {
-        fprintf(stderr, "Could not import runpy module\n");
-        return pymain_exit_err_print();
-    }
-    runmodule = PyObject_GetAttrString(runpy, "_run_module_as_main");
+    runmodule = PyImport_ImportModuleAttrString("runpy",
+                                                "_run_module_as_main");
     if (runmodule == NULL) {
-        fprintf(stderr, "Could not access runpy._run_module_as_main\n");
-        Py_DECREF(runpy);
+        fprintf(stderr, "Could not import runpy._run_module_as_main\n");
         return pymain_exit_err_print();
     }
     module = PyUnicode_FromWideChar(modname, wcslen(modname));
     if (module == NULL) {
         fprintf(stderr, "Could not convert module name to unicode\n");
-        Py_DECREF(runpy);
         Py_DECREF(runmodule);
         return pymain_exit_err_print();
     }
@@ -340,7 +334,6 @@ pymain_run_module(const wchar_t *modname, int set_argv0)
     if (runargs == NULL) {
         fprintf(stderr,
             "Could not create arguments for runpy._run_module_as_main\n");
-        Py_DECREF(runpy);
         Py_DECREF(runmodule);
         Py_DECREF(module);
         return pymain_exit_err_print();
@@ -350,7 +343,6 @@ pymain_run_module(const wchar_t *modname, int set_argv0)
     if (!result && PyErr_Occurred() == PyExc_KeyboardInterrupt) {
         _PyRuntime.signals.unhandled_keyboard_interrupt = 1;
     }
-    Py_DECREF(runpy);
     Py_DECREF(runmodule);
     Py_DECREF(module);
     Py_DECREF(runargs);
@@ -497,24 +489,22 @@ pymain_run_startup(PyConfig *config, int *exitcode)
 static int
 pymain_run_interactive_hook(int *exitcode)
 {
-    PyObject *sys, *hook, *result;
-    sys = PyImport_ImportModule("sys");
-    if (sys == NULL) {
-        goto error;
-    }
-
-    hook = PyObject_GetAttrString(sys, "__interactivehook__");
-    Py_DECREF(sys);
+    PyObject *hook = PyImport_ImportModuleAttrString("sys",
+                                                     "__interactivehook__");
     if (hook == NULL) {
-        PyErr_Clear();
-        return 0;
+        if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
+            // no sys.__interactivehook__ attribute
+            PyErr_Clear();
+            return 0;
+        }
+        goto error;
     }
 
     if (PySys_Audit("cpython.run_interactivehook", "O", hook) < 0) {
         goto error;
     }
 
-    result = _PyObject_CallNoArgs(hook);
+    PyObject *result = _PyObject_CallNoArgs(hook);
     Py_DECREF(hook);
     if (result == NULL) {
         goto error;
diff --git a/Python/crossinterp.c b/Python/crossinterp.c
index 7eb5bc267487d1..aa2c1cb78bce06 100644
--- a/Python/crossinterp.c
+++ b/Python/crossinterp.c
@@ -368,12 +368,9 @@ _convert_exc_to_TracebackException(PyObject *exc, PyObject 
**p_tbexc)
     PyObject *create = NULL;
 
     // This is inspired by _PyErr_Display().
-    PyObject *tbmod = PyImport_ImportModule("traceback");
-    if (tbmod == NULL) {
-        return -1;
-    }
-    PyObject *tbexc_type = PyObject_GetAttrString(tbmod, "TracebackException");
-    Py_DECREF(tbmod);
+    PyObject *tbexc_type = PyImport_ImportModuleAttrString(
+        "traceback",
+        "TracebackException");
     if (tbexc_type == NULL) {
         return -1;
     }
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 0da26ad3f9b4bd..ae0df9685ac159 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -1108,22 +1108,15 @@ _PyErr_Display(PyObject *file, PyObject *unused, 
PyObject *value, PyObject *tb)
     int unhandled_keyboard_interrupt = 
_PyRuntime.signals.unhandled_keyboard_interrupt;
 
     // Try first with the stdlib traceback module
-    PyObject *traceback_module = PyImport_ImportModule("traceback");
-
-    if (traceback_module == NULL) {
-        goto fallback;
-    }
-
-    PyObject *print_exception_fn = PyObject_GetAttrString(traceback_module, 
"_print_exception_bltin");
-
+    PyObject *print_exception_fn = PyImport_ImportModuleAttrString(
+        "traceback",
+        "_print_exception_bltin");
     if (print_exception_fn == NULL || !PyCallable_Check(print_exception_fn)) {
-        Py_DECREF(traceback_module);
         goto fallback;
     }
 
     PyObject* result = PyObject_CallOneArg(print_exception_fn, value);
 
-    Py_DECREF(traceback_module);
     Py_XDECREF(print_exception_fn);
     if (result) {
         Py_DECREF(result);
@@ -1371,27 +1364,18 @@ run_mod(mod_ty mod, PyObject *filename, PyObject 
*globals, PyObject *locals,
     }
 
     if (interactive_src) {
-        PyObject *linecache_module = PyImport_ImportModule("linecache");
-
-        if (linecache_module == NULL) {
-            Py_DECREF(co);
-            Py_DECREF(interactive_filename);
-            return NULL;
-        }
-
-        PyObject *print_tb_func = PyObject_GetAttrString(linecache_module, 
"_register_code");
-
+        PyObject *print_tb_func = PyImport_ImportModuleAttrString(
+            "linecache",
+            "_register_code");
         if (print_tb_func == NULL) {
             Py_DECREF(co);
             Py_DECREF(interactive_filename);
-            Py_DECREF(linecache_module);
             return NULL;
         }
 
         if (!PyCallable_Check(print_tb_func)) {
             Py_DECREF(co);
             Py_DECREF(interactive_filename);
-            Py_DECREF(linecache_module);
             Py_DECREF(print_tb_func);
             PyErr_SetString(PyExc_ValueError, "linecache._register_code is not 
callable");
             return NULL;
@@ -1406,7 +1390,6 @@ run_mod(mod_ty mod, PyObject *filename, PyObject 
*globals, PyObject *locals,
 
         Py_DECREF(interactive_filename);
 
-        Py_DECREF(linecache_module);
         Py_XDECREF(print_tb_func);
         Py_XDECREF(result);
         if (!result) {

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to