ruff/crates/ruff_python_parser/tests/snapshots/valid_syntax@expressions__dictionary.py.snap
Dhruv Manilawala 13ffb5bc19
Replace LALRPOP parser with hand-written parser (#10036)
(Supersedes #9152, authored by @LaBatata101)

## Summary

This PR replaces the current parser generated from LALRPOP to a
hand-written recursive descent parser.

It also updates the grammar for [PEP
646](https://peps.python.org/pep-0646/) so that the parser outputs the
correct AST. For example, in `data[*x]`, the index expression is now a
tuple with a single starred expression instead of just a starred
expression.

Beyond the performance improvements, the parser is also error resilient
and can provide better error messages. The behavior as seen by any
downstream tools isn't changed. That is, the linter and formatter can
still assume that the parser will _stop_ at the first syntax error. This
will be updated in the following months.

For more details about the change here, refer to the PR corresponding to
the individual commits and the release blog post.

## Test Plan

Write _lots_ and _lots_ of tests for both valid and invalid syntax and
verify the output.

## Acknowledgements

- @MichaReiser for reviewing 100+ parser PRs and continuously providing
guidance throughout the project
- @LaBatata101 for initiating the transition to a hand-written parser in
#9152
- @addisoncrump for implementing the fuzzer which helped
[catch](https://github.com/astral-sh/ruff/pull/10903)
[a](https://github.com/astral-sh/ruff/pull/10910)
[lot](https://github.com/astral-sh/ruff/pull/10966)
[of](https://github.com/astral-sh/ruff/pull/10896)
[bugs](https://github.com/astral-sh/ruff/pull/10877)

---------

Co-authored-by: Victor Hugo Gomes <labatata101@linuxmail.org>
Co-authored-by: Micha Reiser <micha@reiser.io>
2024-04-18 17:57:39 +05:30

1208 lines
56 KiB
Text

---
source: crates/ruff_python_parser/tests/fixtures.rs
input_file: crates/ruff_python_parser/resources/valid/expressions/dictionary.py
---
## AST
```
Module(
ModModule {
range: 0..622,
body: [
Expr(
StmtExpr {
range: 9..11,
value: Dict(
ExprDict {
range: 9..11,
keys: [],
values: [],
},
),
},
),
Expr(
StmtExpr {
range: 12..18,
value: Dict(
ExprDict {
range: 12..18,
keys: [
Some(
NumberLiteral(
ExprNumberLiteral {
range: 13..14,
value: Int(
1,
),
},
),
),
],
values: [
NumberLiteral(
ExprNumberLiteral {
range: 16..17,
value: Int(
2,
),
},
),
],
},
),
},
),
Expr(
StmtExpr {
range: 19..43,
value: Dict(
ExprDict {
range: 19..43,
keys: [
Some(
NumberLiteral(
ExprNumberLiteral {
range: 20..21,
value: Int(
1,
),
},
),
),
Some(
Name(
ExprName {
range: 26..27,
id: "a",
ctx: Load,
},
),
),
Some(
Name(
ExprName {
range: 32..33,
id: "b",
ctx: Load,
},
),
),
],
values: [
NumberLiteral(
ExprNumberLiteral {
range: 23..24,
value: Int(
2,
),
},
),
NumberLiteral(
ExprNumberLiteral {
range: 29..30,
value: Int(
1,
),
},
),
StringLiteral(
ExprStringLiteral {
range: 35..42,
value: StringLiteralValue {
inner: Single(
StringLiteral {
range: 35..42,
value: "hello",
flags: StringLiteralFlags {
quote_style: Single,
prefix: Empty,
triple_quoted: false,
},
},
),
},
},
),
],
},
),
},
),
Expr(
StmtExpr {
range: 66..69,
value: Dict(
ExprDict {
range: 66..69,
keys: [],
values: [],
},
),
},
),
Expr(
StmtExpr {
range: 70..100,
value: Dict(
ExprDict {
range: 70..100,
keys: [
Some(
NumberLiteral(
ExprNumberLiteral {
range: 76..77,
value: Int(
1,
),
},
),
),
Some(
NumberLiteral(
ExprNumberLiteral {
range: 90..91,
value: Int(
3,
),
},
),
),
],
values: [
NumberLiteral(
ExprNumberLiteral {
range: 83..84,
value: Int(
2,
),
},
),
NumberLiteral(
ExprNumberLiteral {
range: 97..98,
value: Int(
4,
),
},
),
],
},
),
},
),
Expr(
StmtExpr {
range: 111..132,
value: Dict(
ExprDict {
range: 111..132,
keys: [
Some(
Dict(
ExprDict {
range: 112..118,
keys: [
Some(
NumberLiteral(
ExprNumberLiteral {
range: 113..114,
value: Int(
1,
),
},
),
),
],
values: [
NumberLiteral(
ExprNumberLiteral {
range: 116..117,
value: Int(
2,
),
},
),
],
},
),
),
],
values: [
Dict(
ExprDict {
range: 120..131,
keys: [
Some(
NumberLiteral(
ExprNumberLiteral {
range: 121..122,
value: Int(
3,
),
},
),
),
],
values: [
Dict(
ExprDict {
range: 124..130,
keys: [
Some(
NumberLiteral(
ExprNumberLiteral {
range: 125..126,
value: Int(
4,
),
},
),
),
],
values: [
NumberLiteral(
ExprNumberLiteral {
range: 128..129,
value: Int(
5,
),
},
),
],
},
),
],
},
),
],
},
),
},
),
Expr(
StmtExpr {
range: 155..171,
value: Dict(
ExprDict {
range: 155..171,
keys: [
Some(
Lambda(
ExprLambda {
range: 156..167,
parameters: Some(
Parameters {
range: 163..164,
posonlyargs: [],
args: [
ParameterWithDefault {
range: 163..164,
parameter: Parameter {
range: 163..164,
name: Identifier {
id: "x",
range: 163..164,
},
annotation: None,
},
default: None,
},
],
vararg: None,
kwonlyargs: [],
kwarg: None,
},
),
body: Name(
ExprName {
range: 166..167,
id: "x",
ctx: Load,
},
),
},
),
),
],
values: [
NumberLiteral(
ExprNumberLiteral {
range: 169..170,
value: Int(
1,
),
},
),
],
},
),
},
),
Expr(
StmtExpr {
range: 172..202,
value: Dict(
ExprDict {
range: 172..202,
keys: [
Some(
StringLiteral(
ExprStringLiteral {
range: 173..176,
value: StringLiteralValue {
inner: Single(
StringLiteral {
range: 173..176,
value: "A",
flags: StringLiteralFlags {
quote_style: Single,
prefix: Empty,
triple_quoted: false,
},
},
),
},
},
),
),
Some(
StringLiteral(
ExprStringLiteral {
range: 194..197,
value: StringLiteralValue {
inner: Single(
StringLiteral {
range: 194..197,
value: "B",
flags: StringLiteralFlags {
quote_style: Single,
prefix: Empty,
triple_quoted: false,
},
},
),
},
},
),
),
],
values: [
Lambda(
ExprLambda {
range: 178..192,
parameters: Some(
Parameters {
range: 185..186,
posonlyargs: [],
args: [
ParameterWithDefault {
range: 185..186,
parameter: Parameter {
range: 185..186,
name: Identifier {
id: "p",
range: 185..186,
},
annotation: None,
},
default: None,
},
],
vararg: None,
kwonlyargs: [],
kwarg: None,
},
),
body: NoneLiteral(
ExprNoneLiteral {
range: 188..192,
},
),
},
),
Name(
ExprName {
range: 199..200,
id: "C",
ctx: Load,
},
),
],
},
),
},
),
Expr(
StmtExpr {
range: 224..237,
value: Dict(
ExprDict {
range: 224..237,
keys: [
Some(
Named(
ExprNamed {
range: 226..232,
target: Name(
ExprName {
range: 226..227,
id: "x",
ctx: Store,
},
),
value: NumberLiteral(
ExprNumberLiteral {
range: 231..232,
value: Int(
1,
),
},
),
},
),
),
],
values: [
Name(
ExprName {
range: 235..236,
id: "y",
ctx: Load,
},
),
],
},
),
},
),
Expr(
StmtExpr {
range: 238..258,
value: Dict(
ExprDict {
range: 238..258,
keys: [
Some(
Named(
ExprNamed {
range: 240..246,
target: Name(
ExprName {
range: 240..241,
id: "x",
ctx: Store,
},
),
value: NumberLiteral(
ExprNumberLiteral {
range: 245..246,
value: Int(
1,
),
},
),
},
),
),
],
values: [
Named(
ExprNamed {
range: 250..256,
target: Name(
ExprName {
range: 250..251,
id: "y",
ctx: Store,
},
),
value: NumberLiteral(
ExprNumberLiteral {
range: 255..256,
value: Int(
2,
),
},
),
},
),
],
},
),
},
),
Expr(
StmtExpr {
range: 284..289,
value: Dict(
ExprDict {
range: 284..289,
keys: [
None,
],
values: [
Name(
ExprName {
range: 287..288,
id: "d",
ctx: Load,
},
),
],
},
),
},
),
Expr(
StmtExpr {
range: 290..301,
value: Dict(
ExprDict {
range: 290..301,
keys: [
Some(
Name(
ExprName {
range: 291..292,
id: "a",
ctx: Load,
},
),
),
None,
],
values: [
Name(
ExprName {
range: 294..295,
id: "b",
ctx: Load,
},
),
Name(
ExprName {
range: 299..300,
id: "d",
ctx: Load,
},
),
],
},
),
},
),
Expr(
StmtExpr {
range: 302..312,
value: Dict(
ExprDict {
range: 302..312,
keys: [
None,
None,
],
values: [
Name(
ExprName {
range: 305..306,
id: "a",
ctx: Load,
},
),
Name(
ExprName {
range: 310..311,
id: "b",
ctx: Load,
},
),
],
},
),
},
),
Expr(
StmtExpr {
range: 313..338,
value: Dict(
ExprDict {
range: 313..338,
keys: [
Some(
StringLiteral(
ExprStringLiteral {
range: 314..317,
value: StringLiteralValue {
inner: Single(
StringLiteral {
range: 314..317,
value: "a",
flags: StringLiteralFlags {
quote_style: Double,
prefix: Empty,
triple_quoted: false,
},
},
),
},
},
),
),
None,
Some(
StringLiteral(
ExprStringLiteral {
range: 329..332,
value: StringLiteralValue {
inner: Single(
StringLiteral {
range: 329..332,
value: "d",
flags: StringLiteralFlags {
quote_style: Double,
prefix: Empty,
triple_quoted: false,
},
},
),
},
},
),
),
],
values: [
StringLiteral(
ExprStringLiteral {
range: 319..322,
value: StringLiteralValue {
inner: Single(
StringLiteral {
range: 319..322,
value: "b",
flags: StringLiteralFlags {
quote_style: Double,
prefix: Empty,
triple_quoted: false,
},
},
),
},
},
),
Name(
ExprName {
range: 326..327,
id: "c",
ctx: Load,
},
),
StringLiteral(
ExprStringLiteral {
range: 334..337,
value: StringLiteralValue {
inner: Single(
StringLiteral {
range: 334..337,
value: "e",
flags: StringLiteralFlags {
quote_style: Double,
prefix: Empty,
triple_quoted: false,
},
},
),
},
},
),
],
},
),
},
),
Expr(
StmtExpr {
range: 339..367,
value: Dict(
ExprDict {
range: 339..367,
keys: [
Some(
NumberLiteral(
ExprNumberLiteral {
range: 340..341,
value: Int(
1,
),
},
),
),
None,
],
values: [
NumberLiteral(
ExprNumberLiteral {
range: 343..344,
value: Int(
2,
),
},
),
Dict(
ExprDict {
range: 348..366,
keys: [
Some(
StringLiteral(
ExprStringLiteral {
range: 349..357,
value: StringLiteralValue {
inner: Single(
StringLiteral {
range: 349..357,
value: "nested",
flags: StringLiteralFlags {
quote_style: Single,
prefix: Empty,
triple_quoted: false,
},
},
),
},
},
),
),
],
values: [
StringLiteral(
ExprStringLiteral {
range: 359..365,
value: StringLiteralValue {
inner: Single(
StringLiteral {
range: 359..365,
value: "dict",
flags: StringLiteralFlags {
quote_style: Single,
prefix: Empty,
triple_quoted: false,
},
},
),
},
},
),
],
},
),
],
},
),
},
),
Expr(
StmtExpr {
range: 368..393,
value: Dict(
ExprDict {
range: 368..393,
keys: [
Some(
BinOp(
ExprBinOp {
range: 369..374,
left: Name(
ExprName {
range: 369..370,
id: "x",
ctx: Load,
},
),
op: Mult,
right: NumberLiteral(
ExprNumberLiteral {
range: 373..374,
value: Int(
1,
),
},
),
},
),
),
None,
],
values: [
BinOp(
ExprBinOp {
range: 376..382,
left: Name(
ExprName {
range: 376..377,
id: "y",
ctx: Load,
},
),
op: Pow,
right: NumberLiteral(
ExprNumberLiteral {
range: 381..382,
value: Int(
2,
),
},
),
},
),
Call(
ExprCall {
range: 386..392,
func: Name(
ExprName {
range: 386..390,
id: "call",
ctx: Load,
},
),
arguments: Arguments {
range: 390..392,
args: [],
keywords: [],
},
},
),
],
},
),
},
),
Expr(
StmtExpr {
range: 460..471,
value: Dict(
ExprDict {
range: 460..471,
keys: [
None,
],
values: [
UnaryOp(
ExprUnaryOp {
range: 464..469,
op: Not,
operand: Name(
ExprName {
range: 468..469,
id: "x",
ctx: Load,
},
),
},
),
],
},
),
},
),
Expr(
StmtExpr {
range: 494..515,
value: Dict(
ExprDict {
range: 494..515,
keys: [
Some(
NumberLiteral(
ExprNumberLiteral {
range: 495..496,
value: Int(
1,
),
},
),
),
],
values: [
If(
ExprIf {
range: 498..514,
test: BooleanLiteral(
ExprBooleanLiteral {
range: 503..507,
value: true,
},
),
body: Name(
ExprName {
range: 498..499,
id: "x",
ctx: Load,
},
),
orelse: Name(
ExprName {
range: 513..514,
id: "y",
ctx: Load,
},
),
},
),
],
},
),
},
),
Expr(
StmtExpr {
range: 516..575,
value: DictComp(
ExprDictComp {
range: 516..575,
key: If(
ExprIf {
range: 517..533,
test: BooleanLiteral(
ExprBooleanLiteral {
range: 522..526,
value: true,
},
),
body: Name(
ExprName {
range: 517..518,
id: "x",
ctx: Load,
},
),
orelse: Name(
ExprName {
range: 532..533,
id: "y",
ctx: Load,
},
),
},
),
value: Name(
ExprName {
range: 535..536,
id: "y",
ctx: Load,
},
),
generators: [
Comprehension {
range: 537..555,
target: Name(
ExprName {
range: 541..542,
id: "x",
ctx: Store,
},
),
iter: Call(
ExprCall {
range: 546..555,
func: Name(
ExprName {
range: 546..551,
id: "range",
ctx: Load,
},
),
arguments: Arguments {
range: 551..555,
args: [
NumberLiteral(
ExprNumberLiteral {
range: 552..554,
value: Int(
10,
),
},
),
],
keywords: [],
},
},
),
ifs: [],
is_async: false,
},
Comprehension {
range: 556..574,
target: Name(
ExprName {
range: 560..561,
id: "y",
ctx: Store,
},
),
iter: Call(
ExprCall {
range: 565..574,
func: Name(
ExprName {
range: 565..570,
id: "range",
ctx: Load,
},
),
arguments: Arguments {
range: 570..574,
args: [
NumberLiteral(
ExprNumberLiteral {
range: 571..573,
value: Int(
10,
),
},
),
],
keywords: [],
},
},
),
ifs: [],
is_async: false,
},
],
},
),
},
),
Expr(
StmtExpr {
range: 576..600,
value: Dict(
ExprDict {
range: 576..600,
keys: [
Some(
Set(
ExprSet {
range: 577..583,
elts: [
NumberLiteral(
ExprNumberLiteral {
range: 578..579,
value: Int(
1,
),
},
),
NumberLiteral(
ExprNumberLiteral {
range: 581..582,
value: Int(
2,
),
},
),
],
},
),
),
Some(
Name(
ExprName {
range: 588..589,
id: "x",
ctx: Load,
},
),
),
],
values: [
NumberLiteral(
ExprNumberLiteral {
range: 585..586,
value: Int(
3,
),
},
),
Dict(
ExprDict {
range: 591..598,
keys: [
Some(
NumberLiteral(
ExprNumberLiteral {
range: 592..593,
value: Int(
1,
),
},
),
),
],
values: [
NumberLiteral(
ExprNumberLiteral {
range: 595..596,
value: Int(
2,
),
},
),
],
},
),
],
},
),
},
),
Expr(
StmtExpr {
range: 601..621,
value: Dict(
ExprDict {
range: 601..621,
keys: [
Some(
Name(
ExprName {
range: 603..604,
id: "x",
ctx: Load,
},
),
),
Some(
Name(
ExprName {
range: 613..614,
id: "z",
ctx: Load,
},
),
),
],
values: [
Name(
ExprName {
range: 608..609,
id: "y",
ctx: Load,
},
),
Name(
ExprName {
range: 618..619,
id: "a",
ctx: Load,
},
),
],
},
),
},
),
],
},
)
```