[Python-checkins] Use FASTCALL for __import__ (GH-31752)

asvetlov webhook-mailer at python.org
Fri Mar 11 11:47:28 EST 2022


https://github.com/python/cpython/commit/6f3b9e2243d8c5b6cf1be988eb5d2bd3da65a422
commit: 6f3b9e2243d8c5b6cf1be988eb5d2bd3da65a422
branch: main
author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com>
committer: asvetlov <andrew.svetlov at gmail.com>
date: 2022-03-11T18:46:55+02:00
summary:

Use FASTCALL for __import__ (GH-31752)

files:
M Python/bltinmodule.c
M Python/clinic/bltinmodule.c.h

diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index b253f88a04bae..332f4cbbd0dcc 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -243,38 +243,41 @@ PyDoc_STRVAR(build_class_doc,
 \n\
 Internal helper function used by the class statement.");
 
+/*[clinic input]
+__import__ as builtin___import__
+
+    name: object
+    globals: object(c_default="NULL") = None
+    locals: object(c_default="NULL") = None
+    fromlist: object(c_default="NULL") = ()
+    level: int = 0
+
+Import a module.
+
+Because this function is meant for use by the Python
+interpreter and not for general use, it is better to use
+importlib.import_module() to programmatically import a module.
+
+The globals argument is only used to determine the context;
+they are not modified.  The locals argument is unused.  The fromlist
+should be a list of names to emulate ``from name import ...'', or an
+empty list to emulate ``import name''.
+When importing a module from a package, note that __import__('A.B', ...)
+returns package A when fromlist is empty, but its submodule B when
+fromlist is not empty.  The level argument is used to determine whether to
+perform absolute or relative imports: 0 is absolute, while a positive number
+is the number of parent directories to search relative to the current module.
+[clinic start generated code]*/
+
 static PyObject *
-builtin___import__(PyObject *self, PyObject *args, PyObject *kwds)
+builtin___import___impl(PyObject *module, PyObject *name, PyObject *globals,
+                        PyObject *locals, PyObject *fromlist, int level)
+/*[clinic end generated code: output=4febeda88a0cd245 input=35e9a6460412430f]*/
 {
-    static char *kwlist[] = {"name", "globals", "locals", "fromlist",
-                             "level", 0};
-    PyObject *name, *globals = NULL, *locals = NULL, *fromlist = NULL;
-    int level = 0;
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "U|OOOi:__import__",
-                    kwlist, &name, &globals, &locals, &fromlist, &level))
-        return NULL;
     return PyImport_ImportModuleLevelObject(name, globals, locals,
                                             fromlist, level);
 }
 
-PyDoc_STRVAR(import_doc,
-"__import__(name, globals=None, locals=None, fromlist=(), level=0) -> module\n\
-\n\
-Import a module. Because this function is meant for use by the Python\n\
-interpreter and not for general use, it is better to use\n\
-importlib.import_module() to programmatically import a module.\n\
-\n\
-The globals argument is only used to determine the context;\n\
-they are not modified.  The locals argument is unused.  The fromlist\n\
-should be a list of names to emulate ``from name import ...'', or an\n\
-empty list to emulate ``import name''.\n\
-When importing a module from a package, note that __import__('A.B', ...)\n\
-returns package A when fromlist is empty, but its submodule B when\n\
-fromlist is not empty.  The level argument is used to determine whether to\n\
-perform absolute or relative imports: 0 is absolute, while a positive number\n\
-is the number of parent directories to search relative to the current module.");
-
 
 /*[clinic input]
 abs as builtin_abs
@@ -2903,7 +2906,7 @@ PyTypeObject PyZip_Type = {
 static PyMethodDef builtin_methods[] = {
     {"__build_class__", (PyCFunction)(void(*)(void))builtin___build_class__,
      METH_FASTCALL | METH_KEYWORDS, build_class_doc},
-    {"__import__",      (PyCFunction)(void(*)(void))builtin___import__, METH_VARARGS | METH_KEYWORDS, import_doc},
+    BUILTIN___IMPORT___METHODDEF
     BUILTIN_ABS_METHODDEF
     BUILTIN_ALL_METHODDEF
     BUILTIN_ANY_METHODDEF
diff --git a/Python/clinic/bltinmodule.c.h b/Python/clinic/bltinmodule.c.h
index 1fade994f40e3..4053f5a341e1f 100644
--- a/Python/clinic/bltinmodule.c.h
+++ b/Python/clinic/bltinmodule.c.h
@@ -2,6 +2,85 @@
 preserve
 [clinic start generated code]*/
 
+PyDoc_STRVAR(builtin___import____doc__,
+"__import__($module, /, name, globals=None, locals=None, fromlist=(),\n"
+"           level=0)\n"
+"--\n"
+"\n"
+"Import a module.\n"
+"\n"
+"Because this function is meant for use by the Python\n"
+"interpreter and not for general use, it is better to use\n"
+"importlib.import_module() to programmatically import a module.\n"
+"\n"
+"The globals argument is only used to determine the context;\n"
+"they are not modified.  The locals argument is unused.  The fromlist\n"
+"should be a list of names to emulate ``from name import ...\'\', or an\n"
+"empty list to emulate ``import name\'\'.\n"
+"When importing a module from a package, note that __import__(\'A.B\', ...)\n"
+"returns package A when fromlist is empty, but its submodule B when\n"
+"fromlist is not empty.  The level argument is used to determine whether to\n"
+"perform absolute or relative imports: 0 is absolute, while a positive number\n"
+"is the number of parent directories to search relative to the current module.");
+
+#define BUILTIN___IMPORT___METHODDEF    \
+    {"__import__", (PyCFunction)(void(*)(void))builtin___import__, METH_FASTCALL|METH_KEYWORDS, builtin___import____doc__},
+
+static PyObject *
+builtin___import___impl(PyObject *module, PyObject *name, PyObject *globals,
+                        PyObject *locals, PyObject *fromlist, int level);
+
+static PyObject *
+builtin___import__(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    static const char * const _keywords[] = {"name", "globals", "locals", "fromlist", "level", NULL};
+    static _PyArg_Parser _parser = {NULL, _keywords, "__import__", 0};
+    PyObject *argsbuf[5];
+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+    PyObject *name;
+    PyObject *globals = NULL;
+    PyObject *locals = NULL;
+    PyObject *fromlist = NULL;
+    int level = 0;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 5, 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    name = args[0];
+    if (!noptargs) {
+        goto skip_optional_pos;
+    }
+    if (args[1]) {
+        globals = args[1];
+        if (!--noptargs) {
+            goto skip_optional_pos;
+        }
+    }
+    if (args[2]) {
+        locals = args[2];
+        if (!--noptargs) {
+            goto skip_optional_pos;
+        }
+    }
+    if (args[3]) {
+        fromlist = args[3];
+        if (!--noptargs) {
+            goto skip_optional_pos;
+        }
+    }
+    level = _PyLong_AsInt(args[4]);
+    if (level == -1 && PyErr_Occurred()) {
+        goto exit;
+    }
+skip_optional_pos:
+    return_value = builtin___import___impl(module, name, globals, locals, fromlist, level);
+
+exit:
+    return return_value;
+}
+
 PyDoc_STRVAR(builtin_abs__doc__,
 "abs($module, x, /)\n"
 "--\n"
@@ -951,4 +1030,4 @@ builtin_issubclass(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=77ace832b3fb38e0 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=d341fa7525f30070 input=a9049054013a1b77]*/



More information about the Python-checkins mailing list