You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 01:09:52 +08:00
enhance call_ex_kw(s) positional args handling
This commit is contained in:
Binary file not shown.
@@ -16,6 +16,9 @@ def f1(c, d, **extra_args):
|
||||
def f2(**extra_args):
|
||||
return showparams(1, test="C", **extra_args)
|
||||
|
||||
def f3(c, *args, **extra_args):
|
||||
return showparams(c, *args, **extra_args)
|
||||
|
||||
assert f(1, a=2, b=3) == {'c': 1, 'a': 2, 'b': 3, 'test': 'A'}
|
||||
|
||||
a = {'param1': 2}
|
||||
@@ -35,3 +38,10 @@ assert f1((a.get('a'), a.get('b')), a, test3='A', **a) \
|
||||
b = {'b1': 1, 'b2': 2}
|
||||
assert f2(**a, **b) == \
|
||||
{'c': 1, 'param1': 2, 'b1': 1, 'b2': 2, 'test': 'C'}
|
||||
|
||||
c = (2,)
|
||||
d = (2, 3)
|
||||
assert f(2, **a) == {'c': 2, 'param1': 2, 'test': 'A'}
|
||||
assert f3(2, *c, **a) == {'c': 2, 'param1': 2, 'test': 2}
|
||||
assert f3(*d, **a) == {'c': 2, 'param1': 2, 'test': 3}
|
||||
|
||||
|
@@ -76,20 +76,28 @@ def customize_for_version36(self, version):
|
||||
})
|
||||
|
||||
def build_unpack_tuple_with_call(node):
|
||||
|
||||
if node[0] == 'expr':
|
||||
tup = node[0][0]
|
||||
n = node[0]
|
||||
if n == 'expr':
|
||||
n = n[0]
|
||||
if n == 'tuple':
|
||||
self.call36_tuple(n)
|
||||
first = 1
|
||||
sep = ', *'
|
||||
elif n == 'LOAD_CONST':
|
||||
value = self.format_pos_args(n)
|
||||
self.f.write(value)
|
||||
first = 1
|
||||
sep = ', *'
|
||||
else:
|
||||
tup = node[0]
|
||||
pass
|
||||
assert tup == 'tuple'
|
||||
self.call36_tuple(tup)
|
||||
first = 0
|
||||
sep = '*'
|
||||
|
||||
buwc = node[-1]
|
||||
assert buwc.kind.startswith('BUILD_TUPLE_UNPACK_WITH_CALL')
|
||||
for n in node[1:-1]:
|
||||
self.f.write(', *')
|
||||
for n in node[first:-1]:
|
||||
self.f.write(sep)
|
||||
self.preorder(n)
|
||||
sep = ', *'
|
||||
pass
|
||||
self.prune()
|
||||
return
|
||||
@@ -121,17 +129,10 @@ def customize_for_version36(self, version):
|
||||
|
||||
expr = node[1]
|
||||
assert expr == 'expr'
|
||||
value = self.traverse(expr, indent='')
|
||||
|
||||
if value.startswith('('):
|
||||
assert value.endswith(')')
|
||||
value = value[1:-1].rstrip(" ") # Remove starting '(' and trailing ')' and additional spaces
|
||||
value = self.format_pos_args(expr)
|
||||
if value == '':
|
||||
fmt = "%c(%p)" # args is empty
|
||||
else:
|
||||
if value.endswith(','): # if args has only one item
|
||||
value = value[:-1]
|
||||
fmt = "%%c(%s, %%p)" % value
|
||||
fmt = "%c(%p)"
|
||||
else:
|
||||
fmt = "%%c(%s, %%p)" % value
|
||||
|
||||
@@ -146,41 +147,17 @@ def customize_for_version36(self, version):
|
||||
"""Handle CALL_FUNCTION_EX 2 (have KW) but with
|
||||
BUILD_{MAP,TUPLE}_UNPACK_WITH_CALL"""
|
||||
|
||||
# This is weird shit. Thanks Python!
|
||||
self.preorder(node[0])
|
||||
self.write('(')
|
||||
|
||||
assert node[1] == 'build_tuple_unpack_with_call'
|
||||
btuwc = node[1]
|
||||
tup = btuwc[0]
|
||||
if tup == 'expr':
|
||||
tup = tup[0]
|
||||
|
||||
if tup == 'LOAD_CONST':
|
||||
self.write(', '.join(['"%s"' % t.replace('"','\\"') for t in tup.attr]))
|
||||
value = self.format_pos_args(node[1])
|
||||
if value == '':
|
||||
fmt = "%c(%p)"
|
||||
else:
|
||||
assert tup == 'tuple'
|
||||
self.call36_tuple(tup)
|
||||
fmt = "%%c(%s, %%p)" % value
|
||||
|
||||
assert node[2] == 'build_map_unpack_with_call'
|
||||
self.template_engine(
|
||||
(fmt,
|
||||
(0, 'expr'), (2, 'build_map_unpack_with_call', 100)), node)
|
||||
|
||||
self.write(', ')
|
||||
d = node[2][0]
|
||||
if d == 'expr':
|
||||
d = d[0]
|
||||
assert d == 'dict'
|
||||
self.call36_dict(d)
|
||||
|
||||
args = btuwc[1]
|
||||
self.write(', *')
|
||||
self.preorder(args)
|
||||
|
||||
self.write(', **')
|
||||
star_star_args = node[2][1]
|
||||
if star_star_args == 'expr':
|
||||
star_star_args = star_star_args[0]
|
||||
self.preorder(star_star_args)
|
||||
self.write(')')
|
||||
self.prune()
|
||||
self.n_call_ex_kw2 = call_ex_kw2
|
||||
|
||||
@@ -189,14 +166,13 @@ def customize_for_version36(self, version):
|
||||
BUILD_MAP_UNPACK_WITH_CALL"""
|
||||
self.preorder(node[0])
|
||||
self.write('(')
|
||||
args = node[1][0]
|
||||
if args == 'expr':
|
||||
args = args[0]
|
||||
if args == 'tuple':
|
||||
if self.call36_tuple(args) > 0:
|
||||
|
||||
value = self.format_pos_args(node[1][0])
|
||||
if value == '':
|
||||
pass
|
||||
else:
|
||||
self.write(value)
|
||||
self.write(', ')
|
||||
pass
|
||||
pass
|
||||
|
||||
self.write('*')
|
||||
self.preorder(node[1][1])
|
||||
@@ -249,6 +225,25 @@ def customize_for_version36(self, version):
|
||||
self.prune()
|
||||
self.n_call_ex_kw4 = call_ex_kw4
|
||||
|
||||
def format_pos_args(node):
|
||||
"""
|
||||
Positional args should format to:
|
||||
(*(2, ), ...) -> (2, ...)
|
||||
We remove starting and trailing parenthesis and ', ' if
|
||||
tuple has only one element.
|
||||
"""
|
||||
value = self.traverse(node, indent='')
|
||||
if value.startswith('('):
|
||||
assert value.endswith(')')
|
||||
value = value[1:-1].rstrip(" ") # Remove starting '(' and trailing ')' and additional spaces
|
||||
if value == '':
|
||||
pass # args is empty
|
||||
else:
|
||||
if value.endswith(','): # if args has only one item
|
||||
value = value[:-1]
|
||||
return value
|
||||
self.format_pos_args = format_pos_args
|
||||
|
||||
def call36_tuple(node):
|
||||
"""
|
||||
A tuple used in a call, these are like normal tuples but they
|
||||
|
Reference in New Issue
Block a user