diff options
author | Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> | 2022-03-11 16:46:55 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-11 16:46:55 (GMT) |
commit | 6f3b9e2243d8c5b6cf1be988eb5d2bd3da65a422 (patch) | |
tree | 9a2d140e04422804d26fb8bdfd368ae94f198d34 | |
parent | f84c867dd7c87c49d830e5d195a13afe7eb86caa (diff) | |
download | cpython-6f3b9e2243d8c5b6cf1be988eb5d2bd3da65a422.zip cpython-6f3b9e2243d8c5b6cf1be988eb5d2bd3da65a422.tar.gz cpython-6f3b9e2243d8c5b6cf1be988eb5d2bd3da65a422.tar.bz2 |
Use FASTCALL for __import__ (GH-31752)
-rw-r--r-- | Python/bltinmodule.c | 57 | ||||
-rw-r--r-- | Python/clinic/bltinmodule.c.h | 81 |
2 files changed, 110 insertions, 28 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index b253f88..332f4cb 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 1fade99..4053f5a 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]*/ |