From 9513df64576577310bee92a5f51606853cc39728 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 30 May 2014 11:21:14 -0400 Subject: Move import.c to use Clinic file output. --- Python/import.c | 347 +++----------------------------------------------------- 1 file changed, 17 insertions(+), 330 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 80e376483f..cad830f64a 100644 --- a/Python/import.c +++ b/Python/import.c @@ -32,9 +32,12 @@ struct _inittab *PyImport_Inittab = _PyImport_Inittab; static PyObject *initstr = NULL; /*[clinic input] +output preset file module _imp [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9c332475d8686284]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=98c38221164579d5]*/ + +#include "clinic/import.c.h" /*[python input] class fs_unicode_converter(CConverter): @@ -235,29 +238,9 @@ Return True if the import lock is currently held, else False. On platforms without threads, return False. [clinic start generated code]*/ -PyDoc_STRVAR(_imp_lock_held__doc__, -"lock_held($module, /)\n" -"--\n" -"\n" -"Return True if the import lock is currently held, else False.\n" -"\n" -"On platforms without threads, return False."); - -#define _IMP_LOCK_HELD_METHODDEF \ - {"lock_held", (PyCFunction)_imp_lock_held, METH_NOARGS, _imp_lock_held__doc__}, - -static PyObject * -_imp_lock_held_impl(PyModuleDef *module); - -static PyObject * -_imp_lock_held(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) -{ - return _imp_lock_held_impl(module); -} - static PyObject * _imp_lock_held_impl(PyModuleDef *module) -/*[clinic end generated code: output=dae65674966baa65 input=9b088f9b217d9bdf]*/ +/*[clinic end generated code: output=d7a8cc3a5169081a input=9b088f9b217d9bdf]*/ { #ifdef WITH_THREAD return PyBool_FromLong(import_lock_thread != -1); @@ -275,30 +258,9 @@ This lock should be used by import hooks to ensure thread-safety when importing modules. On platforms without threads, this function does nothing. [clinic start generated code]*/ -PyDoc_STRVAR(_imp_acquire_lock__doc__, -"acquire_lock($module, /)\n" -"--\n" -"\n" -"Acquires the interpreter\'s import lock for the current thread.\n" -"\n" -"This lock should be used by import hooks to ensure thread-safety when importing\n" -"modules. On platforms without threads, this function does nothing."); - -#define _IMP_ACQUIRE_LOCK_METHODDEF \ - {"acquire_lock", (PyCFunction)_imp_acquire_lock, METH_NOARGS, _imp_acquire_lock__doc__}, - -static PyObject * -_imp_acquire_lock_impl(PyModuleDef *module); - -static PyObject * -_imp_acquire_lock(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) -{ - return _imp_acquire_lock_impl(module); -} - static PyObject * _imp_acquire_lock_impl(PyModuleDef *module) -/*[clinic end generated code: output=478f1fa089fdb9a4 input=4a2d4381866d5fdc]*/ +/*[clinic end generated code: output=cc143b1d16422cae input=4a2d4381866d5fdc]*/ { #ifdef WITH_THREAD _PyImport_AcquireLock(); @@ -315,29 +277,9 @@ Release the interpreter's import lock. On platforms without threads, this function does nothing. [clinic start generated code]*/ -PyDoc_STRVAR(_imp_release_lock__doc__, -"release_lock($module, /)\n" -"--\n" -"\n" -"Release the interpreter\'s import lock.\n" -"\n" -"On platforms without threads, this function does nothing."); - -#define _IMP_RELEASE_LOCK_METHODDEF \ - {"release_lock", (PyCFunction)_imp_release_lock, METH_NOARGS, _imp_release_lock__doc__}, - -static PyObject * -_imp_release_lock_impl(PyModuleDef *module); - -static PyObject * -_imp_release_lock(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) -{ - return _imp_release_lock_impl(module); -} - static PyObject * _imp_release_lock_impl(PyModuleDef *module) -/*[clinic end generated code: output=36c77a6832fdafd4 input=934fb11516dd778b]*/ +/*[clinic end generated code: output=74d28e38ebe2b224 input=934fb11516dd778b]*/ { #ifdef WITH_THREAD if (_PyImport_ReleaseLock() < 0) { @@ -962,43 +904,9 @@ _imp._fix_co_filename Changes code.co_filename to specify the passed-in file path. [clinic start generated code]*/ -PyDoc_STRVAR(_imp__fix_co_filename__doc__, -"_fix_co_filename($module, code, path, /)\n" -"--\n" -"\n" -"Changes code.co_filename to specify the passed-in file path.\n" -"\n" -" code\n" -" Code object to change.\n" -" path\n" -" File path to use."); - -#define _IMP__FIX_CO_FILENAME_METHODDEF \ - {"_fix_co_filename", (PyCFunction)_imp__fix_co_filename, METH_VARARGS, _imp__fix_co_filename__doc__}, - -static PyObject * -_imp__fix_co_filename_impl(PyModuleDef *module, PyCodeObject *code, PyObject *path); - -static PyObject * -_imp__fix_co_filename(PyModuleDef *module, PyObject *args) -{ - PyObject *return_value = NULL; - PyCodeObject *code; - PyObject *path; - - if (!PyArg_ParseTuple(args, - "O!U:_fix_co_filename", - &PyCode_Type, &code, &path)) - goto exit; - return_value = _imp__fix_co_filename_impl(module, code, path); - -exit: - return return_value; -} - static PyObject * _imp__fix_co_filename_impl(PyModuleDef *module, PyCodeObject *code, PyObject *path) -/*[clinic end generated code: output=6b4b1edeb0d55c5d input=895ba50e78b82f05]*/ +/*[clinic end generated code: output=7afe5ba6b9d383e4 input=895ba50e78b82f05]*/ { update_compiled_module(code, path); @@ -1860,27 +1768,9 @@ _imp.extension_suffixes Returns the list of file suffixes used to identify extension modules. [clinic start generated code]*/ -PyDoc_STRVAR(_imp_extension_suffixes__doc__, -"extension_suffixes($module, /)\n" -"--\n" -"\n" -"Returns the list of file suffixes used to identify extension modules."); - -#define _IMP_EXTENSION_SUFFIXES_METHODDEF \ - {"extension_suffixes", (PyCFunction)_imp_extension_suffixes, METH_NOARGS, _imp_extension_suffixes__doc__}, - -static PyObject * -_imp_extension_suffixes_impl(PyModuleDef *module); - -static PyObject * -_imp_extension_suffixes(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) -{ - return _imp_extension_suffixes_impl(module); -} - static PyObject * _imp_extension_suffixes_impl(PyModuleDef *module) -/*[clinic end generated code: output=bb30a2438167798c input=ecdeeecfcb6f839e]*/ +/*[clinic end generated code: output=d44c1566ef362229 input=ecdeeecfcb6f839e]*/ { PyObject *list; const char *suffix; @@ -1917,37 +1807,9 @@ _imp.init_builtin Initializes a built-in module. [clinic start generated code]*/ -PyDoc_STRVAR(_imp_init_builtin__doc__, -"init_builtin($module, name, /)\n" -"--\n" -"\n" -"Initializes a built-in module."); - -#define _IMP_INIT_BUILTIN_METHODDEF \ - {"init_builtin", (PyCFunction)_imp_init_builtin, METH_VARARGS, _imp_init_builtin__doc__}, - -static PyObject * -_imp_init_builtin_impl(PyModuleDef *module, PyObject *name); - -static PyObject * -_imp_init_builtin(PyModuleDef *module, PyObject *args) -{ - PyObject *return_value = NULL; - PyObject *name; - - if (!PyArg_ParseTuple(args, - "U:init_builtin", - &name)) - goto exit; - return_value = _imp_init_builtin_impl(module, name); - -exit: - return return_value; -} - static PyObject * _imp_init_builtin_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: output=a0244948a43f8e26 input=f934d2231ec52a2e]*/ +/*[clinic end generated code: output=1868f473685f6d67 input=f934d2231ec52a2e]*/ { int ret; PyObject *m; @@ -1973,37 +1835,9 @@ _imp.init_frozen Initializes a frozen module. [clinic start generated code]*/ -PyDoc_STRVAR(_imp_init_frozen__doc__, -"init_frozen($module, name, /)\n" -"--\n" -"\n" -"Initializes a frozen module."); - -#define _IMP_INIT_FROZEN_METHODDEF \ - {"init_frozen", (PyCFunction)_imp_init_frozen, METH_VARARGS, _imp_init_frozen__doc__}, - -static PyObject * -_imp_init_frozen_impl(PyModuleDef *module, PyObject *name); - -static PyObject * -_imp_init_frozen(PyModuleDef *module, PyObject *args) -{ - PyObject *return_value = NULL; - PyObject *name; - - if (!PyArg_ParseTuple(args, - "U:init_frozen", - &name)) - goto exit; - return_value = _imp_init_frozen_impl(module, name); - -exit: - return return_value; -} - static PyObject * _imp_init_frozen_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: output=e4bc2bff296f8f22 input=13019adfc04f3fb3]*/ +/*[clinic end generated code: output=a9de493bdd711878 input=13019adfc04f3fb3]*/ { int ret; PyObject *m; @@ -2029,37 +1863,9 @@ _imp.get_frozen_object Create a code object for a frozen module. [clinic start generated code]*/ -PyDoc_STRVAR(_imp_get_frozen_object__doc__, -"get_frozen_object($module, name, /)\n" -"--\n" -"\n" -"Create a code object for a frozen module."); - -#define _IMP_GET_FROZEN_OBJECT_METHODDEF \ - {"get_frozen_object", (PyCFunction)_imp_get_frozen_object, METH_VARARGS, _imp_get_frozen_object__doc__}, - -static PyObject * -_imp_get_frozen_object_impl(PyModuleDef *module, PyObject *name); - -static PyObject * -_imp_get_frozen_object(PyModuleDef *module, PyObject *args) -{ - PyObject *return_value = NULL; - PyObject *name; - - if (!PyArg_ParseTuple(args, - "U:get_frozen_object", - &name)) - goto exit; - return_value = _imp_get_frozen_object_impl(module, name); - -exit: - return return_value; -} - static PyObject * _imp_get_frozen_object_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: output=4089ec702a9d70c5 input=ed689bc05358fdbd]*/ +/*[clinic end generated code: output=3114c970a47f2e3c input=ed689bc05358fdbd]*/ { return get_frozen_object(name); } @@ -2073,37 +1879,9 @@ _imp.is_frozen_package Returns True if the module name is of a frozen package. [clinic start generated code]*/ -PyDoc_STRVAR(_imp_is_frozen_package__doc__, -"is_frozen_package($module, name, /)\n" -"--\n" -"\n" -"Returns True if the module name is of a frozen package."); - -#define _IMP_IS_FROZEN_PACKAGE_METHODDEF \ - {"is_frozen_package", (PyCFunction)_imp_is_frozen_package, METH_VARARGS, _imp_is_frozen_package__doc__}, - -static PyObject * -_imp_is_frozen_package_impl(PyModuleDef *module, PyObject *name); - -static PyObject * -_imp_is_frozen_package(PyModuleDef *module, PyObject *args) -{ - PyObject *return_value = NULL; - PyObject *name; - - if (!PyArg_ParseTuple(args, - "U:is_frozen_package", - &name)) - goto exit; - return_value = _imp_is_frozen_package_impl(module, name); - -exit: - return return_value; -} - static PyObject * _imp_is_frozen_package_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: output=86aab14dcd4b959b input=81b6cdecd080fbb8]*/ +/*[clinic end generated code: output=3e4cab802b56d649 input=81b6cdecd080fbb8]*/ { return is_frozen_package(name); } @@ -2117,37 +1895,9 @@ _imp.is_builtin Returns True if the module name corresponds to a built-in module. [clinic start generated code]*/ -PyDoc_STRVAR(_imp_is_builtin__doc__, -"is_builtin($module, name, /)\n" -"--\n" -"\n" -"Returns True if the module name corresponds to a built-in module."); - -#define _IMP_IS_BUILTIN_METHODDEF \ - {"is_builtin", (PyCFunction)_imp_is_builtin, METH_VARARGS, _imp_is_builtin__doc__}, - -static PyObject * -_imp_is_builtin_impl(PyModuleDef *module, PyObject *name); - -static PyObject * -_imp_is_builtin(PyModuleDef *module, PyObject *args) -{ - PyObject *return_value = NULL; - PyObject *name; - - if (!PyArg_ParseTuple(args, - "U:is_builtin", - &name)) - goto exit; - return_value = _imp_is_builtin_impl(module, name); - -exit: - return return_value; -} - static PyObject * _imp_is_builtin_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: output=d5847f8cac50946e input=86befdac021dd1c7]*/ +/*[clinic end generated code: output=2deec9cac6fb9a7e input=86befdac021dd1c7]*/ { return PyLong_FromLong(is_builtin(name)); } @@ -2161,37 +1911,9 @@ _imp.is_frozen Returns True if the module name corresponds to a frozen module. [clinic start generated code]*/ -PyDoc_STRVAR(_imp_is_frozen__doc__, -"is_frozen($module, name, /)\n" -"--\n" -"\n" -"Returns True if the module name corresponds to a frozen module."); - -#define _IMP_IS_FROZEN_METHODDEF \ - {"is_frozen", (PyCFunction)_imp_is_frozen, METH_VARARGS, _imp_is_frozen__doc__}, - -static PyObject * -_imp_is_frozen_impl(PyModuleDef *module, PyObject *name); - -static PyObject * -_imp_is_frozen(PyModuleDef *module, PyObject *args) -{ - PyObject *return_value = NULL; - PyObject *name; - - if (!PyArg_ParseTuple(args, - "U:is_frozen", - &name)) - goto exit; - return_value = _imp_is_frozen_impl(module, name); - -exit: - return return_value; -} - static PyObject * _imp_is_frozen_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: output=6691af884ba4987d input=7301dbca1897d66b]*/ +/*[clinic end generated code: output=7de8e260c8e36aed input=7301dbca1897d66b]*/ { const struct _frozen *p; @@ -2212,39 +1934,9 @@ _imp.load_dynamic Loads an extension module. [clinic start generated code]*/ -PyDoc_STRVAR(_imp_load_dynamic__doc__, -"load_dynamic($module, name, path, file=None, /)\n" -"--\n" -"\n" -"Loads an extension module."); - -#define _IMP_LOAD_DYNAMIC_METHODDEF \ - {"load_dynamic", (PyCFunction)_imp_load_dynamic, METH_VARARGS, _imp_load_dynamic__doc__}, - -static PyObject * -_imp_load_dynamic_impl(PyModuleDef *module, PyObject *name, PyObject *path, PyObject *file); - -static PyObject * -_imp_load_dynamic(PyModuleDef *module, PyObject *args) -{ - PyObject *return_value = NULL; - PyObject *name; - PyObject *path; - PyObject *file = NULL; - - if (!PyArg_ParseTuple(args, - "UO&|O:load_dynamic", - &name, PyUnicode_FSDecoder, &path, &file)) - goto exit; - return_value = _imp_load_dynamic_impl(module, name, path, file); - -exit: - return return_value; -} - static PyObject * _imp_load_dynamic_impl(PyModuleDef *module, PyObject *name, PyObject *path, PyObject *file) -/*[clinic end generated code: output=81d11a1fbd1ea0a8 input=af64f06e4bad3526]*/ +/*[clinic end generated code: output=8b7ae431d795e1ba input=af64f06e4bad3526]*/ { PyObject *mod; FILE *fp; @@ -2272,11 +1964,7 @@ _imp_load_dynamic_impl(PyModuleDef *module, PyObject *name, PyObject *path, PyOb /*[clinic input] dump buffer [clinic start generated code]*/ - -#ifndef _IMP_LOAD_DYNAMIC_METHODDEF - #define _IMP_LOAD_DYNAMIC_METHODDEF -#endif /* !defined(_IMP_LOAD_DYNAMIC_METHODDEF) */ -/*[clinic end generated code: output=d07c1d4a343a9579 input=524ce2e021e4eba6]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/ PyDoc_STRVAR(doc_imp, @@ -2385,4 +2073,3 @@ PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void)) #ifdef __cplusplus } #endif - -- cgit v1.2.1 From 8cbd503f52fac32926312dd3476a4580dfbe6daa Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 28 Sep 2014 11:27:24 +0300 Subject: Removed redundant casts to `char *`. Corresponding functions now accept `const char *` (issue #1772673). --- Python/import.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 317bdf7653..c3b9e12572 100644 --- a/Python/import.c +++ b/Python/import.c @@ -2064,7 +2064,7 @@ PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void)) memset(newtab, '\0', sizeof newtab); - newtab[0].name = (char *)name; + newtab[0].name = name; newtab[0].initfunc = initfunc; return PyImport_ExtendInittab(newtab); -- cgit v1.2.1 From b76e79ce344cf60aeeff69c4ca5c96302890ea3c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 18 Mar 2015 01:39:23 +0100 Subject: Issue #23694: Enhance _Py_fopen(), it now raises an exception on error * If fopen() fails, OSError is raised with the original filename object. * The GIL is now released while calling fopen() --- Python/import.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index c3b9e12572..238e8d06a1 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1945,8 +1945,6 @@ _imp_load_dynamic_impl(PyModuleDef *module, PyObject *name, PyObject *path, PyOb fp = _Py_fopen_obj(path, "r"); if (fp == NULL) { Py_DECREF(path); - if (!PyErr_Occurred()) - PyErr_SetFromErrno(PyExc_IOError); return NULL; } } -- cgit v1.2.1 From 970e566ca7317a2fa90d57de73aec7216995691f Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 3 Apr 2015 23:53:51 +0300 Subject: Issue #23501: Argumen Clinic now generates code into separate files by default. --- Python/import.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 238e8d06a1..54654afd14 100644 --- a/Python/import.c +++ b/Python/import.c @@ -32,10 +32,9 @@ struct _inittab *PyImport_Inittab = _PyImport_Inittab; static PyObject *initstr = NULL; /*[clinic input] -output preset file module _imp [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=98c38221164579d5]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9c332475d8686284]*/ #include "clinic/import.c.h" -- cgit v1.2.1 From 8f7e37ea29d7bdfadb98c3ef264862962e99748c Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Tue, 14 Apr 2015 18:07:59 -0400 Subject: Issue #23944: Argument Clinic now wraps long impl prototypes at column 78. --- Python/import.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 54654afd14..46c6b53e7a 100644 --- a/Python/import.c +++ b/Python/import.c @@ -904,8 +904,9 @@ Changes code.co_filename to specify the passed-in file path. [clinic start generated code]*/ static PyObject * -_imp__fix_co_filename_impl(PyModuleDef *module, PyCodeObject *code, PyObject *path) -/*[clinic end generated code: output=7afe5ba6b9d383e4 input=895ba50e78b82f05]*/ +_imp__fix_co_filename_impl(PyModuleDef *module, PyCodeObject *code, + PyObject *path) +/*[clinic end generated code: output=f4db56aac0a1327f input=895ba50e78b82f05]*/ { update_compiled_module(code, path); @@ -1934,8 +1935,9 @@ Loads an extension module. [clinic start generated code]*/ static PyObject * -_imp_load_dynamic_impl(PyModuleDef *module, PyObject *name, PyObject *path, PyObject *file) -/*[clinic end generated code: output=8b7ae431d795e1ba input=af64f06e4bad3526]*/ +_imp_load_dynamic_impl(PyModuleDef *module, PyObject *name, PyObject *path, + PyObject *file) +/*[clinic end generated code: output=e84e5f7f0f39bc54 input=af64f06e4bad3526]*/ { PyObject *mod; FILE *fp; -- cgit v1.2.1 From 470268ae1d0e919df838db5b652ab9a8608fc2b8 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Sat, 2 May 2015 19:15:18 -0600 Subject: Issue #23911: Move path-based bootstrap code to a separate frozen module. --- Python/import.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 999da3759c..658360d820 100644 --- a/Python/import.c +++ b/Python/import.c @@ -491,8 +491,13 @@ PyImport_GetMagicNumber(void) { long res; PyInterpreterState *interp = PyThreadState_Get()->interp; - PyObject *pyc_magic = PyObject_GetAttrString(interp->importlib, - "_RAW_MAGIC_NUMBER"); + PyObject *external, *pyc_magic; + + external = PyObject_GetAttrString(interp->importlib, "_bootstrap_external"); + if (external == NULL) + return -1; + pyc_magic = PyObject_GetAttrString(external, "_RAW_MAGIC_NUMBER"); + Py_DECREF(external); if (pyc_magic == NULL) return -1; res = PyLong_AsLong(pyc_magic); @@ -737,7 +742,7 @@ PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co, const char *cpathname) { PyObject *m = NULL; - PyObject *nameobj, *pathobj = NULL, *cpathobj = NULL; + PyObject *nameobj, *pathobj = NULL, *cpathobj = NULL, *external= NULL; nameobj = PyUnicode_FromString(name); if (nameobj == NULL) @@ -765,9 +770,14 @@ PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co, "no interpreter!"); } - pathobj = _PyObject_CallMethodIdObjArgs(interp->importlib, - &PyId__get_sourcefile, cpathobj, - NULL); + external= PyObject_GetAttrString(interp->importlib, + "_bootstrap_external"); + if (external != NULL) { + pathobj = _PyObject_CallMethodIdObjArgs(external, + &PyId__get_sourcefile, cpathobj, + NULL); + Py_DECREF(external); + } if (pathobj == NULL) PyErr_Clear(); } @@ -833,7 +843,7 @@ PyObject* PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, PyObject *cpathname) { - PyObject *d, *res; + PyObject *d, *external, *res; PyInterpreterState *interp = PyThreadState_GET()->interp; _Py_IDENTIFIER(_fix_up_module); @@ -845,9 +855,13 @@ PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, if (pathname == NULL) { pathname = ((PyCodeObject *)co)->co_filename; } - res = _PyObject_CallMethodIdObjArgs(interp->importlib, + external = PyObject_GetAttrString(interp->importlib, "_bootstrap_external"); + if (external == NULL) + return NULL; + res = _PyObject_CallMethodIdObjArgs(external, &PyId__fix_up_module, d, name, pathname, cpathname, NULL); + Py_DECREF(external); if (res != NULL) { Py_DECREF(res); res = exec_code_in_module(name, d, co); @@ -1245,6 +1259,7 @@ static void remove_importlib_frames(void) { const char *importlib_filename = ""; + const char *external_filename = ""; const char *remove_frames = "_call_with_frames_removed"; int always_trim = 0; int in_importlib = 0; @@ -1274,7 +1289,10 @@ remove_importlib_frames(void) assert(PyTraceBack_Check(tb)); now_in_importlib = (PyUnicode_CompareWithASCIIString( code->co_filename, - importlib_filename) == 0); + importlib_filename) == 0) || + (PyUnicode_CompareWithASCIIString( + code->co_filename, + external_filename) == 0); if (now_in_importlib && !in_importlib) { /* This is the link to this chunk of importlib tracebacks */ outer_link = prev_link; -- cgit v1.2.1 From 599ed75a674f7ad2c983783ed6f3a75bd5ccae18 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Sat, 23 May 2015 22:24:10 +1000 Subject: PEP 489: Multi-phase extension module initialization Known limitations of the current implementation: - documentation changes are incomplete - there's a reference leak I haven't tracked down yet The leak is most visible by running: ./python -m test -R3:3 test_importlib However, you can also see it by running: ./python -X showrefcount Importing the array or _testmultiphase modules, and then deleting them from both sys.modules and the local namespace shows significant increases in the total number of active references each cycle. By contrast, with _testcapi (which continues to use single-phase initialisation) the global refcounts stabilise after a couple of cycles. --- Python/import.c | 189 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 123 insertions(+), 66 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 658360d820..3e27715345 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1026,50 +1026,74 @@ PyImport_GetImporter(PyObject *path) { return importer; } +/*[clinic input] +_imp.create_builtin -static int init_builtin(PyObject *); /* Forward */ + spec: object + / -/* Initialize a built-in module. - Return 1 for success, 0 if the module is not found, and -1 with - an exception set if the initialization failed. */ +Create an extension module. +[clinic start generated code]*/ -static int -init_builtin(PyObject *name) +static PyObject * +_imp_create_builtin(PyModuleDef *module, PyObject *spec) +/*[clinic end generated code: output=5038f467617226bd input=37f966f890384e47]*/ { struct _inittab *p; + PyObject *name; + char *namestr; PyObject *mod; + name = PyObject_GetAttrString(spec, "name"); + if (name == NULL) { + return NULL; + } + mod = _PyImport_FindExtensionObject(name, name); - if (PyErr_Occurred()) - return -1; - if (mod != NULL) - return 1; + if (mod || PyErr_Occurred()) { + Py_DECREF(name); + Py_INCREF(mod); + return mod; + } + + namestr = PyUnicode_AsUTF8(name); + if (namestr == NULL) { + Py_DECREF(name); + return NULL; + } for (p = PyImport_Inittab; p->name != NULL; p++) { - PyObject *mod; PyModuleDef *def; if (PyUnicode_CompareWithASCIIString(name, p->name) == 0) { if (p->initfunc == NULL) { - PyErr_Format(PyExc_ImportError, - "Cannot re-init internal module %R", - name); - return -1; + /* Cannot re-init internal module ("sys" or "builtins") */ + mod = PyImport_AddModule(namestr); + Py_DECREF(name); + return mod; } mod = (*p->initfunc)(); - if (mod == 0) - return -1; - /* Remember pointer to module init function. */ - def = PyModule_GetDef(mod); - def->m_base.m_init = p->initfunc; - if (_PyImport_FixupExtensionObject(mod, name, name) < 0) - return -1; - /* FixupExtension has put the module into sys.modules, - so we can release our own reference. */ - Py_DECREF(mod); - return 1; + if (mod == NULL) { + Py_DECREF(name); + return NULL; + } + if (PyObject_TypeCheck(mod, &PyModuleDef_Type)) { + Py_DECREF(name); + return PyModule_FromDefAndSpec((PyModuleDef*)mod, spec); + } else { + /* Remember pointer to module init function. */ + def = PyModule_GetDef(mod); + def->m_base.m_init = p->initfunc; + if (_PyImport_FixupExtensionObject(mod, name, name) < 0) { + Py_DECREF(name); + return NULL; + } + Py_DECREF(name); + return mod; + } } } - return 0; + Py_DECREF(name); + Py_RETURN_NONE; } @@ -1820,34 +1844,6 @@ _imp_extension_suffixes_impl(PyModuleDef *module) return list; } -/*[clinic input] -_imp.init_builtin - - name: unicode - / - -Initializes a built-in module. -[clinic start generated code]*/ - -static PyObject * -_imp_init_builtin_impl(PyModuleDef *module, PyObject *name) -/*[clinic end generated code: output=1868f473685f6d67 input=f934d2231ec52a2e]*/ -{ - int ret; - PyObject *m; - - ret = init_builtin(name); - if (ret < 0) - return NULL; - if (ret == 0) { - Py_INCREF(Py_None); - return Py_None; - } - m = PyImport_AddModuleObject(name); - Py_XINCREF(m); - return m; -} - /*[clinic input] _imp.init_frozen @@ -1946,40 +1942,100 @@ _imp_is_frozen_impl(PyModuleDef *module, PyObject *name) #ifdef HAVE_DYNAMIC_LOADING /*[clinic input] -_imp.load_dynamic +_imp.create_dynamic - name: unicode - path: fs_unicode + spec: object file: object = NULL / -Loads an extension module. +Create an extension module. [clinic start generated code]*/ static PyObject * -_imp_load_dynamic_impl(PyModuleDef *module, PyObject *name, PyObject *path, - PyObject *file) -/*[clinic end generated code: output=e84e5f7f0f39bc54 input=af64f06e4bad3526]*/ +_imp_create_dynamic_impl(PyModuleDef *module, PyObject *spec, PyObject *file) +/*[clinic end generated code: output=935cde5b3872d56d input=c31b954f4cf4e09d]*/ { - PyObject *mod; + PyObject *mod, *name, *path; FILE *fp; + name = PyObject_GetAttrString(spec, "name"); + if (name == NULL) { + return NULL; + } + + path = PyObject_GetAttrString(spec, "origin"); + if (path == NULL) { + Py_DECREF(name); + return NULL; + } + + mod = _PyImport_FindExtensionObject(name, path); + if (mod != NULL) { + Py_DECREF(name); + Py_DECREF(path); + Py_INCREF(mod); + return mod; + } + if (file != NULL) { fp = _Py_fopen_obj(path, "r"); if (fp == NULL) { + Py_DECREF(name); Py_DECREF(path); return NULL; } } else fp = NULL; - mod = _PyImport_LoadDynamicModule(name, path, fp); + + mod = _PyImport_LoadDynamicModuleWithSpec(spec, fp); + + Py_DECREF(name); Py_DECREF(path); if (fp) fclose(fp); return mod; } +/*[clinic input] +_imp.exec_dynamic -> int + + mod: object + / + +Initialize an extension module. +[clinic start generated code]*/ + +static int +_imp_exec_dynamic_impl(PyModuleDef *module, PyObject *mod) +/*[clinic end generated code: output=4b84f1301b22d4bd input=9fdbfcb250280d3a]*/ +{ + PyModuleDef *def; + void *state; + + if (!PyModule_Check(mod)) { + return 0; + } + + def = PyModule_GetDef(mod); + if (def == NULL) { + if (PyErr_Occurred()) { + return -1; + } + return 0; + } + state = PyModule_GetState(mod); + if (PyErr_Occurred()) { + return -1; + } + if (state) { + /* Already initialized; skip reload */ + return 0; + } + return PyModule_ExecDef(mod, def); +} + + #endif /* HAVE_DYNAMIC_LOADING */ /*[clinic input] @@ -1998,11 +2054,12 @@ static PyMethodDef imp_methods[] = { _IMP_RELEASE_LOCK_METHODDEF _IMP_GET_FROZEN_OBJECT_METHODDEF _IMP_IS_FROZEN_PACKAGE_METHODDEF - _IMP_INIT_BUILTIN_METHODDEF + _IMP_CREATE_BUILTIN_METHODDEF _IMP_INIT_FROZEN_METHODDEF _IMP_IS_BUILTIN_METHODDEF _IMP_IS_FROZEN_METHODDEF - _IMP_LOAD_DYNAMIC_METHODDEF + _IMP_CREATE_DYNAMIC_METHODDEF + _IMP_EXEC_DYNAMIC_METHODDEF _IMP__FIX_CO_FILENAME_METHODDEF {NULL, NULL} /* sentinel */ }; -- cgit v1.2.1 From c465d05cc7c93e63c43fa4ad3d6edba1b4fa8ef3 Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Mon, 24 Aug 2015 19:53:56 -0700 Subject: Issue #24769: Interpreter now starts properly when dynamic loading is disabled. Patch by Petr Viktorin. --- Python/import.c | 69 ++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 23 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 44aae80990..7fd49305cb 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1943,6 +1943,34 @@ _imp_is_frozen_impl(PyModuleDef *module, PyObject *name) return PyBool_FromLong((long) (p == NULL ? 0 : p->size)); } +/* Common implementation for _imp.exec_dynamic and _imp.exec_builtin */ +static int +exec_builtin_or_dynamic(PyObject *mod) { + PyModuleDef *def; + void *state; + + if (!PyModule_Check(mod)) { + return 0; + } + + def = PyModule_GetDef(mod); + if (def == NULL) { + if (PyErr_Occurred()) { + return -1; + } + return 0; + } + state = PyModule_GetState(mod); + if (PyErr_Occurred()) { + return -1; + } + if (state) { + /* Already initialized; skip reload */ + return 0; + } + return PyModule_ExecDef(mod, def); +} + #ifdef HAVE_DYNAMIC_LOADING /*[clinic input] @@ -2014,34 +2042,28 @@ static int _imp_exec_dynamic_impl(PyModuleDef *module, PyObject *mod) /*[clinic end generated code: output=4b84f1301b22d4bd input=9fdbfcb250280d3a]*/ { - PyModuleDef *def; - void *state; - - if (!PyModule_Check(mod)) { - return 0; - } - - def = PyModule_GetDef(mod); - if (def == NULL) { - if (PyErr_Occurred()) { - return -1; - } - return 0; - } - state = PyModule_GetState(mod); - if (PyErr_Occurred()) { - return -1; - } - if (state) { - /* Already initialized; skip reload */ - return 0; - } - return PyModule_ExecDef(mod, def); + return exec_builtin_or_dynamic(mod); } #endif /* HAVE_DYNAMIC_LOADING */ +/*[clinic input] +_imp.exec_builtin -> int + + mod: object + / + +Initialize a built-in module. +[clinic start generated code]*/ + +static int +_imp_exec_builtin_impl(PyModuleDef *module, PyObject *mod) +/*[clinic end generated code: output=215e99876a27e284 input=77ebec0c2a10ecca]*/ +{ + return exec_builtin_or_dynamic(mod); +} + /*[clinic input] dump buffer [clinic start generated code]*/ @@ -2064,6 +2086,7 @@ static PyMethodDef imp_methods[] = { _IMP_IS_FROZEN_METHODDEF _IMP_CREATE_DYNAMIC_METHODDEF _IMP_EXEC_DYNAMIC_METHODDEF + _IMP_EXEC_BUILTIN_METHODDEF _IMP__FIX_CO_FILENAME_METHODDEF {NULL, NULL} /* sentinel */ }; -- cgit v1.2.1 From 132f9bfda14e7b7bb38a4125e027a8676872e236 Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Mon, 24 Aug 2015 20:23:27 -0700 Subject: Rebuilt Clinic generated code. --- Python/import.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 7fd49305cb..edf030d87a 100644 --- a/Python/import.c +++ b/Python/import.c @@ -2059,7 +2059,7 @@ Initialize a built-in module. static int _imp_exec_builtin_impl(PyModuleDef *module, PyObject *mod) -/*[clinic end generated code: output=215e99876a27e284 input=77ebec0c2a10ecca]*/ +/*[clinic end generated code: output=215e99876a27e284 input=7beed5a2f12a60ca]*/ { return exec_builtin_or_dynamic(mod); } -- cgit v1.2.1 From d1ba93f9a6a441ac31c5fd1890ce730b9e6d330d Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 25 Dec 2015 19:53:18 +0200 Subject: Issue #25923: Added the const qualifier to static constant arrays. --- Python/import.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index edf030d87a..8d7bfe906f 100644 --- a/Python/import.c +++ b/Python/import.c @@ -320,7 +320,7 @@ PyImport_GetModuleDict(void) /* List of names to clear in sys */ -static char* sys_deletes[] = { +static const char * const sys_deletes[] = { "path", "argv", "ps1", "ps2", "last_type", "last_value", "last_traceback", "path_hooks", "path_importer_cache", "meta_path", @@ -330,7 +330,7 @@ static char* sys_deletes[] = { NULL }; -static char* sys_files[] = { +static const char * const sys_files[] = { "stdin", "__stdin__", "stdout", "__stdout__", "stderr", "__stderr__", @@ -347,7 +347,7 @@ PyImport_Cleanup(void) PyInterpreterState *interp = PyThreadState_GET()->interp; PyObject *modules = interp->modules; PyObject *weaklist = NULL; - char **p; + const char * const *p; if (modules == NULL) return; /* Already done */ -- cgit v1.2.1 From 93c98b688bef3bf08c027315a744869b590ceef3 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 5 Jan 2016 21:27:54 +0200 Subject: Issue #20440: Cleaning up the code by using Py_SETREF. --- Python/import.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 8d7bfe906f..325b93680d 100644 --- a/Python/import.c +++ b/Python/import.c @@ -879,10 +879,8 @@ update_code_filenames(PyCodeObject *co, PyObject *oldname, PyObject *newname) if (PyUnicode_Compare(co->co_filename, oldname)) return; - tmp = co->co_filename; - co->co_filename = newname; - Py_INCREF(co->co_filename); - Py_DECREF(tmp); + Py_INCREF(newname); + Py_SETREF(co->co_filename, newname); constants = co->co_consts; n = PyTuple_GET_SIZE(constants); @@ -1327,10 +1325,8 @@ remove_importlib_frames(void) (always_trim || PyUnicode_CompareWithASCIIString(code->co_name, remove_frames) == 0)) { - PyObject *tmp = *outer_link; - *outer_link = next; Py_XINCREF(next); - Py_DECREF(tmp); + Py_SETREF(*outer_link, next); prev_link = outer_link; } else { -- cgit v1.2.1 From 8df7769f53ac69a471cc182ee79d9eae4df79960 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 15 Jan 2016 13:33:03 -0800 Subject: Issue #25791: Raise an ImportWarning when __spec__ or __package__ are not defined for a relative import. This is the start of work to try and clean up import semantics to rely more on a module's spec than on the myriad attributes that get set on a module. Thanks to Rose Ames for the patch. --- Python/import.c | 64 ++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 21 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 325b93680d..c1071c0de3 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1359,6 +1359,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, PyObject *final_mod = NULL; PyObject *mod = NULL; PyObject *package = NULL; + PyObject *spec = NULL; PyObject *globals = NULL; PyObject *fromlist = NULL; PyInterpreterState *interp = PyThreadState_GET()->interp; @@ -1414,39 +1415,60 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, goto error; } else if (level > 0) { - package = _PyDict_GetItemId(globals, &PyId___package__); + spec = _PyDict_GetItemId(globals, &PyId___spec__); + if (spec != NULL) { + package = PyObject_GetAttrString(spec, "parent"); + } if (package != NULL && package != Py_None) { - Py_INCREF(package); if (!PyUnicode_Check(package)) { - PyErr_SetString(PyExc_TypeError, "package must be a string"); + PyErr_SetString(PyExc_TypeError, + "__spec__.parent must be a string"); goto error; } } else { - package = _PyDict_GetItemId(globals, &PyId___name__); - if (package == NULL) { - PyErr_SetString(PyExc_KeyError, "'__name__' not in globals"); - goto error; - } - else if (!PyUnicode_Check(package)) { - PyErr_SetString(PyExc_TypeError, "__name__ must be a string"); + package = _PyDict_GetItemId(globals, &PyId___package__); + if (package != NULL && package != Py_None) { + Py_INCREF(package); + if (!PyUnicode_Check(package)) { + PyErr_SetString(PyExc_TypeError, "package must be a string"); + goto error; + } } - Py_INCREF(package); - - if (_PyDict_GetItemId(globals, &PyId___path__) == NULL) { - PyObject *partition = NULL; - PyObject *borrowed_dot = _PyUnicode_FromId(&single_dot); - if (borrowed_dot == NULL) { + else { + if (PyErr_WarnEx(PyExc_ImportWarning, + "can't resolve package from __spec__ or __package__, " + "falling back on __name__ and __path__", 1) < 0) { goto error; } - partition = PyUnicode_RPartition(package, borrowed_dot); - Py_DECREF(package); - if (partition == NULL) { + + package = _PyDict_GetItemId(globals, &PyId___name__); + if (package == NULL) { + PyErr_SetString(PyExc_KeyError, "'__name__' not in globals"); goto error; } - package = PyTuple_GET_ITEM(partition, 0); + Py_INCREF(package); - Py_DECREF(partition); + if (!PyUnicode_Check(package)) { + PyErr_SetString(PyExc_TypeError, "__name__ must be a string"); + goto error; + } + + if (_PyDict_GetItemId(globals, &PyId___path__) == NULL) { + PyObject *partition = NULL; + PyObject *borrowed_dot = _PyUnicode_FromId(&single_dot); + if (borrowed_dot == NULL) { + goto error; + } + partition = PyUnicode_RPartition(package, borrowed_dot); + Py_DECREF(package); + if (partition == NULL) { + goto error; + } + package = PyTuple_GET_ITEM(partition, 0); + Py_INCREF(package); + Py_DECREF(partition); + } } } -- cgit v1.2.1 From 8089b917b39ed072cbc1d03a4028cd39f0f25ecf Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 22 Jan 2016 15:25:50 -0800 Subject: Issue #25791: Warn when __package__ != __spec__.parent. In a previous change, __spec__.parent was prioritized over __package__. That is a backwards-compatibility break, but we do eventually want __spec__ to be the ground truth for module details. So this change reverts the change in semantics and instead raises an ImportWarning when __package__ != __spec__.parent to give people time to adjust to using spec objects. --- Python/import.c | 97 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 58 insertions(+), 39 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index c1071c0de3..22f9d2127a 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1415,60 +1415,79 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, goto error; } else if (level > 0) { + package = _PyDict_GetItemId(globals, &PyId___package__); spec = _PyDict_GetItemId(globals, &PyId___spec__); - if (spec != NULL) { - package = PyObject_GetAttrString(spec, "parent"); - } + if (package != NULL && package != Py_None) { + Py_INCREF(package); if (!PyUnicode_Check(package)) { + PyErr_SetString(PyExc_TypeError, "package must be a string"); + goto error; + } + else if (spec != NULL) { + int equal; + PyObject *parent = PyObject_GetAttrString(spec, "parent"); + if (parent == NULL) { + goto error; + } + + equal = PyObject_RichCompareBool(package, parent, Py_EQ); + Py_DECREF(parent); + if (equal < 0) { + goto error; + } + else if (equal == 0) { + if (PyErr_WarnEx(PyExc_ImportWarning, + "__package__ != __spec__.parent", 1) < 0) { + goto error; + } + } + } + } + else if (spec != NULL) { + package = PyObject_GetAttrString(spec, "parent"); + if (package == NULL) { + goto error; + } + else if (!PyUnicode_Check(package)) { PyErr_SetString(PyExc_TypeError, "__spec__.parent must be a string"); goto error; } } else { - package = _PyDict_GetItemId(globals, &PyId___package__); - if (package != NULL && package != Py_None) { - Py_INCREF(package); - if (!PyUnicode_Check(package)) { - PyErr_SetString(PyExc_TypeError, "package must be a string"); - goto error; - } + if (PyErr_WarnEx(PyExc_ImportWarning, + "can't resolve package from __spec__ or __package__, " + "falling back on __name__ and __path__", 1) < 0) { + goto error; } - else { - if (PyErr_WarnEx(PyExc_ImportWarning, - "can't resolve package from __spec__ or __package__, " - "falling back on __name__ and __path__", 1) < 0) { - goto error; - } - package = _PyDict_GetItemId(globals, &PyId___name__); - if (package == NULL) { - PyErr_SetString(PyExc_KeyError, "'__name__' not in globals"); - goto error; - } + package = _PyDict_GetItemId(globals, &PyId___name__); + if (package == NULL) { + PyErr_SetString(PyExc_KeyError, "'__name__' not in globals"); + goto error; + } - Py_INCREF(package); - if (!PyUnicode_Check(package)) { - PyErr_SetString(PyExc_TypeError, "__name__ must be a string"); + Py_INCREF(package); + if (!PyUnicode_Check(package)) { + PyErr_SetString(PyExc_TypeError, "__name__ must be a string"); + goto error; + } + + if (_PyDict_GetItemId(globals, &PyId___path__) == NULL) { + PyObject *partition = NULL; + PyObject *borrowed_dot = _PyUnicode_FromId(&single_dot); + if (borrowed_dot == NULL) { goto error; } - - if (_PyDict_GetItemId(globals, &PyId___path__) == NULL) { - PyObject *partition = NULL; - PyObject *borrowed_dot = _PyUnicode_FromId(&single_dot); - if (borrowed_dot == NULL) { - goto error; - } - partition = PyUnicode_RPartition(package, borrowed_dot); - Py_DECREF(package); - if (partition == NULL) { - goto error; - } - package = PyTuple_GET_ITEM(partition, 0); - Py_INCREF(package); - Py_DECREF(partition); + partition = PyUnicode_RPartition(package, borrowed_dot); + Py_DECREF(package); + if (partition == NULL) { + goto error; } + package = PyTuple_GET_ITEM(partition, 0); + Py_INCREF(package); + Py_DECREF(partition); } } -- cgit v1.2.1 From 0ee2c5b8d80a46dcbb0194a1443331f41f8d1d8f Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 22 Jan 2016 16:39:02 -0800 Subject: Issue #18018: Raise an ImportError if a relative import is attempted with no known parent package. Previously SystemError was raised if the parent package didn't exist (e.g., __package__ was set to ''). Thanks to Florent Xicluna and Yongzhi Pan for reporting the issue. --- Python/import.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 22f9d2127a..8ad5b4c167 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1424,7 +1424,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, PyErr_SetString(PyExc_TypeError, "package must be a string"); goto error; } - else if (spec != NULL) { + else if (spec != NULL && spec != Py_None) { int equal; PyObject *parent = PyObject_GetAttrString(spec, "parent"); if (parent == NULL) { @@ -1444,7 +1444,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, } } } - else if (spec != NULL) { + else if (spec != NULL && spec != Py_None) { package = PyObject_GetAttrString(spec, "parent"); if (package == NULL) { goto error; @@ -1491,7 +1491,12 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, } } - if (PyDict_GetItem(interp->modules, package) == NULL) { + if (PyUnicode_CompareWithASCIIString(package, "") == 0) { + PyErr_SetString(PyExc_ImportError, + "attempted relative import with no known parent package"); + goto error; + } + else if (PyDict_GetItem(interp->modules, package) == NULL) { PyErr_Format(PyExc_SystemError, "Parent module %R not loaded, cannot perform relative " "import", package); -- cgit v1.2.1 From 397ca3e0af84fb1ea32229aff143db8bd69e266c Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 10 Feb 2016 10:31:20 +0200 Subject: Issue #25698: Prevent possible replacing imported module with the empty one if the stack is too deep. --- Python/import.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index edf030d87a..0b843dafd3 100644 --- a/Python/import.c +++ b/Python/import.c @@ -671,9 +671,13 @@ PyImport_AddModuleObject(PyObject *name) PyObject *modules = PyImport_GetModuleDict(); PyObject *m; - if ((m = PyDict_GetItem(modules, name)) != NULL && - PyModule_Check(m)) + if ((m = PyDict_GetItemWithError(modules, name)) != NULL && + PyModule_Check(m)) { return m; + } + if (PyErr_Occurred()) { + return NULL; + } m = PyModule_NewObject(name); if (m == NULL) return NULL; -- cgit v1.2.1 From 00ef7da5a564f7674c65ce2a09c0b7edf07e6b7c Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 14 Apr 2016 12:36:11 +0300 Subject: fs_unicode_converter is no longer used. --- Python/import.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 0608924e43..6d71f2af0f 100644 --- a/Python/import.c +++ b/Python/import.c @@ -38,14 +38,6 @@ module _imp #include "clinic/import.c.h" -/*[python input] -class fs_unicode_converter(CConverter): - type = 'PyObject *' - converter = 'PyUnicode_FSDecoder' - -[python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=9d6786230166006e]*/ - /* Initialize things */ void -- cgit v1.2.1 From 74a2c7bd567be3d93b79ac859d88bd9b668df94d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 20 May 2016 11:36:13 +0200 Subject: Cleanup import.c * Replace PyUnicode_RPartition() with PyUnicode_FindChar() and PyUnicode_Substring() to avoid the creation of a temporary tuple. * Use PyUnicode_FromFormat() to build a string and avoid the single_dot ('.') singleton Thanks Serhiy Storchaka for your review. --- Python/import.c | 67 ++++++++++++++++++++++++--------------------------------- 1 file changed, 28 insertions(+), 39 deletions(-) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index 6d71f2af0f..d4c358f41e 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1349,7 +1349,6 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, _Py_IDENTIFIER(_find_and_load); _Py_IDENTIFIER(_handle_fromlist); _Py_IDENTIFIER(_lock_unlock_module); - _Py_static_string(single_dot, "."); PyObject *abs_name = NULL; PyObject *builtins_import = NULL; PyObject *final_mod = NULL; @@ -1471,19 +1470,25 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, } if (_PyDict_GetItemId(globals, &PyId___path__) == NULL) { - PyObject *partition = NULL; - PyObject *borrowed_dot = _PyUnicode_FromId(&single_dot); - if (borrowed_dot == NULL) { + Py_ssize_t dot; + + if (PyUnicode_READY(package) < 0) { goto error; } - partition = PyUnicode_RPartition(package, borrowed_dot); - Py_DECREF(package); - if (partition == NULL) { + + dot = PyUnicode_FindChar(package, '.', + 0, PyUnicode_GET_LENGTH(package), -1); + if (dot == -2) { goto error; } - package = PyTuple_GET_ITEM(partition, 0); - Py_INCREF(package); - Py_DECREF(partition); + + if (dot >= 0) { + PyObject *substr = PyUnicode_Substring(package, 0, dot); + if (substr == NULL) { + goto error; + } + Py_SETREF(package, substr); + } } } @@ -1531,17 +1536,8 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, goto error; if (PyUnicode_GET_LENGTH(name) > 0) { - PyObject *borrowed_dot, *seq = NULL; - - borrowed_dot = _PyUnicode_FromId(&single_dot); - seq = PyTuple_Pack(2, base, name); + abs_name = PyUnicode_FromFormat("%U.%U", base, name); Py_DECREF(base); - if (borrowed_dot == NULL || seq == NULL) { - goto error; - } - - abs_name = PyUnicode_Join(borrowed_dot, seq); - Py_DECREF(seq); if (abs_name == NULL) { goto error; } @@ -1639,43 +1635,36 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, if (has_from < 0) goto error; if (!has_from) { - if (level == 0 || PyUnicode_GET_LENGTH(name) > 0) { - PyObject *front = NULL; - PyObject *partition = NULL; - PyObject *borrowed_dot = _PyUnicode_FromId(&single_dot); + Py_ssize_t len = PyUnicode_GET_LENGTH(name); + if (level == 0 || len > 0) { + Py_ssize_t dot; - if (borrowed_dot == NULL) { + dot = PyUnicode_FindChar(name, '.', 0, len, 1); + if (dot == -2) { goto error; } - partition = PyUnicode_Partition(name, borrowed_dot); - if (partition == NULL) { - goto error; - } - - if (PyUnicode_GET_LENGTH(PyTuple_GET_ITEM(partition, 1)) == 0) { + if (dot == -1) { /* No dot in module name, simple exit */ - Py_DECREF(partition); final_mod = mod; Py_INCREF(mod); goto error; } - front = PyTuple_GET_ITEM(partition, 0); - Py_INCREF(front); - Py_DECREF(partition); - if (level == 0) { + PyObject *front = PyUnicode_Substring(name, 0, dot); + if (front == NULL) { + goto error; + } + final_mod = PyObject_CallFunctionObjArgs(builtins_import, front, NULL); Py_DECREF(front); } else { - Py_ssize_t cut_off = PyUnicode_GET_LENGTH(name) - - PyUnicode_GET_LENGTH(front); + Py_ssize_t cut_off = len - dot; Py_ssize_t abs_name_len = PyUnicode_GET_LENGTH(abs_name); PyObject *to_return = PyUnicode_Substring(abs_name, 0, abs_name_len - cut_off); - Py_DECREF(front); if (to_return == NULL) { goto error; } -- cgit v1.2.1