summaryrefslogtreecommitdiff
path: root/Python
diff options
context:
space:
mode:
authorJeroen Demeyer <jeroen.k.demeyer@gmail.com>2019-11-05 16:48:04 +0100
committerMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2019-11-05 07:48:04 -0800
commitbf17d41826a8bb4bc1e34ba6345da98aac779e41 (patch)
tree1c256d14c23ffdcbbb5ae54efa546cf718a8f892 /Python
parentb3966639d28313809774ca3859a347b9007be8d2 (diff)
downloadcpython-git-bf17d41826a8bb4bc1e34ba6345da98aac779e41.tar.gz
bpo-37645: add new function _PyObject_FunctionStr() (GH-14890)
Additional note: the `method_check_args` function in `Objects/descrobject.c` is written in such a way that it applies to all kinds of descriptors. In particular, a future re-implementation of `wrapper_descriptor` could use that code. CC @vstinner @encukou https://bugs.python.org/issue37645 Automerge-Triggered-By: @encukou
Diffstat (limited to 'Python')
-rw-r--r--Python/ceval.c49
1 files changed, 30 insertions, 19 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 9019c78508..4d8f1b913c 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -5351,12 +5351,17 @@ static int
check_args_iterable(PyThreadState *tstate, PyObject *func, PyObject *args)
{
if (args->ob_type->tp_iter == NULL && !PySequence_Check(args)) {
- _PyErr_Format(tstate, PyExc_TypeError,
- "%.200s%.200s argument after * "
- "must be an iterable, not %.200s",
- PyEval_GetFuncName(func),
- PyEval_GetFuncDesc(func),
- args->ob_type->tp_name);
+ /* check_args_iterable() may be called with a live exception:
+ * clear it to prevent calling _PyObject_FunctionStr() with an
+ * exception set. */
+ PyErr_Clear();
+ PyObject *funcstr = _PyObject_FunctionStr(func);
+ if (funcstr != NULL) {
+ _PyErr_Format(tstate, PyExc_TypeError,
+ "%U argument after * must be an iterable, not %.200s",
+ funcstr, Py_TYPE(args)->tp_name);
+ Py_DECREF(funcstr);
+ }
return -1;
}
return 0;
@@ -5372,24 +5377,30 @@ format_kwargs_error(PyThreadState *tstate, PyObject *func, PyObject *kwargs)
* is not a mapping.
*/
if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) {
- _PyErr_Format(tstate, PyExc_TypeError,
- "%.200s%.200s argument after ** "
- "must be a mapping, not %.200s",
- PyEval_GetFuncName(func),
- PyEval_GetFuncDesc(func),
- kwargs->ob_type->tp_name);
+ PyErr_Clear();
+ PyObject *funcstr = _PyObject_FunctionStr(func);
+ if (funcstr != NULL) {
+ _PyErr_Format(
+ tstate, PyExc_TypeError,
+ "%U argument after ** must be a mapping, not %.200s",
+ funcstr, Py_TYPE(kwargs)->tp_name);
+ Py_DECREF(funcstr);
+ }
}
else if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
PyObject *exc, *val, *tb;
_PyErr_Fetch(tstate, &exc, &val, &tb);
if (val && PyTuple_Check(val) && PyTuple_GET_SIZE(val) == 1) {
- PyObject *key = PyTuple_GET_ITEM(val, 0);
- _PyErr_Format(tstate, PyExc_TypeError,
- "%.200s%.200s got multiple "
- "values for keyword argument '%S'",
- PyEval_GetFuncName(func),
- PyEval_GetFuncDesc(func),
- key);
+ PyErr_Clear();
+ PyObject *funcstr = _PyObject_FunctionStr(func);
+ if (funcstr != NULL) {
+ PyObject *key = PyTuple_GET_ITEM(val, 0);
+ _PyErr_Format(
+ tstate, PyExc_TypeError,
+ "%U got multiple values for keyword argument '%S'",
+ funcstr, key);
+ Py_DECREF(funcstr);
+ }
Py_XDECREF(exc);
Py_XDECREF(val);
Py_XDECREF(tb);