Merge pull request #932 from youknowone/dict-unpacking

Add dict unpacking support for literal
This commit is contained in:
Windel Bouwman authored and GitHub committed 2019-05-07 21:25:39 +02:00
commit aed8e03473
6 files changed
+40 -8

No files matched your search

+1 -1
View File
@@ -195,7 +195,7 @@ pub enum Expression {
elements: Vec<Expression>,
},
Dict {
elements: Vec<(Expression, Expression)>,
elements: Vec<(Option<Expression>, Expression)>,
},
Set {
elements: Vec<Expression>,
+7 -2
View File
@@ -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
};
+7
View File
@@ -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
View File
@@ -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 } => {
+5 -1
View File
@@ -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());
}
+5 -1
View File
@@ -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)?;
}
}