diff -r 23d9daed4b14 Include/eval.h --- a/Include/eval.h Tue Mar 04 23:22:15 2014 +0000 +++ b/Include/eval.h Sun Mar 09 18:20:38 2014 -0300 @@ -15,7 +15,8 @@ PyObject **args, int argc, PyObject **kwds, int kwdc, PyObject **defs, int defc, - PyObject *kwdefs, PyObject *closure); + PyObject *kwdefs, PyObject *closure, + PyObject *func_name); #ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) _PyEval_CallTracing(PyObject *func, PyObject *args); diff -r 23d9daed4b14 Include/funcobject.h --- a/Include/funcobject.h Tue Mar 04 23:22:15 2014 +0000 +++ b/Include/funcobject.h Sun Mar 09 18:20:38 2014 -0300 @@ -74,6 +74,8 @@ (((PyFunctionObject *)func) -> func_closure) #define PyFunction_GET_ANNOTATIONS(func) \ (((PyFunctionObject *)func) -> func_annotations) +#define PyFunction_GET_NAME(func) \ + (((PyFunctionObject *)func) -> func_name) /* The classmethod and staticmethod types lives here, too */ PyAPI_DATA(PyTypeObject) PyClassMethod_Type; diff -r 23d9daed4b14 Lib/test/test_extcall.py --- a/Lib/test/test_extcall.py Tue Mar 04 23:22:15 2014 +0000 +++ b/Lib/test/test_extcall.py Sun Mar 09 18:20:38 2014 -0300 @@ -337,6 +337,26 @@ ... TypeError: f() missing 5 required keyword-only arguments: 'a', 'b', 'c', 'd', and 'e' +Use function name in traceback (issue #4322): + + >>> def f(): pass + >>> f.__name__ = 'g' + >>> f(1) + Traceback (most recent call last): + ... + TypeError: g() takes 0 positional arguments but 1 was given + >>> def f(a): pass + >>> f.__name__ = 'g' + >>> f() + Traceback (most recent call last): + ... + TypeError: g() missing 1 required positional argument: 'a' + >>> def f(a): pass + >>> f.__name__ = 'g' + >>> f(b=1) + Traceback (most recent call last): + ... + TypeError: g() got an unexpected keyword argument 'b' """ import sys diff -r 23d9daed4b14 Objects/funcobject.c --- a/Objects/funcobject.c Tue Mar 04 23:22:15 2014 +0000 +++ b/Objects/funcobject.c Sun Mar 09 18:20:38 2014 -0300 @@ -635,7 +635,8 @@ &PyTuple_GET_ITEM(arg, 0), PyTuple_GET_SIZE(arg), k, nk, d, nd, PyFunction_GET_KW_DEFAULTS(func), - PyFunction_GET_CLOSURE(func)); + PyFunction_GET_CLOSURE(func), + PyFunction_GET_NAME(func)); Py_XDECREF(kwtuple); diff -r 23d9daed4b14 Python/bltinmodule.c --- a/Python/bltinmodule.c Tue Mar 04 23:22:15 2014 +0000 +++ b/Python/bltinmodule.c Sun Mar 09 18:20:38 2014 -0300 @@ -172,7 +172,7 @@ } cell = PyEval_EvalCodeEx(PyFunction_GET_CODE(func), PyFunction_GET_GLOBALS(func), ns, NULL, 0, NULL, 0, NULL, 0, NULL, - PyFunction_GET_CLOSURE(func)); + PyFunction_GET_CLOSURE(func), PyFunction_GET_NAME(func)); if (cell != NULL) { PyObject *margs; margs = PyTuple_Pack(3, name, bases, ns); diff -r 23d9daed4b14 Python/ceval.c --- a/Python/ceval.c Tue Mar 04 23:22:15 2014 +0000 +++ b/Python/ceval.c Sun Mar 09 18:20:38 2014 -0300 @@ -775,7 +775,7 @@ (PyObject **)NULL, 0, (PyObject **)NULL, 0, (PyObject **)NULL, 0, - NULL, NULL); + NULL, NULL, NULL); } @@ -3224,7 +3224,8 @@ } static void -format_missing(const char *kind, PyCodeObject *co, PyObject *names) +format_missing(const char *kind, PyCodeObject *co, PyObject *names, + PyObject *func_name) { int err; Py_ssize_t len = PyList_GET_SIZE(names); @@ -3277,7 +3278,7 @@ return; PyErr_Format(PyExc_TypeError, "%U() missing %i required %s argument%s: %U", - co->co_name, + func_name, len, kind, len == 1 ? "" : "s", @@ -3287,7 +3288,7 @@ static void missing_arguments(PyCodeObject *co, int missing, int defcount, - PyObject **fastlocals) + PyObject **fastlocals, PyObject *func_name) { int i, j = 0; int start, end; @@ -3319,12 +3320,13 @@ } } assert(j == missing); - format_missing(kind, co, missing_names); + format_missing(kind, co, missing_names, func_name); Py_DECREF(missing_names); } static void -too_many_positional(PyCodeObject *co, int given, int defcount, PyObject **fastlocals) +too_many_positional(PyCodeObject *co, int given, int defcount, PyObject **fastlocals, + PyObject *func_name) { int plural; int kwonly_given = 0; @@ -3363,7 +3365,7 @@ } PyErr_Format(PyExc_TypeError, "%U() takes %U positional argument%s but %d%U %s given", - co->co_name, + func_name, sig, plural ? "s" : "", given, @@ -3380,7 +3382,8 @@ PyObject * PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, PyObject **args, int argcount, PyObject **kws, int kwcount, - PyObject **defs, int defcount, PyObject *kwdefs, PyObject *closure) + PyObject **defs, int defcount, PyObject *kwdefs, PyObject *closure, + PyObject *func_name) { PyCodeObject* co = (PyCodeObject*)_co; PyFrameObject *f; @@ -3444,7 +3447,7 @@ if (keyword == NULL || !PyUnicode_Check(keyword)) { PyErr_Format(PyExc_TypeError, "%U() keywords must be strings", - co->co_name); + func_name); goto fail; } /* Speed hack: do raw pointer compares. As names are @@ -3469,7 +3472,7 @@ PyErr_Format(PyExc_TypeError, "%U() got an unexpected " "keyword argument '%S'", - co->co_name, + func_name, keyword); goto fail; } @@ -3482,7 +3485,7 @@ PyErr_Format(PyExc_TypeError, "%U() got multiple " "values for argument '%S'", - co->co_name, + func_name, keyword); goto fail; } @@ -3490,7 +3493,7 @@ SETLOCAL(j, value); } if (argcount > co->co_argcount && !(co->co_flags & CO_VARARGS)) { - too_many_positional(co, argcount, defcount, fastlocals); + too_many_positional(co, argcount, defcount, fastlocals, func_name); goto fail; } if (argcount < co->co_argcount) { @@ -3500,7 +3503,7 @@ if (GETLOCAL(i) == NULL) missing++; if (missing) { - missing_arguments(co, missing, defcount, fastlocals); + missing_arguments(co, missing, defcount, fastlocals, func_name); goto fail; } if (n > m) @@ -3533,7 +3536,7 @@ missing++; } if (missing) { - missing_arguments(co, missing, -1, fastlocals); + missing_arguments(co, missing, -1, fastlocals, func_name); goto fail; } } @@ -4334,7 +4337,8 @@ return PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, (*pp_stack)-n, na, (*pp_stack)-2*nk, nk, d, nd, kwdefs, - PyFunction_GET_CLOSURE(func)); + PyFunction_GET_CLOSURE(func), + PyFunction_GET_NAME(func)); } static PyObject *