From cf27802e860da7e9ed3c66dccc7927308ea621d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lozier?= Date: Fri, 16 Apr 2021 08:55:29 -0400 Subject: [PATCH] Update AST for extended unpacking --- Src/IronPython/Modules/_ast.cs | 85 +++++++++++++++------------------- Tests/test_ast.py | 65 ++++++++++++-------------- 2 files changed, 67 insertions(+), 83 deletions(-) diff --git a/Src/IronPython/Modules/_ast.cs b/Src/IronPython/Modules/_ast.cs index 7c3fcdadf..2ddf95151 100755 --- a/Src/IronPython/Modules/_ast.cs +++ b/Src/IronPython/Modules/_ast.cs @@ -1022,17 +1022,14 @@ internal override AstExpression Revert() { [PythonType] public class Call : expr { public Call() { - _fields = PythonTuple.MakeTuple(new[] { nameof(func), nameof(args), nameof(keywords), nameof(starargs), nameof(kwargs) }); + _fields = PythonTuple.MakeTuple(new[] { nameof(func), nameof(args), nameof(keywords) }); } - public Call(expr func, PythonList args, PythonList keywords, expr starargs, expr kwargs, - [Optional]int? lineno, [Optional]int? col_offset) + public Call(expr func, PythonList args, PythonList keywords, [Optional] int? lineno, [Optional] int? col_offset) : this() { this.func = func; this.args = args; this.keywords = keywords; - this.starargs = starargs; - this.kwargs = kwargs; _lineno = lineno; _col_offset = col_offset; } @@ -1043,16 +1040,15 @@ internal Call(CallExpression call) keywords = new PythonList(); func = Convert(call.Target); foreach (Arg arg in call.Args) { - if (arg.Name == null) + if (arg.Name == "*") { + var loc = arg.Start; + args.Add(new Starred(Convert(arg.Expression), Load.Instance, loc.Line, loc.Column)); + } else { args.Add(Convert(arg.Expression)); - else // name == "*" - starargs = Convert(arg.Expression); + } } foreach (Arg arg in call.Kwargs) { - if (arg.Name == "**") - kwargs = Convert(arg.Expression); - else // name is proper - keywords.Add(new keyword(arg)); + keywords.Add(new keyword(arg.Name == "**" ? null : arg.Name, Convert(arg.Expression))); } } @@ -1060,14 +1056,17 @@ internal override AstExpression Revert() { AstExpression target = expr.Revert(func); List newArgs = new List(); List newKwargs = new List(); - foreach (expr ex in args) - newArgs.Add(new Arg(expr.Revert(ex))); - if (null != starargs) - newArgs.Add(new Arg("*", expr.Revert(starargs))); - foreach (keyword kw in keywords) - newKwargs.Add(new Arg(kw.arg, expr.Revert(kw.value))); - if (null != kwargs) - newKwargs.Add(new Arg("**", expr.Revert(kwargs))); + foreach (expr ex in args) { + if (ex is Starred starred) { + newArgs.Add(new Arg("*", starred.value?.Revert())); + } else { + newArgs.Add(new Arg(ex?.Revert())); + } + } + foreach (keyword kw in keywords) { + newKwargs.Add(new Arg(kw.arg is null ? "**" : kw.arg, kw.value?.Revert())); + } + return new CallExpression(target, newArgs, newKwargs); } @@ -1076,26 +1075,19 @@ internal override AstExpression Revert() { public PythonList args { get; set; } public PythonList keywords { get; set; } - - public expr starargs { get; set; } // TODO: remove in 3.5 - - public expr kwargs { get; set; } // TODO: remove in 3.5 } [PythonType] public class ClassDef : stmt { public ClassDef() { - _fields = PythonTuple.MakeTuple(new[] { nameof(name), nameof(bases), nameof(keywords), nameof(starargs), nameof(kwargs), nameof(body), nameof(decorator_list) }); + _fields = PythonTuple.MakeTuple(new[] { nameof(name), nameof(bases), nameof(keywords), nameof(body), nameof(decorator_list) }); } - public ClassDef(string name, PythonList bases, PythonList keywords, object starargs, object kwargs, PythonList body, PythonList decorator_list, - [Optional]int? lineno, [Optional]int? col_offset) + public ClassDef(string name, PythonList bases, PythonList keywords, PythonList body, PythonList decorator_list, [Optional] int? lineno, [Optional] int? col_offset) : this() { this.name = name; this.bases = bases; this.keywords = keywords; - this.starargs = starargs; - this.kwargs = kwargs; this.body = body; this.decorator_list = decorator_list; _lineno = lineno; @@ -1107,17 +1099,16 @@ internal ClassDef(ClassDefinition def) name = def.Name; bases = new PythonList(def.Bases.Count); foreach (Arg arg in def.Bases) { - if (arg.Name == null) + if (arg.Name == "*") { + var loc = arg.Start; + bases.Add(new Starred(Convert(arg.Expression), Load.Instance, loc.Line, loc.Column)); + } else { bases.Add(Convert(arg.Expression)); - else // name == "*" - starargs = Convert(arg.Expression); + } } keywords = new PythonList(def.Keywords.Count); foreach (Arg arg in def.Keywords) { - if (arg.Name == "**") - kwargs = Convert(arg.Expression); - else // name is proper - keywords.Add(new keyword(arg)); + keywords.Add(new keyword(arg.Name == "**" ? null : arg.Name, Convert(arg.Expression))); } body = ConvertStatements(def.Body); if (def.Decorators != null) { @@ -1132,14 +1123,16 @@ internal ClassDef(ClassDefinition def) internal override Statement Revert() { List newBases = new List(); List newKeywords = new List(); - foreach (expr ex in bases) - newBases.Add(new Arg(expr.Revert(ex))); - if (null != starargs) - newBases.Add(new Arg("*", expr.Revert(starargs))); - foreach (keyword kw in keywords) - newKeywords.Add(new Arg(kw.arg, expr.Revert(kw.value))); - if (null != kwargs) - newKeywords.Add(new Arg("**", expr.Revert(kwargs))); + foreach (expr ex in bases) { + if (ex is Starred starred) { + newBases.Add(new Arg("*", starred.value?.Revert())); + } else { + newBases.Add(new Arg(ex?.Revert())); + } + } + foreach (keyword kw in keywords) { + newKeywords.Add(new Arg(kw.arg is null ? "**" : kw.arg, kw.value?.Revert())); + } ClassDefinition cd = new ClassDefinition(name, newBases, newKeywords, RevertStmts(body)); if (decorator_list.Count != 0) @@ -1153,10 +1146,6 @@ internal override Statement Revert() { public PythonList keywords { get; set; } - public object starargs { get; set; } // TODO: remove in 3.5 - - public object kwargs { get; set; } // TODO: remove in 3.5 - public PythonList body { get; set; } public PythonList decorator_list { get; set; } diff --git a/Tests/test_ast.py b/Tests/test_ast.py index d80590e86..f9c98e08c 100644 --- a/Tests/test_ast.py +++ b/Tests/test_ast.py @@ -1031,13 +1031,13 @@ def test_operators(self): dictcomp1 = ast.DictComp(ast.Name('i', ast.Load()), ast.Call(ast.Name('chr', ast.Load()), [ast.BinOp(ast.Num(65), ast.Add(), ast.Name('i', ast.Load()))], - [], None, None), + []), [ast.comprehension(ast.Name('i', ast.Store()), ast.Tuple([ast.Num(1), ast.Num(n=2)], ast.Load()), [])]) dictcomp2 = ast.DictComp(ast.Name('i', ast.Load()), ast.Call(ast.Name('chr', ast.Load()), [ast.BinOp(ast.Num(65), ast.Add(), ast.Name('i', ast.Load()))], - [], None, None), + []), [ast.comprehension(ast.Name('i', ast.Store()), ast.Tuple([ast.Num(1), ast.Num(n=2)], ast.Load()), [])], lineno=0, col_offset=0) @@ -1063,10 +1063,10 @@ def test_operators(self): # chr(65) call0 = ast.Call() - call1 = ast.Call(ast.Name('chr', ast.Load()), [ast.Num(65)], [], None, None) - call2 = ast.Call(ast.Name('chr', ast.Load()), [ast.Num(65)], [], None, None, lineno=0, col_offset=0) - call20 = ast.Call(ast.Name('f', ast.Load()), [ast.Num(0)], [], None, None) - call21 = ast.Call(ast.Name('f', ast.Load()), [ast.Num(0)], [], None, None, lineno=0, col_offset=0) + call1 = ast.Call(ast.Name('chr', ast.Load()), [ast.Num(65)], []) + call2 = ast.Call(ast.Name('chr', ast.Load()), [ast.Num(65)], [], lineno=0, col_offset=0) + call20 = ast.Call(ast.Name('f', ast.Load()), [ast.Num(0)], []) + call21 = ast.Call(ast.Name('f', ast.Load()), [ast.Num(0)], [], lineno=0, col_offset=0) # 0 num0 = ast.Num() @@ -1114,8 +1114,8 @@ def test_stmt(self): # class foo(object): # pass classdef0 = ast.ClassDef() - classdef1 = ast.ClassDef('foo', [ast.Name('object', ast.Load())], [], None, None, [ast.Pass()], []) - classdef1 = ast.ClassDef('foo', [ast.Name('object', ast.Load())], [], None, None, [ast.Pass()], [], lineno=0, col_offset=0) + classdef1 = ast.ClassDef('foo', [ast.Name('object', ast.Load())], [], [ast.Pass()], []) + classdef1 = ast.ClassDef('foo', [ast.Name('object', ast.Load())], [], [ast.Pass()], [], lineno=0, col_offset=0) # return 0 return0 = ast.Return() @@ -1171,14 +1171,14 @@ def test_stmt(self): # with open("foo") as f: # pass with0 = ast.With() - with0 = ast.With([ast.withitem(ast.Call(ast.Name('open', ast.Load()), [ast.Str('foo')], [], None, None), + with0 = ast.With([ast.withitem(ast.Call(ast.Name('open', ast.Load()), [ast.Str('foo')], []), ast.Name('f', ast.Store()))], [ast.Pass()]) # raise Exception() raise0 = ast.Raise() - raise1 = ast.Raise(ast.Call(ast.Name('Exception', ast.Load()), [], [], None, None), None) - raise2 = ast.Raise(ast.Call(ast.Name('Exception', ast.Load()), [], [], None, None), None, lineno=0, col_offset=0) + raise1 = ast.Raise(ast.Call(ast.Name('Exception', ast.Load()), [], []), None) + raise2 = ast.Raise(ast.Call(ast.Name('Exception', ast.Load()), [], []), None, lineno=0, col_offset=0) def test_attributes(self): # assert True, "bad" @@ -1238,19 +1238,17 @@ def test_dump(self): node = ast.parse('spam(eggs, "and cheese")') self.assertEqual(ast.dump(node), "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), " - "args=[Name(id='eggs', ctx=Load()), Str(s='and cheese')], " - "keywords=[], starargs=None, kwargs=None))])" + "args=[Name(id='eggs', ctx=Load()), Str(s='and cheese')], keywords=[]))])" ) self.assertEqual(ast.dump(node, annotate_fields=False), "Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), " - "Str('and cheese')], [], None, None))])" + "Str('and cheese')], []))])" ) self.assertEqual(ast.dump(node, include_attributes=True), "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), " "lineno=1, col_offset=0), args=[Name(id='eggs', ctx=Load(), " "lineno=1, col_offset=5), Str(s='and cheese', lineno=1, " - "col_offset=11)], keywords=[], starargs=None, kwargs=None, " - "lineno=1, col_offset=0), lineno=1, col_offset=0)])" + "col_offset=11)], keywords=[], lineno=1, col_offset=0), lineno=1, col_offset=0)])" ) def test_copy_location(self): @@ -1265,17 +1263,15 @@ def test_copy_location(self): def test_fix_missing_locations(self): src = ast.parse('write("spam")') src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()), - [ast.Str('eggs')], [], None, None))) + [ast.Str('eggs')], []))) self.assertEqual(src, ast.fix_missing_locations(src)) self.assertEqual(ast.dump(src, include_attributes=True), "Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), " "lineno=1, col_offset=0), args=[Str(s='spam', lineno=1, " - "col_offset=6)], keywords=[], starargs=None, kwargs=None, " - "lineno=1, col_offset=0), lineno=1, col_offset=0), " + "col_offset=6)], keywords=[], lineno=1, col_offset=0), lineno=1, col_offset=0), " "Expr(value=Call(func=Name(id='spam', ctx=Load(), lineno=1, " "col_offset=0), args=[Str(s='eggs', lineno=1, col_offset=0)], " - "keywords=[], starargs=None, kwargs=None, lineno=1, " - "col_offset=0), lineno=1, col_offset=0)])" + "keywords=[], lineno=1, col_offset=0), lineno=1, col_offset=0)])" ) def test_increment_lineno(self): @@ -1299,8 +1295,7 @@ def test_iter_fields(self): node = ast.parse('foo()', mode='eval') d = dict(ast.iter_fields(node.body)) self.assertEqual(d.pop('func').id, 'foo') - self.assertEqual(d, {'keywords': [], 'kwargs': None, - 'args': [], 'starargs': None}) + self.assertEqual(d, {'keywords': [], 'args': []}) def test_iter_child_nodes(self): node = ast.parse("spam(23, 42, eggs='leek')", mode='eval') @@ -1384,8 +1379,8 @@ def main(): ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], ('arg', (1, 7), 'args', None), [], [], None, []), [('Pass', (1, 14))], [], None)]), ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], ('arg', (1, 8), 'kwargs', None), []), [('Pass', (1, 17))], [], None)]), ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None), ('arg', (1, 9), 'b', None), ('arg', (1, 14), 'c', None), ('arg', (1, 22), 'd', None), ('arg', (1, 28), 'e', None)], ('arg', (1, 35), 'args', None), [('arg', (1, 41), 'f', None)], [('Num', (1, 43), 42)], ('arg', (1, 49), 'kwargs', None), [('Num', (1, 11), 1), ('NameConstant', (1, 16), None), ('List', (1, 24), [], ('Load',)), ('Dict', (1, 30), [], [])]), [('Pass', (1, 58))], [], None)]), -('Module', [('ClassDef', (1, 0), 'C', [], [], None, None, [('Pass', (1, 8))], [])]), -('Module', [('ClassDef', (1, 0), 'C', [('Name', (1, 8), 'object', ('Load',))], [], None, None, [('Pass', (1, 17))], [])]), +('Module', [('ClassDef', (1, 0), 'C', [], [], [('Pass', (1, 8))], [])]), +('Module', [('ClassDef', (1, 0), 'C', [('Name', (1, 8), 'object', ('Load',))], [], [('Pass', (1, 17))], [])]), ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Return', (1, 8), ('Num', (1, 15), 1))], [], None)]), ('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])]), ('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Num', (1, 4), 1))]), @@ -1396,7 +1391,7 @@ def main(): ('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',)))], [('Pass', (1, 13))])]), ('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',)))], [('With', (1, 0), [('withitem', ('Name', (1, 13), 'z', ('Load',)), ('Name', (1, 18), 'q', ('Store',)))], [('Pass', (1, 21))])])]) if is_cli else ('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',))), ('withitem', ('Name', (1, 13), 'z', ('Load',)), ('Name', (1, 18), 'q', ('Store',)))], [('Pass', (1, 21))])]), -('Module', [('Raise', (1, 0), ('Call', (1, 6), ('Name', (1, 6), 'Exception', ('Load',)), [('Str', (1, 16), 'string')], [], None, None), None)]), +('Module', [('Raise', (1, 0), ('Call', (1, 6), ('Name', (1, 6), 'Exception', ('Load',)), [('Str', (1, 16), 'string')], []), None)]), ('Module', [('Try', (1, 0), [('Pass', (2, 2))], [('ExceptHandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [], [])]), ('Module', [('Try', (1, 0), [('Pass', (2, 2))], [], [], [('Pass', (4, 2))])]), ('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)]), @@ -1412,10 +1407,10 @@ def main(): ('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 0 if is_cli else 1), ('Tuple', (1, 1 if is_cli else 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [])]))]), ('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 0 if is_cli else 1), ('Tuple', (1, 1 if is_cli else 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11 if is_cli else 12), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [])]))]), ('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 0) if is_cli else (2, 4), ('Tuple', (2 if is_cli else 3, 4), [('Name', (3, 4), 'Aa', ('Load',)), ('Name', (5, 7), 'Bb', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (8, 4), [('Name', (8, 4), 'Aa', ('Store',)), ('Name', (10, 4), 'Bb', ('Store',))], ('Store',)), ('Name', (10, 10), 'Cc', ('Load',)), [])]))]), -('Module', [('Expr', (1, 0), ('DictComp', (1, 0 if is_cli else 1), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Name', (1, 11), 'w', ('Store',)), ('Name', (1, 16), 'x', ('Load',)), []), ('comprehension', ('Name', (1, 22), 'm', ('Store',)), ('Name', (1, 27), 'p', ('Load',)), [('Name', (1, 32), 'g', ('Load',))])]))]), -('Module', [('Expr', (1, 0), ('DictComp', (1, 0 if is_cli else 1), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'v', ('Store',)), ('Name', (1, 13), 'w', ('Store',))], ('Store',)), ('Name', (1, 18), 'x', ('Load',)), [])]))]), -('Module', [('Expr', (1, 0), ('SetComp', (1, 0 if is_cli else 1), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 12), 'x', ('Load',)), [('Name', (1, 17), 'g', ('Load',))])]))]), -('Module', [('Expr', (1, 0), ('SetComp', (1, 0 if is_cli else 1), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7), [('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 9), 'm', ('Store',))], ('Store',)), ('Name', (1, 14), 'x', ('Load',)), [])]))]), +('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Name', (1, 11), 'w', ('Store',)), ('Name', (1, 16), 'x', ('Load',)), []), ('comprehension', ('Name', (1, 22), 'm', ('Store',)), ('Name', (1, 27), 'p', ('Load',)), [('Name', (1, 32), 'g', ('Load',))])]))]), +('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'v', ('Store',)), ('Name', (1, 13), 'w', ('Store',))], ('Store',)), ('Name', (1, 18), 'x', ('Load',)), [])]))]), +('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 12), 'x', ('Load',)), [('Name', (1, 17), 'g', ('Load',))])]))]), +('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7), [('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 9), 'm', ('Store',))], ('Store',)), ('Name', (1, 14), 'x', ('Load',)), [])]))]), ] exec_results = exec_results_stdlib + [ ('Module', [('While', (1, 0), ('Name', (1, 6), 'x', ('Load',)), [('Break', (1, 9))], [])]), @@ -1441,7 +1436,7 @@ def main(): ('Expression', ('ListComp', (1, 0 if is_cli else 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))])])), ('Expression', ('GeneratorExp', (1, 0 if is_cli else 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))])])), ('Expression', ('Compare', (1, 0), ('Num', (1, 0), 1), [('Lt',), ('Lt',)], [('Num', (1, 4), 2), ('Num', (1, 8), 3)])), -('Expression', ('Call', (1, 0), ('Name', (1, 0), 'f', ('Load',)), [('Num', (1, 2), 1), ('Num', (1, 4), 2)], [('keyword', 'c', ('Num', (1, 8), 3))], ('Name', (1, 11), 'd', ('Load',)), ('Name', (1, 15), 'e', ('Load',)))), +('Expression', ('Call', (1, 0), ('Name', (1, 0), 'f', ('Load',)), [('Num', (1, 2), 1), ('Num', (1, 4), 2), ('Starred', (1, 10), ('Name', (1, 11), 'd', ('Load',)), ('Load',))], [('keyword', 'c', ('Num', (1, 8), 3)), ('keyword', None, ('Name', (1, 15), 'e', ('Load',)))])), ('Expression', ('Num', (1, 0), 10)), ('Expression', ('Str', (1, 0), 'string')), ('Expression', ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',))), @@ -1452,7 +1447,7 @@ def main(): ('Expression', ('Tuple', (1, 0), [('Num', (1, 0), 1), ('Num', (1, 2), 2), ('Num', (1, 4), 3)], ('Load',))), ('Expression', ('Tuple', (1, 0 if is_cli else 1), [('Num', (1, 1), 1), ('Num', (1, 3), 2), ('Num', (1, 5), 3)], ('Load',))), ('Expression', ('Tuple', (1, 0), [], ('Load',))), -('Expression', ('Call', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 8), ('Attribute', (1, 8), ('Name', (1, 8), 'a', ('Load',)), 'b', ('Load',)), ('Slice', ('Num', (1, 12), 1), ('Num', (1, 14), 2), None), ('Load',))], [], None, None)), +('Expression', ('Call', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 8), ('Attribute', (1, 8), ('Name', (1, 8), 'a', ('Load',)), 'b', ('Load',)), ('Slice', ('Num', (1, 12), 1), ('Num', (1, 14), 2), None), ('Load',))], [])), ] eval_results = eval_results_stdlib + [ ('Expression', ('Lambda', (1, 0), ('arguments', [('arg', (1, 7), 'x', None)], None, [], [], None, []), ('Name', (1, 10), 'x', ('Load',)))), @@ -1463,12 +1458,12 @@ def main(): ('Expression', ('GeneratorExp', (1, 0 if is_cli else 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), []), ('comprehension', ('Name', (1, 18), 'd', ('Store',)), ('Name', (1, 23), 'e', ('Load',)), []), ('comprehension', ('Name', (1, 29), 'f', ('Store',)), ('Name', (1, 34), 'g', ('Load',)), [])])), ('Expression', ('GeneratorExp', (1, 0 if is_cli else 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), []), ('comprehension', ('Name', (1, 18), 'c', ('Store',)), ('Name', (1, 23), 'd', ('Load',)), [])])), ('Expression', ('GeneratorExp', (1, 0 if is_cli else 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), []), ('comprehension', ('Name', (1, 18), 'c', ('Store',)), ('Name', (1, 23), 'd', ('Load',)), [('Name', (1, 28), 'e', ('Load',))])])), -('Expression', ('GeneratorExp', (1, 0 if is_cli else 1), ('Yield', (1, 1 if is_cli else 2), ('Name', (1, 8), 'i', ('Load',))), [('comprehension', ('Name', (1, 15), 'i', ('Store',)), ('Call', (1, 20), ('Name', (1, 20), 'range', ('Load',)), [('Num', (1, 26), 5)], [], None, None), [])])), +('Expression', ('GeneratorExp', (1, 0 if is_cli else 1), ('Yield', (1, 1 if is_cli else 2), ('Name', (1, 8), 'i', ('Load',))), [('comprehension', ('Name', (1, 15), 'i', ('Store',)), ('Call', (1, 20), ('Name', (1, 20), 'range', ('Load',)), [('Num', (1, 26), 5)], []), [])])), ('Expression', ('Subscript', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Index', ('Ellipsis', (1, 1 if is_cli else 2))), ('Load',))), ('Expression', ('Subscript', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Index', ('Num', (1, 1 if is_cli else 2), 1)), ('Load',))), ('Expression', ('Set', (1, 0), [('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 3), 'b', ('Load',)), ('Name', (1, 5), 'c', ('Load',))])), -('Expression', ('DictComp', (1, 0 if is_cli else 1), ('Name', (1, 1), 'k', ('Load',)), ('Name', (1, 3), 'v', ('Load',)), [('comprehension', ('Tuple', (1, 9), [('Name', (1, 9), 'k', ('Store',)), ('Name', (1, 11), 'v', ('Store',))], ('Store',)), ('Name', (1, 16), 'li', ('Load',)), [])])), -('Expression', ('SetComp', (1, 0 if is_cli else 1), ('Name', (1, 1), 'e', ('Load',)), [('comprehension', ('Name', (1, 7), 'e', ('Store',)), ('Name', (1, 12), 'li', ('Load',)), [])])), +('Expression', ('DictComp', (1, 0), ('Name', (1, 1), 'k', ('Load',)), ('Name', (1, 3), 'v', ('Load',)), [('comprehension', ('Tuple', (1, 9), [('Name', (1, 9), 'k', ('Store',)), ('Name', (1, 11), 'v', ('Store',))], ('Store',)), ('Name', (1, 16), 'li', ('Load',)), [])])), +('Expression', ('SetComp', (1, 0), ('Name', (1, 1), 'e', ('Load',)), [('comprehension', ('Name', (1, 7), 'e', ('Store',)), ('Name', (1, 12), 'li', ('Load',)), [])])), ] run_test(__name__)