diff -r 1c51f1650c42 Python/ceval.c --- a/Python/ceval.c Fri Dec 26 23:08:58 2014 -0800 +++ b/Python/ceval.c Mon Dec 29 03:06:44 2014 +1100 @@ -780,6 +780,17 @@ NULL, NULL); } +/* Helper function for when a name isn't found. Returns new reference or NULL if NameError raised. */ +static PyObject *name_not_found(PyObject *name) +{ + PyObject *func = PySys_GetObject("__getglobal__"); + if (func) { + PyObject *v = PyObject_CallFunctionObjArgs(func, name, NULL); + if (v) return v; + } + format_exc_check_arg(PyExc_NameError, NAME_ERROR_MSG, name); + return NULL; +} /* Interpreter main loop */ @@ -2214,21 +2225,19 @@ if (PyDict_CheckExact(f->f_builtins)) { v = PyDict_GetItem(f->f_builtins, name); if (v == NULL) { - format_exc_check_arg( - PyExc_NameError, - NAME_ERROR_MSG, name); - goto error; + v = name_not_found(name); + if (v == NULL) goto error; } - Py_INCREF(v); + else Py_INCREF(v); } else { v = PyObject_GetItem(f->f_builtins, name); if (v == NULL) { - if (PyErr_ExceptionMatches(PyExc_KeyError)) - format_exc_check_arg( - PyExc_NameError, - NAME_ERROR_MSG, name); - goto error; + if (PyErr_ExceptionMatches(PyExc_KeyError)) { + v = name_not_found(name); + if (v == NULL) goto error; + } + PyErr_Clear(); } } } @@ -2246,12 +2255,13 @@ (PyDictObject *)f->f_builtins, name); if (v == NULL) { - if (!_PyErr_OCCURRED()) - format_exc_check_arg(PyExc_NameError, - NAME_ERROR_MSG, name); - goto error; + if (!_PyErr_OCCURRED()) { + v = name_not_found(name); + if (!v) goto error; + } + else goto error; } - Py_INCREF(v); + else Py_INCREF(v); } else { /* Slow-path if globals or builtins is not a dict */ @@ -2259,11 +2269,12 @@ if (v == NULL) { v = PyObject_GetItem(f->f_builtins, name); if (v == NULL) { - if (PyErr_ExceptionMatches(PyExc_KeyError)) - format_exc_check_arg( - PyExc_NameError, - NAME_ERROR_MSG, name); - goto error; + if (PyErr_ExceptionMatches(PyExc_KeyError)) { + v = name_not_found(name); + if (!v) goto error; + PyErr_Clear(); + } + else goto error; } } }