From dad1b4780cdb2be63e035bc88d23dad1c51461e3 Mon Sep 17 00:00:00 2001 From: rocky Date: Fri, 1 Dec 2017 20:12:06 -0500 Subject: [PATCH] Fix bugs in 3.6 default parameter handling Mentioned in Issue #139 --- test/bytecode_3.6/03_fn_defaults.pyc | Bin 0 -> 620 bytes test/simple_source/bug36/03_fn_defaults.py | 9 +++++++ uncompyle6/semantics/make_function.py | 26 ++++++++++++++------- 3 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 test/bytecode_3.6/03_fn_defaults.pyc create mode 100644 test/simple_source/bug36/03_fn_defaults.py diff --git a/test/bytecode_3.6/03_fn_defaults.pyc b/test/bytecode_3.6/03_fn_defaults.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c441b93907ee410c352fbe06677c6768e0ffe1e6 GIT binary patch literal 620 zcmaixzfQw25XNIWv}sCUWo2N9geVZigb)&Y7q%=>n@bQ3{;7aHc4H@Z!U*;4Qgi2SY^Ro|p02k>Dmd*C>8+)~Mw|!@XuFs$V_c@ zUd)#EF}a?dCt3NNQBf{z^E4{gc$oX{Zne{o@iaCMgg8m=&Vrj&O|~j-Q8JJfN<4o}Jy>4= literal 0 HcmV?d00001 diff --git a/test/simple_source/bug36/03_fn_defaults.py b/test/simple_source/bug36/03_fn_defaults.py new file mode 100644 index 00000000..172d61d1 --- /dev/null +++ b/test/simple_source/bug36/03_fn_defaults.py @@ -0,0 +1,9 @@ +# Python 3.6 changes, yet again, the way deafult pairs are handled +def foo1(bar, baz=1): + return 1 +def foo2(bar, baz, qux=1): + return 2 +def foo3(bar, baz=1, qux=2): + return 3 +def foo4(bar, baz, qux=1, quux=2): + return 4 diff --git a/uncompyle6/semantics/make_function.py b/uncompyle6/semantics/make_function.py index 008b45dc..422b1deb 100644 --- a/uncompyle6/semantics/make_function.py +++ b/uncompyle6/semantics/make_function.py @@ -481,7 +481,10 @@ def make_function3(self, node, is_lambda, nested=1, codeNode=None): - handle format tuple parameters """ if default: - value = self.traverse(default, indent='') + if self.version >= 3.6: + value = default + else: + value = self.traverse(default, indent='') maybe_show_ast_param_default(self.showast, name, value) result = '%s=%s' % (name, value) if result[-2:] == '= ': # default was 'LOAD_CONST None' @@ -517,12 +520,17 @@ def make_function3(self, node, is_lambda, nested=1, codeNode=None): defparams = node[:args_node.attr] else: default, kw, annotate, closure = args_node.attr - # FIXME: start here for Python 3.6 and above: - defparams = [] - # if default: - # defparams = node[-(2 + kw + annotate + closure)] - # else: - # defparams = [] + if default: + assert node[0] == 'expr', "expecting mkfunc default node to be an expr" + expr_node = node[0] + if (expr_node[0] == 'LOAD_CONST' and + isinstance(expr_node[0].attr, tuple)): + defparams = list(expr_node[0].attr) + elif expr_node[0] == 'list': + defparams = [self.traverse(n, indent='') for n in expr_node[0][:-1]] + else: + defparams = [] + # FIXME: handle kw, annotate and closure kw_args = 0 pass @@ -542,7 +550,7 @@ def make_function3(self, node, is_lambda, nested=1, codeNode=None): paramnames = list(code.co_varnames[:argc]) # defaults are for last n parameters, thus reverse - if not 3.0 <= self.version <= 3.1: + if not 3.0 <= self.version <= 3.1 or self.version >= 3.6: paramnames.reverse(); defparams.reverse() try: @@ -562,7 +570,7 @@ def make_function3(self, node, is_lambda, nested=1, codeNode=None): params = [build_param(ast, name, d) for name, d in zip_longest(paramnames, defparams, fillvalue=None)] - if not 3.0 <= self.version <= 3.1: + if not 3.0 <= self.version <= 3.1 or self.version >= 3.6: params.reverse() # back to correct order if code_has_star_arg(code):