bpo-32023: Disallow genexprs without parenthesis in class definitions. (#4400)
This commit is contained in:
parent
edad8eebee
commit
ddbce13786
|
@ -638,10 +638,14 @@ Changes in Python behavior
|
|||
|
||||
f(1 for x in [1],)
|
||||
|
||||
class C(1 for x in [1]):
|
||||
pass
|
||||
|
||||
Python 3.7 now correctly raises a :exc:`SyntaxError`, as a generator
|
||||
expression always needs to be directly inside a set of parentheses
|
||||
and cannot have a comma on either side.
|
||||
(Contributed by Serhiy Storchaka in :issue:`32012`.)
|
||||
and cannot have a comma on either side, and the duplication of the
|
||||
parentheses can be omitted only on calls.
|
||||
(Contributed by Serhiy Storchaka in :issue:`32012` and :issue:`32023`.)
|
||||
|
||||
|
||||
Changes in the Python API
|
||||
|
|
|
@ -153,6 +153,10 @@ Traceback (most recent call last):
|
|||
SyntaxError: Generator expression must be parenthesized
|
||||
>>> f((x for x in L), 1)
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
>>> class C(x for x in L):
|
||||
... pass
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: invalid syntax
|
||||
|
||||
>>> def g(*args, **kwargs):
|
||||
... print(args, sorted(kwargs.items()))
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
SyntaxError is now correctly raised when a generator expression without
|
||||
parenthesis is used instead of an inheritance list in a class definition.
|
||||
The duplication of the parentheses can be omitted only on calls.
|
15
Python/ast.c
15
Python/ast.c
|
@ -11,6 +11,7 @@
|
|||
#include "pythonrun.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
static int validate_stmts(asdl_seq *);
|
||||
static int validate_exprs(asdl_seq *, expr_context_ty, int);
|
||||
|
@ -611,7 +612,7 @@ static stmt_ty ast_for_with_stmt(struct compiling *, const node *, int);
|
|||
static stmt_ty ast_for_for_stmt(struct compiling *, const node *, int);
|
||||
|
||||
/* Note different signature for ast_for_call */
|
||||
static expr_ty ast_for_call(struct compiling *, const node *, expr_ty);
|
||||
static expr_ty ast_for_call(struct compiling *, const node *, expr_ty, bool);
|
||||
|
||||
static PyObject *parsenumber(struct compiling *, const char *);
|
||||
static expr_ty parsestrplus(struct compiling *, const node *n);
|
||||
|
@ -1545,7 +1546,7 @@ ast_for_decorator(struct compiling *c, const node *n)
|
|||
name_expr = NULL;
|
||||
}
|
||||
else {
|
||||
d = ast_for_call(c, CHILD(n, 3), name_expr);
|
||||
d = ast_for_call(c, CHILD(n, 3), name_expr, true);
|
||||
if (!d)
|
||||
return NULL;
|
||||
name_expr = NULL;
|
||||
|
@ -2368,7 +2369,7 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr)
|
|||
return Call(left_expr, NULL, NULL, LINENO(n),
|
||||
n->n_col_offset, c->c_arena);
|
||||
else
|
||||
return ast_for_call(c, CHILD(n, 1), left_expr);
|
||||
return ast_for_call(c, CHILD(n, 1), left_expr, true);
|
||||
}
|
||||
else if (TYPE(CHILD(n, 0)) == DOT) {
|
||||
PyObject *attr_id = NEW_IDENTIFIER(CHILD(n, 1));
|
||||
|
@ -2705,7 +2706,7 @@ ast_for_expr(struct compiling *c, const node *n)
|
|||
}
|
||||
|
||||
static expr_ty
|
||||
ast_for_call(struct compiling *c, const node *n, expr_ty func)
|
||||
ast_for_call(struct compiling *c, const node *n, expr_ty func, bool allowgen)
|
||||
{
|
||||
/*
|
||||
arglist: argument (',' argument)* [',']
|
||||
|
@ -2728,6 +2729,10 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func)
|
|||
nargs++;
|
||||
else if (TYPE(CHILD(ch, 1)) == comp_for) {
|
||||
nargs++;
|
||||
if (!allowgen) {
|
||||
ast_error(c, ch, "invalid syntax");
|
||||
return NULL;
|
||||
}
|
||||
if (NCH(n) > 1) {
|
||||
ast_error(c, ch, "Generator expression must be parenthesized");
|
||||
return NULL;
|
||||
|
@ -3973,7 +3978,7 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq)
|
|||
if (!dummy_name)
|
||||
return NULL;
|
||||
dummy = Name(dummy_name, Load, LINENO(n), n->n_col_offset, c->c_arena);
|
||||
call = ast_for_call(c, CHILD(n, 3), dummy);
|
||||
call = ast_for_call(c, CHILD(n, 3), dummy, false);
|
||||
if (!call)
|
||||
return NULL;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue