diff --git a/test/bytecode_3.3/02_named_and_kwargs.pyc b/test/bytecode_3.3/02_named_and_kwargs.pyc new file mode 100644 index 00000000..259063d5 Binary files /dev/null and b/test/bytecode_3.3/02_named_and_kwargs.pyc differ diff --git a/test/simple_source/bug33/02_named_and_kwargs.py b/test/simple_source/bug33/02_named_and_kwargs.py new file mode 100644 index 00000000..bb50c08b --- /dev/null +++ b/test/simple_source/bug33/02_named_and_kwargs.py @@ -0,0 +1,4 @@ +# Python 3.6 subprocess.py bug +# Bug is getting params correct: timeout before **kwargs +def call(*popenargs, timeout=None, **kwargs): + return diff --git a/uncompyle6/scanners/scanner2.py b/uncompyle6/scanners/scanner2.py index d92fc5bd..feb097db 100644 --- a/uncompyle6/scanners/scanner2.py +++ b/uncompyle6/scanners/scanner2.py @@ -392,9 +392,15 @@ class Scanner2(scan.Scanner): stmts.remove(s) continue elif code[s] == self.opc.POP_TOP: + # The POP_TOP in: + # ROT_TWO, POP_TOP or + # JUMP_IF_{FALSE,TRUE}, POP_TOP + # is part of the previous instruction and not the + # beginning of a new statement prev = code[self.prev[s]] if (prev == self.opc.ROT_TWO or - self.version <= 2.6 and prev == self.opc.JUMP_IF_FALSE): + self.version <= 2.6 and prev in + (self.opc.JUMP_IF_FALSE, self.opc.JUMP_IF_TRUE)): stmts.remove(s) continue elif code[s] in self.designator_ops: diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index c0ae6fc0..078bd0cb 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -2021,23 +2021,21 @@ class SourceWalker(GenericASTTraversal, object): return # build parameters - params = [build_param(ast, name, default) for name, default in zip_longest(paramnames, defparams, fillvalue=None)] params.reverse() # back to correct order + kw_pairs = 0 + if 4 & code.co_flags: # flag 2 -> variable number of args if self.version > 3.0: - params.append('*%s' % code.co_varnames[argc + args_node.attr[1]]) + kw_pairs = args_node.attr[1] + params.append('*%s' % code.co_varnames[argc + kw_pairs]) else: params.append('*%s' % code.co_varnames[argc]) argc += 1 - if 8 & code.co_flags: # flag 3 -> keyword args - params.append('**%s' % code.co_varnames[argc]) - argc += 1 - # dump parameter list (with default values) indent = self.indent if isLambda: @@ -2063,6 +2061,11 @@ class SourceWalker(GenericASTTraversal, object): break pass + if 8 & code.co_flags: # flag 3 -> keyword args + if argc > 0: + self.write(', ') + self.write('**%s' % code.co_varnames[argc + kw_pairs]) + if isLambda: self.write(": ") else: