mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 03:04:38 +08:00
Merge pull request #932 from youknowone/dict-unpacking
Add dict unpacking support for literal
This commit is contained in:
6 files changed
+40
-8
No files matched your search
+1
-1
@@ -195,7 +195,7 @@ pub enum Expression {
|
||||
elements: Vec<Expression>,
|
||||
},
|
||||
Dict {
|
||||
elements: Vec<(Expression, Expression)>,
|
||||
elements: Vec<(Option<Expression>, Expression)>,
|
||||
},
|
||||
Set {
|
||||
elements: Vec<Expression>,
|
||||
|
||||
@@ -833,8 +833,8 @@ TestListComp2: ast::Expression = {
|
||||
},
|
||||
};
|
||||
|
||||
TestDict: Vec<(ast::Expression, ast::Expression)> = {
|
||||
<elements:OneOrMore<DictEntry>> <_trailing_comma:","?> => elements,
|
||||
TestDict: Vec<(Option<ast::Expression>, ast::Expression)> = {
|
||||
<elements:OneOrMore<DictElement>> <_trailing_comma:","?> => elements,
|
||||
};
|
||||
|
||||
TestDictComp: ast::Expression = {
|
||||
@@ -850,6 +850,11 @@ DictEntry: (ast::Expression, ast::Expression) = {
|
||||
<e1: Test> ":" <e2: Test> => (e1, e2),
|
||||
};
|
||||
|
||||
DictElement: (Option<ast::Expression>, ast::Expression) = {
|
||||
<e:DictEntry> => (Some(e.0), e.1),
|
||||
"**" <e:Expression> => (None, e),
|
||||
};
|
||||
|
||||
TestSet: Vec<ast::Expression> = {
|
||||
<e1:OneOrMore<Test>> ","? => e1
|
||||
};
|
||||
|
||||
@@ -191,3 +191,10 @@ assert x['c'] is None
|
||||
|
||||
assert {1: None, "b": None} == dict.fromkeys([1, "b"])
|
||||
assert {1: 0, "b": 0} == dict.fromkeys([1, "b"], 0)
|
||||
|
||||
x = {'a': 1, 'b': 1, 'c': 1}
|
||||
y = {'b': 2, 'c': 2, 'd': 2}
|
||||
z = {'c': 3, 'd': 3, 'e': 3}
|
||||
|
||||
w = {1: 1, **x, 2: 2, **y, 3: 3, **z, 4: 4}
|
||||
assert w == {1: 1, 'a': 1, 'b': 2, 'c': 3, 2: 2, 'd': 3, 3: 3, 'e': 3, 4: 4}
|
||||
+15
-3
@@ -1256,13 +1256,25 @@ impl Compiler {
|
||||
}
|
||||
ast::Expression::Dict { elements } => {
|
||||
let size = elements.len();
|
||||
let has_double_star = elements.iter().any(|e| e.0.is_none());
|
||||
for (key, value) in elements {
|
||||
self.compile_expression(key)?;
|
||||
self.compile_expression(value)?;
|
||||
if let Some(key) = key {
|
||||
self.compile_expression(key)?;
|
||||
self.compile_expression(value)?;
|
||||
if has_double_star {
|
||||
self.emit(Instruction::BuildMap {
|
||||
size: 1,
|
||||
unpack: false,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// dict unpacking
|
||||
self.compile_expression(value)?;
|
||||
}
|
||||
}
|
||||
self.emit(Instruction::BuildMap {
|
||||
size,
|
||||
unpack: false,
|
||||
unpack: has_double_star,
|
||||
});
|
||||
}
|
||||
ast::Expression::Slice { elements } => {
|
||||
|
||||
@@ -358,7 +358,11 @@ fn expression_to_ast(vm: &VirtualMachine, expression: &ast::Expression) -> PyRes
|
||||
let mut keys = Vec::new();
|
||||
let mut values = Vec::new();
|
||||
for (k, v) in elements {
|
||||
keys.push(expression_to_ast(vm, k)?.into_object());
|
||||
if let Some(k) = k {
|
||||
keys.push(expression_to_ast(vm, k)?.into_object());
|
||||
} else {
|
||||
keys.push(vm.ctx.none());
|
||||
}
|
||||
values.push(expression_to_ast(vm, v)?.into_object());
|
||||
}
|
||||
|
||||
|
||||
@@ -404,7 +404,11 @@ impl SymbolTableBuilder {
|
||||
}
|
||||
ast::Expression::Dict { elements } => {
|
||||
for (key, value) in elements {
|
||||
self.scan_expression(key)?;
|
||||
if let Some(key) = key {
|
||||
self.scan_expression(key)?;
|
||||
} else {
|
||||
// dict unpacking marker
|
||||
}
|
||||
self.scan_expression(value)?;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user