bpo-40903: Handle multiple '=' in invalid assignment rules in the PEG parser (GH-20697)

Automerge-Triggered-By: @pablogsal
This commit is contained in:
Pablo Galindo 2020-06-08 02:57:00 +01:00 committed by GitHub
parent 843c277656
commit 9f495908c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 558 additions and 342 deletions

View File

@ -92,7 +92,7 @@ assignment[stmt_ty]:
| a=('(' b=single_target ')' { b } | a=('(' b=single_target ')' { b }
| single_subscript_attribute_target) ':' b=expression c=['=' d=annotated_rhs { d }] { | single_subscript_attribute_target) ':' b=expression c=['=' d=annotated_rhs { d }] {
CHECK_VERSION(6, "Variable annotations syntax is", _Py_AnnAssign(a, b, c, 0, EXTRA)) } CHECK_VERSION(6, "Variable annotations syntax is", _Py_AnnAssign(a, b, c, 0, EXTRA)) }
| a=(z=star_targets '=' { z })+ b=(yield_expr | star_expressions) tc=[TYPE_COMMENT] { | a=(z=star_targets '=' { z })+ b=(yield_expr | star_expressions) !'=' tc=[TYPE_COMMENT] {
_Py_Assign(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA) } _Py_Assign(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA) }
| a=single_target b=augassign c=(yield_expr | star_expressions) { | a=single_target b=augassign c=(yield_expr | star_expressions) {
_Py_AugAssign(a, b->kind, c, EXTRA) } _Py_AugAssign(a, b->kind, c, EXTRA) }
@ -646,10 +646,11 @@ invalid_assignment:
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "only single target (not tuple) can be annotated") } RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "only single target (not tuple) can be annotated") }
| a=expression ':' expression ['=' annotated_rhs] { | a=expression ':' expression ['=' annotated_rhs] {
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "illegal target for annotation") } RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "illegal target for annotation") }
| a=star_expressions '=' (yield_expr | star_expressions) { | (star_targets '=')* a=star_expressions '=' {
RAISE_SYNTAX_ERROR_KNOWN_LOCATION( RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
_PyPegen_get_invalid_target(a), _PyPegen_get_invalid_target(a),
"cannot assign to %s", _PyPegen_get_expr_name(_PyPegen_get_invalid_target(a))) } "cannot assign to %s", _PyPegen_get_expr_name(_PyPegen_get_invalid_target(a))) }
| (star_targets '=')* a=yield_expr '=' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "assignment to yield expression not possible") }
| a=star_expressions augassign (yield_expr | star_expressions) { | a=star_expressions augassign (yield_expr | star_expressions) {
RAISE_SYNTAX_ERROR_KNOWN_LOCATION( RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
a, a,

View File

@ -63,6 +63,10 @@ SyntaxError: cannot assign to __debug__
Traceback (most recent call last): Traceback (most recent call last):
SyntaxError: cannot assign to function call SyntaxError: cannot assign to function call
>>> yield = 1
Traceback (most recent call last):
SyntaxError: assignment to yield expression not possible
>>> del f() >>> del f()
Traceback (most recent call last): Traceback (most recent call last):
SyntaxError: cannot delete function call SyntaxError: cannot delete function call
@ -136,6 +140,18 @@ SyntaxError: cannot assign to operator
Traceback (most recent call last): Traceback (most recent call last):
SyntaxError: cannot assign to conditional expression SyntaxError: cannot assign to conditional expression
>>> True = True = 3
Traceback (most recent call last):
SyntaxError: cannot assign to True
>>> x = y = True = z = 3
Traceback (most recent call last):
SyntaxError: cannot assign to True
>>> x = y = yield = 1
Traceback (most recent call last):
SyntaxError: assignment to yield expression not possible
>>> a, b += 1, 2 >>> a, b += 1, 2
Traceback (most recent call last): Traceback (most recent call last):
SyntaxError: 'tuple' is an illegal expression for augmented assignment SyntaxError: 'tuple' is an illegal expression for augmented assignment
@ -148,6 +164,10 @@ SyntaxError: 'tuple' is an illegal expression for augmented assignment
Traceback (most recent call last): Traceback (most recent call last):
SyntaxError: 'list' is an illegal expression for augmented assignment SyntaxError: 'list' is an illegal expression for augmented assignment
>>> p = p =
Traceback (most recent call last):
SyntaxError: invalid syntax
From compiler_complex_args(): From compiler_complex_args():
>>> def f(None=1): >>> def f(None=1):
@ -155,7 +175,6 @@ From compiler_complex_args():
Traceback (most recent call last): Traceback (most recent call last):
SyntaxError: invalid syntax SyntaxError: invalid syntax
From ast_for_arguments(): From ast_for_arguments():
>>> def f(x, y=1, z): >>> def f(x, y=1, z):

View File

@ -0,0 +1 @@
Fixed a possible segfault in the new PEG parser when producing error messages for invalid assignments of the form :code:`p=p=`. Patch by Pablo Galindo

File diff suppressed because it is too large Load Diff

View File

@ -161,6 +161,7 @@ byte_offset_to_character_offset(PyObject *line, int col_offset)
const char * const char *
_PyPegen_get_expr_name(expr_ty e) _PyPegen_get_expr_name(expr_ty e)
{ {
assert(e != NULL);
switch (e->kind) { switch (e->kind) {
case Attribute_kind: case Attribute_kind:
return "attribute"; return "attribute";