diff -r 703d9066c459 Python/ceval.c --- a/Python/ceval.c Mon Jun 20 21:42:05 2016 +0300 +++ b/Python/ceval.c Mon Jun 20 23:18:28 2016 +0200 @@ -139,6 +139,7 @@ static int maybe_call_line_trace(Py_trac PyThreadState *, PyFrameObject *, int *, int *, int *); static PyObject * cmp_outcome(int, PyObject *, PyObject *); +static PyObject * import_name(PyFrameObject *, PyObject *, PyObject *, PyObject *); static PyObject * import_from(PyObject *, PyObject *); static int import_all_from(PyObject *, PyObject *); static void format_exc_check_arg(PyObject *, const char *, PyObject *); @@ -2803,45 +2804,15 @@ PyEval_EvalFrameEx(PyFrameObject *f, int } TARGET(IMPORT_NAME) { - _Py_IDENTIFIER(__import__); PyObject *name = GETITEM(names, oparg); - PyObject *func = _PyDict_GetItemId(f->f_builtins, &PyId___import__); - PyObject *from, *level, *args, *res; - if (func == NULL) { - PyErr_SetString(PyExc_ImportError, - "__import__ not found"); - goto error; - } - Py_INCREF(func); - from = POP(); - level = TOP(); - if (PyLong_AsLong(level) != -1 || PyErr_Occurred()) - args = PyTuple_Pack(5, - name, - f->f_globals, - f->f_locals == NULL ? - Py_None : f->f_locals, - from, - level); - else - args = PyTuple_Pack(4, - name, - f->f_globals, - f->f_locals == NULL ? - Py_None : f->f_locals, - from); + PyObject *fromlist = POP(); + PyObject *level = TOP(); + PyObject *res; + READ_TIMESTAMP(intr0); + res = import_name(f, name, fromlist, level); Py_DECREF(level); - Py_DECREF(from); - if (args == NULL) { - Py_DECREF(func); - STACKADJ(-1); - goto error; - } - READ_TIMESTAMP(intr0); - res = PyEval_CallObject(func, args); + Py_DECREF(fromlist); READ_TIMESTAMP(intr1); - Py_DECREF(args); - Py_DECREF(func); SET_TOP(res); if (res == NULL) goto error; @@ -5157,6 +5128,91 @@ cmp_outcome(int op, PyObject *v, PyObjec } static PyObject * +import_name(PyFrameObject *f, PyObject *name, PyObject *fromlist, PyObject *level) +{ + _Py_IDENTIFIER(__import__); + static PyObject *orig_func = NULL; + PyObject *func = _PyDict_GetItemId(f->f_builtins, &PyId___import__); + PyObject *args, *res; + if (func == NULL) { + PyErr_SetString(PyExc_ImportError, "__import__ not found"); + return NULL; + } + Py_INCREF(func); + + /* Fast path for not overloaded __import__. */ + if (orig_func == NULL) { + orig_func = _PyDict_GetItemId( + PyThreadState_GET()->interp->builtins_copy, + &PyId___import__); + if (orig_func == NULL) { + PyErr_Clear(); + } + } + if (func == orig_func) { + int ilevel = 0; + Py_DECREF(func); + if (level != Py_None) { + ilevel = _PyLong_AsInt(level); + if (ilevel == -1 && PyErr_Occurred()) { + return NULL; + } + } + /* Fast path for simple import of the module which already is in + sys.modules. */ + if (fromlist == Py_None && ilevel == 0 && PyUnicode_Check(name)) { + Py_ssize_t i = PyUnicode_FindChar(name, '.', + 0, PyUnicode_GET_LENGTH(name), 1); + if (i == -2) { + PyErr_Clear(); + } + else if (i == -1) { + res = PyDict_GetItem(PyImport_GetModuleDict(), name); + if (res == NULL) { + PyErr_Clear(); + } + else if (res != Py_None) { + Py_INCREF(res); + return res; + } + } + } + + res = PyImport_ImportModuleLevelObject( + name, + f->f_globals, + f->f_locals == NULL ? Py_None : f->f_locals, + fromlist, + ilevel); + return res; + } + + if (level != Py_None) { + args = PyTuple_Pack(5, + name, + f->f_globals, + f->f_locals == NULL ? Py_None : f->f_locals, + fromlist, + level); + } + else { + args = PyTuple_Pack(4, + name, + f->f_globals, + f->f_locals == NULL ? Py_None : f->f_locals, + fromlist); + } + if (args == NULL) { + Py_DECREF(func); + return NULL; + } + res = PyEval_CallObject(func, args); + Py_DECREF(args); + Py_DECREF(func); + return res; +} + +static PyObject * import_from(PyObject *v, PyObject *name) { PyObject *x;