diff -r d9a3d23cf8f0 Python/ceval.c --- a/Python/ceval.c Tue Oct 14 00:53:13 2014 +0200 +++ b/Python/ceval.c Tue Oct 14 15:02:19 2014 +0300 @@ -135,6 +135,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 *); @@ -2462,45 +2463,13 @@ 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); - Py_DECREF(level); - Py_DECREF(from); - if (args == NULL) { - Py_DECREF(func); - STACKADJ(-1); - goto error; - } + PyObject *fromlist = POP(); + PyObject *level = TOP(); + PyObject *res; READ_TIMESTAMP(intr0); - res = PyEval_CallObject(func, args); + res = import_name(f, name, fromlist, level); READ_TIMESTAMP(intr1); - Py_DECREF(args); - Py_DECREF(func); SET_TOP(res); if (res == NULL) goto error; @@ -4690,6 +4659,86 @@ 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"); + Py_DECREF(level); + Py_DECREF(fromlist); + 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 (func == orig_func) { + int ilevel = _PyLong_AsInt(level); + Py_DECREF(func); + Py_DECREF(level); + if (ilevel == -1 && PyErr_Occurred()) { + Py_DECREF(fromlist); + 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 == -1) { + res = PyDict_GetItem(PyImport_GetModuleDict(), name); + if (res != NULL) { + Py_INCREF(res); + Py_DECREF(fromlist); + return res; + } + } + else if (i == -2) + PyErr_Clear(); + } + + res = PyImport_ImportModuleLevelObject( + name, + f->f_globals, + f->f_locals == NULL ? Py_None : f->f_locals, + fromlist, + ilevel); + Py_DECREF(fromlist); + return res; + } + + if (PyLong_AsLong(level) != -1 || PyErr_Occurred()) + 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); + Py_DECREF(level); + Py_DECREF(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;