From: Zsolt Dollenstein Date: Thu, 24 Oct 2019 06:19:07 +0000 (-0700) Subject: bpo-33348: parse expressions after * and ** in lib2to3 (GH-6586) X-Git-Tag: v3.9.0a1~128 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=96b06aefe23521b61e4e9cdd44f5d30b00c7eb95;p=thirdparty%2FPython%2Fcpython.git bpo-33348: parse expressions after * and ** in lib2to3 (GH-6586) These are valid even in python 2.7 https://bugs.python.org/issue33348 Automerge-Triggered-By: @gpshead --- diff --git a/Lib/lib2to3/Grammar.txt b/Lib/lib2to3/Grammar.txt index a7ddad3cf322..68b73868b582 100644 --- a/Lib/lib2to3/Grammar.txt +++ b/Lib/lib2to3/Grammar.txt @@ -138,8 +138,8 @@ arglist: argument (',' argument)* [','] # that precede iterable unpackings are blocked; etc. argument: ( test [comp_for] | test '=' test | - '**' expr | - star_expr ) + '**' test | + '*' test ) comp_iter: comp_for | comp_if comp_for: [ASYNC] 'for' exprlist 'in' testlist_safe [comp_iter] diff --git a/Lib/lib2to3/fixes/fix_apply.py b/Lib/lib2to3/fixes/fix_apply.py index 826ec8c9b62a..6408582c4264 100644 --- a/Lib/lib2to3/fixes/fix_apply.py +++ b/Lib/lib2to3/fixes/fix_apply.py @@ -37,10 +37,8 @@ class FixApply(fixer_base.BaseFix): # I feel like we should be able to express this logic in the # PATTERN above but I don't know how to do it so... if args: - if args.type == self.syms.star_expr: - return # Make no change. if (args.type == self.syms.argument and - args.children[0].value == '**'): + args.children[0].value in {'**', '*'}): return # Make no change. if kwds and (kwds.type == self.syms.argument and kwds.children[0].value == '**'): diff --git a/Lib/lib2to3/fixes/fix_intern.py b/Lib/lib2to3/fixes/fix_intern.py index a852330908bd..d752843092aa 100644 --- a/Lib/lib2to3/fixes/fix_intern.py +++ b/Lib/lib2to3/fixes/fix_intern.py @@ -30,10 +30,8 @@ class FixIntern(fixer_base.BaseFix): # PATTERN above but I don't know how to do it so... obj = results['obj'] if obj: - if obj.type == self.syms.star_expr: - return # Make no change. if (obj.type == self.syms.argument and - obj.children[0].value == '**'): + obj.children[0].value in {'**', '*'}): return # Make no change. names = ('sys', 'intern') new = ImportAndCall(node, results, names) diff --git a/Lib/lib2to3/fixes/fix_reload.py b/Lib/lib2to3/fixes/fix_reload.py index 6c7fbbd3be3f..b30841131c51 100644 --- a/Lib/lib2to3/fixes/fix_reload.py +++ b/Lib/lib2to3/fixes/fix_reload.py @@ -27,10 +27,8 @@ class FixReload(fixer_base.BaseFix): # PATTERN above but I don't know how to do it so... obj = results['obj'] if obj: - if obj.type == self.syms.star_expr: - return # Make no change. if (obj.type == self.syms.argument and - obj.children[0].value == '**'): + obj.children[0].value in {'**', '*'}): return # Make no change. names = ('importlib', 'reload') new = ImportAndCall(node, results, names) diff --git a/Lib/lib2to3/tests/test_parser.py b/Lib/lib2to3/tests/test_parser.py index f22d399b3403..a0c31e8f5300 100644 --- a/Lib/lib2to3/tests/test_parser.py +++ b/Lib/lib2to3/tests/test_parser.py @@ -253,6 +253,13 @@ class TestUnpackingGeneralizations(GrammarTest): def test_double_star_dict_literal_after_keywords(self): self.validate("""func(spam='fried', **{'eggs':'scrambled'})""") + def test_double_star_expression(self): + self.validate("""func(**{'a':2} or {})""") + self.validate("""func(**() or {})""") + + def test_star_expression(self): + self.validate("""func(*[] or [2])""") + def test_list_display(self): self.validate("""[*{2}, 3, *[4]]""") diff --git a/Misc/NEWS.d/next/Library/2018-04-24-13-18-48.bpo-33348.XaJDei.rst b/Misc/NEWS.d/next/Library/2018-04-24-13-18-48.bpo-33348.XaJDei.rst new file mode 100644 index 000000000000..f95a73fb57ed --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-24-13-18-48.bpo-33348.XaJDei.rst @@ -0,0 +1,2 @@ +lib2to3 now recognizes expressions after ``*`` and `**` like in ``f(*[] or +[])``.