mirror of
https://github.com/RustPython/Parser.git
synced 2025-08-04 10:49:55 +00:00
Fix dict spreading in dict literal
This commit is contained in:
parent
ac4d3c076c
commit
581f6e176c
4 changed files with 124 additions and 37 deletions
|
@ -195,7 +195,7 @@ pub enum ExprKind<U = ()> {
|
||||||
orelse: Box<Expr<U>>,
|
orelse: Box<Expr<U>>,
|
||||||
},
|
},
|
||||||
Dict {
|
Dict {
|
||||||
keys: Vec<Expr<U>>,
|
keys: Vec<Option<Expr<U>>>,
|
||||||
values: Vec<Expr<U>>,
|
values: Vec<Expr<U>>,
|
||||||
},
|
},
|
||||||
Set {
|
Set {
|
||||||
|
|
|
@ -1138,42 +1138,42 @@ Atom<Goal>: ast::Expr = {
|
||||||
<location:@L> "{" <e:DictLiteralValues?> "}" <end_location:@R> => {
|
<location:@L> "{" <e:DictLiteralValues?> "}" <end_location:@R> => {
|
||||||
let pairs = e.unwrap_or_default();
|
let pairs = e.unwrap_or_default();
|
||||||
|
|
||||||
let (keys, values) = match pairs.iter().position(|(k,_)| k.is_none()) {
|
// let (keys, values) = match pairs.iter().position(|(k,_)| k.is_none()) {
|
||||||
Some(unpack_idx) => {
|
// Some(unpack_idx) => {
|
||||||
let mut pairs = pairs;
|
// let mut pairs = pairs;
|
||||||
let (keys, mut values): (_, Vec<_>) = pairs.drain(..unpack_idx).map(|(k, v)| (*k.unwrap(), v)).unzip();
|
// let (keys, mut values): (_, Vec<_>) = pairs.drain(..unpack_idx).map(|(k, v)| (*k.unwrap(), v)).unzip();
|
||||||
|
//
|
||||||
fn build_map(items: &mut Vec<(ast::Expr, ast::Expr)>) -> ast::Expr {
|
// fn build_map(items: &mut Vec<(ast::Expr, ast::Expr)>) -> ast::Expr {
|
||||||
let location = items[0].0.location;
|
// let location = items[0].0.location;
|
||||||
let end_location = items[0].0.end_location;
|
// let end_location = items[0].0.end_location;
|
||||||
let (keys, values) = items.drain(..).unzip();
|
// let (keys, values) = items.drain(..).unzip();
|
||||||
ast::Expr {
|
// ast::Expr {
|
||||||
location,
|
// location,
|
||||||
end_location,
|
// end_location,
|
||||||
custom: (),
|
// custom: (),
|
||||||
node: ast::ExprKind::Dict { keys, values }
|
// node: ast::ExprKind::Dict { keys, values }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
let mut items = Vec::new();
|
// let mut items = Vec::new();
|
||||||
for (key, value) in pairs.into_iter() {
|
// for (key, value) in pairs.into_iter() {
|
||||||
if let Some(key) = key {
|
// if let Some(key) = key {
|
||||||
items.push((*key, value));
|
// items.push((*key, value));
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
if !items.is_empty() {
|
// if !items.is_empty() {
|
||||||
values.push(build_map(&mut items));
|
// values.push(build_map(&mut items));
|
||||||
}
|
// }
|
||||||
values.push(value);
|
// values.push(value);
|
||||||
}
|
// }
|
||||||
if !items.is_empty() {
|
// if !items.is_empty() {
|
||||||
values.push(build_map(&mut items));
|
// values.push(build_map(&mut items));
|
||||||
}
|
// }
|
||||||
(keys, values)
|
// (keys, values)
|
||||||
},
|
// },
|
||||||
None => pairs.into_iter().map(|(k, v)| (*k.unwrap(), v)).unzip()
|
// None => pairs.into_iter().map(|(k, v)| (k, v)).unzip()
|
||||||
};
|
// };
|
||||||
|
let (keys, values) = pairs.into_iter().map(|(k, v)| (k.map(|x| *x), v)).unzip();
|
||||||
ast::Expr {
|
ast::Expr {
|
||||||
location,
|
location,
|
||||||
end_location: Some(end_location),
|
end_location: Some(end_location),
|
||||||
|
|
|
@ -309,4 +309,10 @@ with (0 as a, 1 as b,): pass
|
||||||
assert!(parse_program(source, "<test>").is_err());
|
assert!(parse_program(source, "<test>").is_err());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_dict_containing_spread() {
|
||||||
|
let parse_ast = parse_expression(r#"{"k": "v", **d}"#, "<test>").unwrap();
|
||||||
|
insta::assert_debug_snapshot!(parse_ast);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
---
|
||||||
|
source: compiler/parser/src/parser.rs
|
||||||
|
expression: parse_ast
|
||||||
|
---
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 1,
|
||||||
|
column: 0,
|
||||||
|
},
|
||||||
|
end_location: Some(
|
||||||
|
Location {
|
||||||
|
row: 1,
|
||||||
|
column: 15,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
custom: (),
|
||||||
|
node: Dict {
|
||||||
|
keys: [
|
||||||
|
Some(
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 1,
|
||||||
|
column: 1,
|
||||||
|
},
|
||||||
|
end_location: Some(
|
||||||
|
Location {
|
||||||
|
row: 1,
|
||||||
|
column: 4,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
custom: (),
|
||||||
|
node: Constant {
|
||||||
|
value: Str(
|
||||||
|
"k",
|
||||||
|
),
|
||||||
|
kind: None,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
],
|
||||||
|
values: [
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 1,
|
||||||
|
column: 6,
|
||||||
|
},
|
||||||
|
end_location: Some(
|
||||||
|
Location {
|
||||||
|
row: 1,
|
||||||
|
column: 9,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
custom: (),
|
||||||
|
node: Constant {
|
||||||
|
value: Str(
|
||||||
|
"v",
|
||||||
|
),
|
||||||
|
kind: None,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 1,
|
||||||
|
column: 13,
|
||||||
|
},
|
||||||
|
end_location: Some(
|
||||||
|
Location {
|
||||||
|
row: 1,
|
||||||
|
column: 14,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "d",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue