diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2022-05-31 17:38:29 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-31 17:38:29 (GMT) |
commit | 07df8d5b2c715c9aa770c47986d59e272bf049f0 (patch) | |
tree | 53f040830007d2dff4aa8fcb8c1b85f2a79dc57c /Parser/string_parser.c | |
parent | bb900712a5511ba82ef64105fe28d2a6886a8fed (diff) | |
download | cpython-07df8d5b2c715c9aa770c47986d59e272bf049f0.zip cpython-07df8d5b2c715c9aa770c47986d59e272bf049f0.tar.gz cpython-07df8d5b2c715c9aa770c47986d59e272bf049f0.tar.bz2 |
gh-93283: Improve error message for f-string with invalid conversion character (GH-93349)
Diffstat (limited to 'Parser/string_parser.c')
-rw-r--r-- | Parser/string_parser.c | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/Parser/string_parser.c b/Parser/string_parser.c index 9c12d8c..c56ed20 100644 --- a/Parser/string_parser.c +++ b/Parser/string_parser.c @@ -767,27 +767,43 @@ fstring_find_expr(Parser *p, const char **str, const char *end, int raw, int rec /* Check for a conversion char, if present. */ if (**str == '!') { *str += 1; - if (*str >= end) { - goto unexpected_end_of_string; + const char *conv_start = *str; + while (1) { + if (*str >= end) { + goto unexpected_end_of_string; + } + if (**str == '}' || **str == ':') { + break; + } + *str += 1; + } + if (*str == conv_start) { + RAISE_SYNTAX_ERROR( + "f-string: missed conversion character"); + goto error; } - conversion = (unsigned char)**str; - *str += 1; - + conversion = (unsigned char)*conv_start; /* Validate the conversion. */ - if (!(conversion == 's' || conversion == 'r' || conversion == 'a')) { - RAISE_SYNTAX_ERROR( - "f-string: invalid conversion character: " - "expected 's', 'r', or 'a'"); + if ((*str != conv_start + 1) || + !(conversion == 's' || conversion == 'r' || conversion == 'a')) + { + PyObject *conv_obj = PyUnicode_FromStringAndSize(conv_start, + *str-conv_start); + if (conv_obj) { + RAISE_SYNTAX_ERROR( + "f-string: invalid conversion character %R: " + "expected 's', 'r', or 'a'", + conv_obj); + Py_DECREF(conv_obj); + } goto error; } } /* Check for the format spec, if present. */ - if (*str >= end) { - goto unexpected_end_of_string; - } + assert(*str < end); if (**str == ':') { *str += 1; if (*str >= end) { |