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
(cherry picked from commit 96b06aefe2)

Co-authored-by: Zsolt Dollenstein <zsol.zsol@gmail.com>
This commit is contained in:
Miss Skeleton (bot) 2019-10-23 23:37:21 -07:00 committed by GitHub
parent d8fc9c843e
commit d04661f9ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 14 additions and 11 deletions

View File

@ -138,8 +138,8 @@ arglist: argument (',' argument)* [',']
# that precede iterable unpackings are blocked; etc. # that precede iterable unpackings are blocked; etc.
argument: ( test [comp_for] | argument: ( test [comp_for] |
test '=' test | test '=' test |
'**' expr | '**' test |
star_expr ) '*' test )
comp_iter: comp_for | comp_if comp_iter: comp_for | comp_if
comp_for: [ASYNC] 'for' exprlist 'in' testlist_safe [comp_iter] comp_for: [ASYNC] 'for' exprlist 'in' testlist_safe [comp_iter]

View File

@ -37,10 +37,8 @@ class FixApply(fixer_base.BaseFix):
# I feel like we should be able to express this logic in the # 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... # PATTERN above but I don't know how to do it so...
if args: if args:
if args.type == self.syms.star_expr:
return # Make no change.
if (args.type == self.syms.argument and if (args.type == self.syms.argument and
args.children[0].value == '**'): args.children[0].value in {'**', '*'}):
return # Make no change. return # Make no change.
if kwds and (kwds.type == self.syms.argument and if kwds and (kwds.type == self.syms.argument and
kwds.children[0].value == '**'): kwds.children[0].value == '**'):

View File

@ -30,10 +30,8 @@ class FixIntern(fixer_base.BaseFix):
# PATTERN above but I don't know how to do it so... # PATTERN above but I don't know how to do it so...
obj = results['obj'] obj = results['obj']
if obj: if obj:
if obj.type == self.syms.star_expr:
return # Make no change.
if (obj.type == self.syms.argument and if (obj.type == self.syms.argument and
obj.children[0].value == '**'): obj.children[0].value in {'**', '*'}):
return # Make no change. return # Make no change.
names = ('sys', 'intern') names = ('sys', 'intern')
new = ImportAndCall(node, results, names) new = ImportAndCall(node, results, names)

View File

@ -27,10 +27,8 @@ class FixReload(fixer_base.BaseFix):
# PATTERN above but I don't know how to do it so... # PATTERN above but I don't know how to do it so...
obj = results['obj'] obj = results['obj']
if obj: if obj:
if obj.type == self.syms.star_expr:
return # Make no change.
if (obj.type == self.syms.argument and if (obj.type == self.syms.argument and
obj.children[0].value == '**'): obj.children[0].value in {'**', '*'}):
return # Make no change. return # Make no change.
names = ('importlib', 'reload') names = ('importlib', 'reload')
new = ImportAndCall(node, results, names) new = ImportAndCall(node, results, names)

View File

@ -253,6 +253,13 @@ class TestUnpackingGeneralizations(GrammarTest):
def test_double_star_dict_literal_after_keywords(self): def test_double_star_dict_literal_after_keywords(self):
self.validate("""func(spam='fried', **{'eggs':'scrambled'})""") 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): def test_list_display(self):
self.validate("""[*{2}, 3, *[4]]""") self.validate("""[*{2}, 3, *[4]]""")

View File

@ -0,0 +1,2 @@
lib2to3 now recognizes expressions after ``*`` and `**` like in ``f(*[] or
[])``.