mirror of https://github.com/python/cpython
gh-111420: Allow type comments in parenthesized `with` statements (#111468)
This commit is contained in:
parent
faa5f6053d
commit
453e96e302
|
@ -391,8 +391,8 @@ for_stmt[stmt_ty]:
|
|||
|
||||
with_stmt[stmt_ty]:
|
||||
| invalid_with_stmt_indent
|
||||
| 'with' '(' a[asdl_withitem_seq*]=','.with_item+ ','? ')' ':' b=block {
|
||||
CHECK_VERSION(stmt_ty, 9, "Parenthesized context managers are", _PyAST_With(a, b, NULL, EXTRA)) }
|
||||
| 'with' '(' a[asdl_withitem_seq*]=','.with_item+ ','? ')' ':' tc=[TYPE_COMMENT] b=block {
|
||||
CHECK_VERSION(stmt_ty, 9, "Parenthesized context managers are", _PyAST_With(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA)) }
|
||||
| 'with' a[asdl_withitem_seq*]=','.with_item+ ':' tc=[TYPE_COMMENT] b=block {
|
||||
_PyAST_With(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA) }
|
||||
| 'async' 'with' '(' a[asdl_withitem_seq*]=','.with_item+ ','? ')' ':' b=block {
|
||||
|
|
|
@ -100,6 +100,8 @@ exec_tests = [
|
|||
# With
|
||||
"with x as y: pass",
|
||||
"with x as y, z as q: pass",
|
||||
"with (x as y): pass",
|
||||
"with (x, y): pass",
|
||||
# Raise
|
||||
"raise Exception('string')",
|
||||
# TryExcept
|
||||
|
@ -3015,6 +3017,8 @@ exec_results = [
|
|||
('Module', [('If', (1, 0, 6, 6), ('Name', (1, 3, 1, 4), 'a', ('Load',)), [('Pass', (2, 2, 2, 6))], [('If', (3, 0, 6, 6), ('Name', (3, 5, 3, 6), 'b', ('Load',)), [('Pass', (4, 2, 4, 6))], [('Pass', (6, 2, 6, 6))])])], []),
|
||||
('Module', [('With', (1, 0, 1, 17), [('withitem', ('Name', (1, 5, 1, 6), 'x', ('Load',)), ('Name', (1, 10, 1, 11), 'y', ('Store',)))], [('Pass', (1, 13, 1, 17))], None)], []),
|
||||
('Module', [('With', (1, 0, 1, 25), [('withitem', ('Name', (1, 5, 1, 6), 'x', ('Load',)), ('Name', (1, 10, 1, 11), 'y', ('Store',))), ('withitem', ('Name', (1, 13, 1, 14), 'z', ('Load',)), ('Name', (1, 18, 1, 19), 'q', ('Store',)))], [('Pass', (1, 21, 1, 25))], None)], []),
|
||||
('Module', [('With', (1, 0, 1, 19), [('withitem', ('Name', (1, 6, 1, 7), 'x', ('Load',)), ('Name', (1, 11, 1, 12), 'y', ('Store',)))], [('Pass', (1, 15, 1, 19))], None)], []),
|
||||
('Module', [('With', (1, 0, 1, 17), [('withitem', ('Name', (1, 6, 1, 7), 'x', ('Load',)), None), ('withitem', ('Name', (1, 9, 1, 10), 'y', ('Load',)), None)], [('Pass', (1, 13, 1, 17))], None)], []),
|
||||
('Module', [('Raise', (1, 0, 1, 25), ('Call', (1, 6, 1, 25), ('Name', (1, 6, 1, 15), 'Exception', ('Load',)), [('Constant', (1, 16, 1, 24), 'string', None)], []), None)], []),
|
||||
('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [('ExceptHandler', (3, 0, 4, 6), ('Name', (3, 7, 3, 16), 'Exception', ('Load',)), None, [('Pass', (4, 2, 4, 6))])], [], [])], []),
|
||||
('Module', [('Try', (1, 0, 4, 6), [('Pass', (2, 2, 2, 6))], [], [], [('Pass', (4, 2, 4, 6))])], []),
|
||||
|
|
|
@ -66,6 +66,14 @@ with context() as a: # type: int
|
|||
pass
|
||||
"""
|
||||
|
||||
parenthesized_withstmt = """\
|
||||
with (a as b): # type: int
|
||||
pass
|
||||
|
||||
with (a, b): # type: int
|
||||
pass
|
||||
"""
|
||||
|
||||
vardecl = """\
|
||||
a = 0 # type: int
|
||||
"""
|
||||
|
@ -300,6 +308,14 @@ class TypeCommentTests(unittest.TestCase):
|
|||
tree = self.classic_parse(withstmt)
|
||||
self.assertEqual(tree.body[0].type_comment, None)
|
||||
|
||||
def test_parenthesized_withstmt(self):
|
||||
for tree in self.parse_all(parenthesized_withstmt, minver=9):
|
||||
self.assertEqual(tree.body[0].type_comment, "int")
|
||||
self.assertEqual(tree.body[1].type_comment, "int")
|
||||
tree = self.classic_parse(parenthesized_withstmt)
|
||||
self.assertEqual(tree.body[0].type_comment, None)
|
||||
self.assertEqual(tree.body[1].type_comment, None)
|
||||
|
||||
def test_vardecl(self):
|
||||
for tree in self.parse_all(vardecl):
|
||||
self.assertEqual(tree.body[0].type_comment, "int")
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Allow type comments in parenthesized ``with`` statements
|
|
@ -6483,7 +6483,7 @@ for_stmt_rule(Parser *p)
|
|||
|
||||
// with_stmt:
|
||||
// | invalid_with_stmt_indent
|
||||
// | 'with' '(' ','.with_item+ ','? ')' ':' block
|
||||
// | 'with' '(' ','.with_item+ ','? ')' ':' TYPE_COMMENT? block
|
||||
// | 'with' ','.with_item+ ':' TYPE_COMMENT? block
|
||||
// | 'async' 'with' '(' ','.with_item+ ','? ')' ':' block
|
||||
// | 'async' 'with' ','.with_item+ ':' TYPE_COMMENT? block
|
||||
|
@ -6528,12 +6528,12 @@ with_stmt_rule(Parser *p)
|
|||
D(fprintf(stderr, "%*c%s with_stmt[%d-%d]: %s failed!\n", p->level, ' ',
|
||||
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_with_stmt_indent"));
|
||||
}
|
||||
{ // 'with' '(' ','.with_item+ ','? ')' ':' block
|
||||
{ // 'with' '(' ','.with_item+ ','? ')' ':' TYPE_COMMENT? block
|
||||
if (p->error_indicator) {
|
||||
p->level--;
|
||||
return NULL;
|
||||
}
|
||||
D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with' '(' ','.with_item+ ','? ')' ':' block"));
|
||||
D(fprintf(stderr, "%*c> with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with' '(' ','.with_item+ ','? ')' ':' TYPE_COMMENT? block"));
|
||||
Token * _keyword;
|
||||
Token * _literal;
|
||||
Token * _literal_1;
|
||||
|
@ -6542,6 +6542,7 @@ with_stmt_rule(Parser *p)
|
|||
UNUSED(_opt_var); // Silence compiler warnings
|
||||
asdl_withitem_seq* a;
|
||||
asdl_stmt_seq* b;
|
||||
void *tc;
|
||||
if (
|
||||
(_keyword = _PyPegen_expect_token(p, 629)) // token='with'
|
||||
&&
|
||||
|
@ -6555,10 +6556,12 @@ with_stmt_rule(Parser *p)
|
|||
&&
|
||||
(_literal_2 = _PyPegen_expect_token(p, 11)) // token=':'
|
||||
&&
|
||||
(tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT?
|
||||
&&
|
||||
(b = block_rule(p)) // block
|
||||
)
|
||||
{
|
||||
D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'with' '(' ','.with_item+ ','? ')' ':' block"));
|
||||
D(fprintf(stderr, "%*c+ with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'with' '(' ','.with_item+ ','? ')' ':' TYPE_COMMENT? block"));
|
||||
Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
|
||||
if (_token == NULL) {
|
||||
p->level--;
|
||||
|
@ -6568,7 +6571,7 @@ with_stmt_rule(Parser *p)
|
|||
UNUSED(_end_lineno); // Only used by EXTRA macro
|
||||
int _end_col_offset = _token->end_col_offset;
|
||||
UNUSED(_end_col_offset); // Only used by EXTRA macro
|
||||
_res = CHECK_VERSION ( stmt_ty , 9 , "Parenthesized context managers are" , _PyAST_With ( a , b , NULL , EXTRA ) );
|
||||
_res = CHECK_VERSION ( stmt_ty , 9 , "Parenthesized context managers are" , _PyAST_With ( a , b , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ) );
|
||||
if (_res == NULL && PyErr_Occurred()) {
|
||||
p->error_indicator = 1;
|
||||
p->level--;
|
||||
|
@ -6578,7 +6581,7 @@ with_stmt_rule(Parser *p)
|
|||
}
|
||||
p->mark = _mark;
|
||||
D(fprintf(stderr, "%*c%s with_stmt[%d-%d]: %s failed!\n", p->level, ' ',
|
||||
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'with' '(' ','.with_item+ ','? ')' ':' block"));
|
||||
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'with' '(' ','.with_item+ ','? ')' ':' TYPE_COMMENT? block"));
|
||||
}
|
||||
{ // 'with' ','.with_item+ ':' TYPE_COMMENT? block
|
||||
if (p->error_indicator) {
|
||||
|
|
Loading…
Reference in New Issue