Skip to content

Commit 53dec88

Browse files
authored
Merge pull request #4356 from andersk/with-tuple-named
Fix parsing of tuple with named expression as context manager
2 parents c0f390e + 1fdfa5f commit 53dec88

2 files changed

Lines changed: 140 additions & 115 deletions

File tree

‎parser/python.lalrpop‎

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,11 @@ TestOrStarExpr: ast::Expr = {
164164
StarExpr,
165165
};
166166

167+
NamedOrStarExpr: ast::Expr = {
168+
NamedExpression,
169+
StarExpr,
170+
};
171+
167172
TestOrStarNamedExpr: ast::Expr = {
168173
NamedExpressionTest,
169174
StarExpr,
@@ -518,7 +523,7 @@ WithItems: Vec<ast::Withitem> = {
518523

519524
#[inline]
520525
WithItemsNoAs: Vec<ast::Withitem> = {
521-
<OneOrMore<NamedExpressionTest>> => {
526+
<OneOrMore<Test<"all">>> => {
522527
<>.into_iter().map(|context_expr| ast::Withitem { context_expr, optional_vars: None }).collect()
523528
},
524529
}
@@ -746,26 +751,27 @@ Test<Goal>: ast::Expr = {
746751
};
747752

748753
NamedExpressionTest: ast::Expr = {
749-
<location:@L> <left: (Identifier ":=")?> <right:Test<"all">> <end_location:@R> => {
750-
if let Some(l) = left {
751-
ast::Expr {
752-
location,
753-
end_location: Some(end_location),
754-
custom: (),
755-
node: ast::ExprKind::NamedExpr {
756-
target: Box::new(ast::Expr::new(
757-
location,
758-
end_location,
759-
ast::ExprKind::Name { id: l.0, ctx: ast::ExprContext::Store },
760-
)),
761-
value: Box::new(right),
762-
}
754+
NamedExpression,
755+
Test<"all">,
756+
}
757+
758+
NamedExpression: ast::Expr = {
759+
<location:@L> <id:Identifier> ":=" <value:Test<"all">> <end_location:@R> => {
760+
ast::Expr {
761+
location,
762+
end_location: Some(end_location),
763+
custom: (),
764+
node: ast::ExprKind::NamedExpr {
765+
target: Box::new(ast::Expr::new(
766+
location,
767+
end_location,
768+
ast::ExprKind::Name { id, ctx: ast::ExprContext::Store },
769+
)),
770+
value: Box::new(value),
763771
}
764-
} else {
765-
right
766772
}
767-
}
768-
}
773+
},
774+
};
769775

770776
LambdaDef: ast::Expr = {
771777
<location:@L> "lambda" <p:ParameterList<UntypedParameter>?> ":" <body:Test<"all">> <end_location:@R> => {
@@ -1066,7 +1072,7 @@ Atom<Goal>: ast::Expr = {
10661072
node: ast::ExprKind::ListComp { elt: Box::new(elt), generators }
10671073
}
10681074
},
1069-
<location:@L> "(" <elts:OneOrMore<NamedExpressionTest>> <trailing_comma:","?> ")" <end_location:@R> if Goal != "no-withitems" => {
1075+
<location:@L> "(" <elts:OneOrMore<Test<"all">>> <trailing_comma:","?> ")" <end_location:@R> if Goal != "no-withitems" => {
10701076
if elts.len() == 1 && trailing_comma.is_none() {
10711077
elts.into_iter().next().unwrap()
10721078
} else {
@@ -1077,19 +1083,23 @@ Atom<Goal>: ast::Expr = {
10771083
)
10781084
}
10791085
},
1080-
<location:@L> "(" <left:(<OneOrMore<NamedExpressionTest>> ",")?> <mid:StarExpr> <right:("," <TestOrStarNamedExpr>)*> <trailing_comma:","?> ")" <end_location:@R> =>? {
1086+
<location:@L> "(" <left:(<OneOrMore<Test<"all">>> ",")?> <mid:NamedOrStarExpr> <right:("," <TestOrStarNamedExpr>)*> <trailing_comma:","?> ")" <end_location:@R> =>? {
10811087
if left.is_none() && right.is_empty() && trailing_comma.is_none() {
1082-
Err(LexicalError{
1083-
error: LexicalErrorType::OtherError("cannot use starred expression here".to_string()),
1084-
location: mid.location,
1085-
})?
1088+
if matches!(mid.node, ast::ExprKind::Starred { .. }) {
1089+
Err(LexicalError{
1090+
error: LexicalErrorType::OtherError("cannot use starred expression here".to_string()),
1091+
location: mid.location,
1092+
})?
1093+
}
1094+
Ok(mid)
1095+
} else {
1096+
let elts = left.into_iter().flatten().chain([mid]).chain(right).collect();
1097+
Ok(ast::Expr::new(
1098+
location,
1099+
end_location,
1100+
ast::ExprKind::Tuple { elts, ctx: ast::ExprContext::Load },
1101+
))
10861102
}
1087-
let elts = left.into_iter().flatten().chain([mid]).chain(right).collect();
1088-
Ok(ast::Expr::new(
1089-
location,
1090-
end_location,
1091-
ast::ExprKind::Tuple { elts, ctx: ast::ExprContext::Load },
1092-
))
10931103
},
10941104
<location:@L> "(" ")" <end_location:@R> => ast::Expr::new(
10951105
location,

‎parser/src/snapshots/rustpython_parser__with__tests__with_statement.snap‎

Lines changed: 99 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,106 +1792,121 @@ expression: "parse_program(source, \"<test>\").unwrap()"
17921792
context_expr: Located {
17931793
location: Location {
17941794
row: 21,
1795-
column: 6,
1795+
column: 5,
17961796
},
17971797
end_location: Some(
17981798
Location {
17991799
row: 21,
1800-
column: 12,
1800+
column: 21,
18011801
},
18021802
),
18031803
custom: (),
1804-
node: NamedExpr {
1805-
target: Located {
1806-
location: Location {
1807-
row: 21,
1808-
column: 6,
1809-
},
1810-
end_location: Some(
1811-
Location {
1812-
row: 21,
1813-
column: 12,
1814-
},
1815-
),
1816-
custom: (),
1817-
node: Name {
1818-
id: "a",
1819-
ctx: Store,
1820-
},
1821-
},
1822-
value: Located {
1823-
location: Location {
1824-
row: 21,
1825-
column: 11,
1826-
},
1827-
end_location: Some(
1828-
Location {
1804+
node: Tuple {
1805+
elts: [
1806+
Located {
1807+
location: Location {
18291808
row: 21,
1830-
column: 12,
1809+
column: 6,
18311810
},
1832-
),
1833-
custom: (),
1834-
node: Constant {
1835-
value: Int(
1836-
0,
1811+
end_location: Some(
1812+
Location {
1813+
row: 21,
1814+
column: 12,
1815+
},
18371816
),
1838-
kind: None,
1839-
},
1840-
},
1841-
},
1842-
},
1843-
optional_vars: None,
1844-
},
1845-
Withitem {
1846-
context_expr: Located {
1847-
location: Location {
1848-
row: 21,
1849-
column: 14,
1850-
},
1851-
end_location: Some(
1852-
Location {
1853-
row: 21,
1854-
column: 20,
1855-
},
1856-
),
1857-
custom: (),
1858-
node: NamedExpr {
1859-
target: Located {
1860-
location: Location {
1861-
row: 21,
1862-
column: 14,
1863-
},
1864-
end_location: Some(
1865-
Location {
1866-
row: 21,
1867-
column: 20,
1817+
custom: (),
1818+
node: NamedExpr {
1819+
target: Located {
1820+
location: Location {
1821+
row: 21,
1822+
column: 6,
1823+
},
1824+
end_location: Some(
1825+
Location {
1826+
row: 21,
1827+
column: 12,
1828+
},
1829+
),
1830+
custom: (),
1831+
node: Name {
1832+
id: "a",
1833+
ctx: Store,
1834+
},
1835+
},
1836+
value: Located {
1837+
location: Location {
1838+
row: 21,
1839+
column: 11,
1840+
},
1841+
end_location: Some(
1842+
Location {
1843+
row: 21,
1844+
column: 12,
1845+
},
1846+
),
1847+
custom: (),
1848+
node: Constant {
1849+
value: Int(
1850+
0,
1851+
),
1852+
kind: None,
1853+
},
1854+
},
18681855
},
1869-
),
1870-
custom: (),
1871-
node: Name {
1872-
id: "b",
1873-
ctx: Store,
1874-
},
1875-
},
1876-
value: Located {
1877-
location: Location {
1878-
row: 21,
1879-
column: 19,
18801856
},
1881-
end_location: Some(
1882-
Location {
1857+
Located {
1858+
location: Location {
18831859
row: 21,
1884-
column: 20,
1860+
column: 14,
18851861
},
1886-
),
1887-
custom: (),
1888-
node: Constant {
1889-
value: Int(
1890-
1,
1862+
end_location: Some(
1863+
Location {
1864+
row: 21,
1865+
column: 20,
1866+
},
18911867
),
1892-
kind: None,
1868+
custom: (),
1869+
node: NamedExpr {
1870+
target: Located {
1871+
location: Location {
1872+
row: 21,
1873+
column: 14,
1874+
},
1875+
end_location: Some(
1876+
Location {
1877+
row: 21,
1878+
column: 20,
1879+
},
1880+
),
1881+
custom: (),
1882+
node: Name {
1883+
id: "b",
1884+
ctx: Store,
1885+
},
1886+
},
1887+
value: Located {
1888+
location: Location {
1889+
row: 21,
1890+
column: 19,
1891+
},
1892+
end_location: Some(
1893+
Location {
1894+
row: 21,
1895+
column: 20,
1896+
},
1897+
),
1898+
custom: (),
1899+
node: Constant {
1900+
value: Int(
1901+
1,
1902+
),
1903+
kind: None,
1904+
},
1905+
},
1906+
},
18931907
},
1894-
},
1908+
],
1909+
ctx: Load,
18951910
},
18961911
},
18971912
optional_vars: None,

0 commit comments

Comments
 (0)