summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorNikita Sobolev <mail@sobolevn.me>2021-09-24 15:18:04 (GMT)
committerGitHub <noreply@github.com>2021-09-24 15:18:04 (GMT)
commit8d8729146f21f61af66e70d3ae9501ea6bdccd09 (patch)
treeed5905df6eb9d2bbab7513b966039cc0642635ca /Python
parent3f8b23f8ddab75d9b77a3997d54e663187e12cc8 (diff)
downloadcpython-8d8729146f21f61af66e70d3ae9501ea6bdccd09.zip
cpython-8d8729146f21f61af66e70d3ae9501ea6bdccd09.tar.gz
cpython-8d8729146f21f61af66e70d3ae9501ea6bdccd09.tar.bz2
bpo-20524: adds better error message for `.format()` (GH-28310)
It now lists the bad format_spec and the type of the object.
Diffstat (limited to 'Python')
-rw-r--r--Python/formatter_unicode.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c
index 7b5a7bd..9071bf3 100644
--- a/Python/formatter_unicode.c
+++ b/Python/formatter_unicode.c
@@ -162,7 +162,8 @@ DEBUG_PRINT_FORMAT_SPEC(InternalFormatSpec *format)
if failure, sets the exception
*/
static int
-parse_internal_render_format_spec(PyObject *format_spec,
+parse_internal_render_format_spec(PyObject *obj,
+ PyObject *format_spec,
Py_ssize_t start, Py_ssize_t end,
InternalFormatSpec *format,
char default_type,
@@ -279,8 +280,19 @@ parse_internal_render_format_spec(PyObject *format_spec,
/* Finally, parse the type field. */
if (end-pos > 1) {
- /* More than one char remain, invalid format specifier. */
- PyErr_Format(PyExc_ValueError, "Invalid format specifier");
+ /* More than one char remains, so this is an invalid format
+ specifier. */
+ /* Create a temporary object that contains the format spec we're
+ operating on. It's format_spec[start:end] (in Python syntax). */
+ PyObject* actual_format_spec = PyUnicode_FromKindAndData(kind,
+ (char*)data + kind*start,
+ end-start);
+ if (actual_format_spec != NULL) {
+ PyErr_Format(PyExc_ValueError,
+ "Invalid format specifier '%U' for object of type '%.200s'",
+ actual_format_spec, Py_TYPE(obj)->tp_name);
+ Py_DECREF(actual_format_spec);
+ }
return 0;
}
@@ -1444,7 +1456,7 @@ _PyUnicode_FormatAdvancedWriter(_PyUnicodeWriter *writer,
}
/* parse the format_spec */
- if (!parse_internal_render_format_spec(format_spec, start, end,
+ if (!parse_internal_render_format_spec(obj, format_spec, start, end,
&format, 's', '<'))
return -1;
@@ -1480,7 +1492,7 @@ _PyLong_FormatAdvancedWriter(_PyUnicodeWriter *writer,
}
/* parse the format_spec */
- if (!parse_internal_render_format_spec(format_spec, start, end,
+ if (!parse_internal_render_format_spec(obj, format_spec, start, end,
&format, 'd', '>'))
goto done;
@@ -1536,7 +1548,7 @@ _PyFloat_FormatAdvancedWriter(_PyUnicodeWriter *writer,
return format_obj(obj, writer);
/* parse the format_spec */
- if (!parse_internal_render_format_spec(format_spec, start, end,
+ if (!parse_internal_render_format_spec(obj, format_spec, start, end,
&format, '\0', '>'))
return -1;
@@ -1575,7 +1587,7 @@ _PyComplex_FormatAdvancedWriter(_PyUnicodeWriter *writer,
return format_obj(obj, writer);
/* parse the format_spec */
- if (!parse_internal_render_format_spec(format_spec, start, end,
+ if (!parse_internal_render_format_spec(obj, format_spec, start, end,
&format, '\0', '>'))
return -1;