diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2017-06-08 21:38:06 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-08 21:38:06 (GMT) |
commit | 570b1c971c31cd08dbf060f4e21636c40aa47786 (patch) | |
tree | f13cb58e5792e0a969e4dc6c59f0624ec9b9cbe2 /Python/ast.c | |
parent | b319d09ee4427aac1ee8f298692127d34ef57dc0 (diff) | |
download | cpython-570b1c971c31cd08dbf060f4e21636c40aa47786.zip cpython-570b1c971c31cd08dbf060f4e21636c40aa47786.tar.gz cpython-570b1c971c31cd08dbf060f4e21636c40aa47786.tar.bz2 |
[3.6] bpo-30529: Fix errors for invalid whitespaces in f-string subexpressions. (GH-1888) (#2013)
'invalid character in identifier' now is raised instead of
'f-string: empty expression not allowed' if a subexpression contains
only whitespaces and they are not accepted by Python parser.
(cherry picked from commit 2e9cd58)
Diffstat (limited to 'Python/ast.c')
-rw-r--r-- | Python/ast.c | 31 |
1 files changed, 7 insertions, 24 deletions
diff --git a/Python/ast.c b/Python/ast.c index ed05a1e..c61ca4b 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -4247,49 +4247,32 @@ fstring_compile_expr(const char *expr_start, const char *expr_end, struct compiling *c, const node *n) { - int all_whitespace = 1; - int kind; - void *data; PyCompilerFlags cf; mod_ty mod; char *str; - PyObject *o; Py_ssize_t len; - Py_ssize_t i; + const char *s; assert(expr_end >= expr_start); assert(*(expr_start-1) == '{'); assert(*expr_end == '}' || *expr_end == '!' || *expr_end == ':'); - /* We know there are no escapes here, because backslashes are not allowed, - and we know it's utf-8 encoded (per PEP 263). But, in order to check - that each char is not whitespace, we need to decode it to unicode. - Which is unfortunate, but such is life. */ - /* If the substring is all whitespace, it's an error. We need to catch this here, and not when we call PyParser_ASTFromString, because turning the expression '' in to '()' would go from being invalid to valid. */ - /* Note that this code says an empty string is all whitespace. That's - important. There's a test for it: f'{}'. */ - o = PyUnicode_DecodeUTF8(expr_start, expr_end-expr_start, NULL); - if (o == NULL) - return NULL; - len = PyUnicode_GET_LENGTH(o); - kind = PyUnicode_KIND(o); - data = PyUnicode_DATA(o); - for (i = 0; i < len; i++) { - if (!Py_UNICODE_ISSPACE(PyUnicode_READ(kind, data, i))) { - all_whitespace = 0; + for (s = expr_start; s != expr_end; s++) { + char c = *s; + /* The Python parser ignores only the following whitespace + characters (\r already is converted to \n). */ + if (!(c == ' ' || c == '\t' || c == '\n' || c == '\f')) { break; } } - Py_DECREF(o); - if (all_whitespace) { + if (s == expr_end) { ast_error(c, n, "f-string: empty expression not allowed"); return NULL; } - /* Reuse len to be the length of the utf-8 input string. */ len = expr_end - expr_start; /* Allocate 3 extra bytes: open paren, close paren, null byte. */ str = PyMem_RawMalloc(len + 3); |