summaryrefslogtreecommitdiffstats
path: root/Python/ast.c
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2017-06-08 21:38:06 (GMT)
committerGitHub <noreply@github.com>2017-06-08 21:38:06 (GMT)
commit570b1c971c31cd08dbf060f4e21636c40aa47786 (patch)
treef13cb58e5792e0a969e4dc6c59f0624ec9b9cbe2 /Python/ast.c
parentb319d09ee4427aac1ee8f298692127d34ef57dc0 (diff)
downloadcpython-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.c31
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);