Compare commits

...

2 Commits

Author SHA1 Message Date
Pablo Galindo bfc413ce4f
[3.9] bpo-42806: Fix ast locations of f-strings inside parentheses (GH-24067) (GH-24069)
(cherry picked from commit bd2728b1e8)

Co-authored-by: Pablo Galindo <Pablogsal@gmail.com>
2021-01-03 01:32:43 +00:00
Lysandros Nikolaou 9a608ac17c
[3.9] bpo-40631: Disallow single parenthesized star target (GH-24027) (GH-24068)
(cherry picked from commit 2ea320dddd)

Automerge-Triggered-By: GH:pablogsal
2021-01-02 16:59:39 -08:00
7 changed files with 1035 additions and 701 deletions

View File

@ -563,18 +563,23 @@ star_targets[expr_ty]:
| a=star_target !',' { a }
| a=star_target b=(',' c=star_target { c })* [','] {
_Py_Tuple(CHECK(_PyPegen_seq_insert_in_front(p, a, b)), Store, EXTRA) }
star_targets_seq[asdl_seq*]: a=','.star_target+ [','] { a }
star_targets_list_seq[asdl_seq*]: a=','.star_target+ [','] { a }
star_targets_tuple_seq[asdl_seq*]:
| a=star_target b=(',' c=star_target { c })+ [','] { _PyPegen_seq_insert_in_front(p, a, b) }
| a=star_target ',' { _PyPegen_singleton_seq(p, a) }
star_target[expr_ty] (memo):
| '*' a=(!'*' star_target) {
_Py_Starred(CHECK(_PyPegen_set_expr_context(p, a, Store)), Store, EXTRA) }
| target_with_star_atom
target_with_star_atom[expr_ty] (memo):
| a=t_primary '.' b=NAME !t_lookahead { _Py_Attribute(a, b->v.Name.id, Store, EXTRA) }
| a=t_primary '[' b=slices ']' !t_lookahead { _Py_Subscript(a, b, Store, EXTRA) }
| star_atom
star_atom[expr_ty]:
| a=NAME { _PyPegen_set_expr_context(p, a, Store) }
| '(' a=star_target ')' { _PyPegen_set_expr_context(p, a, Store) }
| '(' a=[star_targets_seq] ')' { _Py_Tuple(a, Store, EXTRA) }
| '[' a=[star_targets_seq] ']' { _Py_List(a, Store, EXTRA) }
| '(' a=target_with_star_atom ')' { _PyPegen_set_expr_context(p, a, Store) }
| '(' a=[star_targets_tuple_seq] ')' { _Py_Tuple(a, Store, EXTRA) }
| '[' a=[star_targets_list_seq] ']' { _Py_List(a, Store, EXTRA) }
single_target[expr_ty]:
| single_subscript_attribute_target

View File

@ -332,6 +332,59 @@ non-important content
self.assertEqual(binop.left.col_offset, 4)
self.assertEqual(binop.right.col_offset, 7)
def test_ast_line_numbers_with_parentheses(self):
expr = """
x = (
f" {test(t)}"
)"""
t = ast.parse(expr)
self.assertEqual(type(t), ast.Module)
self.assertEqual(len(t.body), 1)
# check the test(t) location
call = t.body[0].value.values[1].value
self.assertEqual(type(call), ast.Call)
self.assertEqual(call.lineno, 3)
self.assertEqual(call.end_lineno, 3)
self.assertEqual(call.col_offset, 8)
self.assertEqual(call.end_col_offset, 15)
expr = """
x = (
'PERL_MM_OPT', (
f'wat'
f'some_string={f(x)} '
f'wat'
),
)
"""
t = ast.parse(expr)
self.assertEqual(type(t), ast.Module)
self.assertEqual(len(t.body), 1)
# check the fstring
fstring = t.body[0].value.elts[1]
self.assertEqual(type(fstring), ast.JoinedStr)
self.assertEqual(len(fstring.values), 3)
wat1, middle, wat2 = fstring.values
# check the first wat
self.assertEqual(type(wat1), ast.Constant)
self.assertEqual(wat1.lineno, 4)
self.assertEqual(wat1.end_lineno, 6)
self.assertEqual(wat1.col_offset, 12)
self.assertEqual(wat1.end_col_offset, 18)
# check the call
call = middle.value
self.assertEqual(type(call), ast.Call)
self.assertEqual(call.lineno, 5)
self.assertEqual(call.end_lineno, 5)
self.assertEqual(call.col_offset, 27)
self.assertEqual(call.end_col_offset, 31)
# check the second wat
self.assertEqual(type(wat2), ast.Constant)
self.assertEqual(wat2.lineno, 4)
self.assertEqual(wat2.end_lineno, 6)
self.assertEqual(wat2.col_offset, 12)
self.assertEqual(wat2.end_col_offset, 18)
def test_docstring(self):
def f():
f'''Not a docstring'''

View File

@ -346,6 +346,31 @@ Now some general starred expressions (all fail).
...
SyntaxError: can't use starred expression here
>>> (*x),y = 1, 2 # doctest:+ELLIPSIS
Traceback (most recent call last):
...
SyntaxError: can't use starred expression here
>>> (((*x))),y = 1, 2 # doctest:+ELLIPSIS
Traceback (most recent call last):
...
SyntaxError: can't use starred expression here
>>> z,(*x),y = 1, 2, 4 # doctest:+ELLIPSIS
Traceback (most recent call last):
...
SyntaxError: can't use starred expression here
>>> z,(*x) = 1, 2 # doctest:+ELLIPSIS
Traceback (most recent call last):
...
SyntaxError: can't use starred expression here
>>> ((*x),y) = 1, 2 # doctest:+ELLIPSIS
Traceback (most recent call last):
...
SyntaxError: can't use starred expression here
Some size constraints (all fail.)
>>> s = ", ".join("a%d" % i for i in range(1<<8)) + ", *rest = range(1<<8 + 1)"

View File

@ -0,0 +1,2 @@
Fix regression where a single parenthesized starred expression was a valid
assignment target.

View File

@ -0,0 +1,2 @@
Fix the column offsets for f-strings :mod:`ast` nodes surrounded by
parentheses and for nodes that spawn multiple lines. Patch by Pablo Galindo.

File diff suppressed because it is too large Load Diff

View File

@ -410,7 +410,7 @@ fstring_compile_expr(Parser *p, const char *expr_start, const char *expr_end,
Parser *p2 = _PyPegen_Parser_New(tok, Py_fstring_input, p->flags, p->feature_version,
NULL, p->arena);
p2->starting_lineno = t->lineno + lines - 1;
p2->starting_col_offset = p->tok->first_lineno == p->tok->lineno ? t->col_offset + cols : cols;
p2->starting_col_offset = t->col_offset + cols;
expr = _PyPegen_run_parser(p2);