From 136f935e26788ae95683c0427a92287e9b946e3e Mon Sep 17 00:00:00 2001 From: rocky Date: Fri, 2 Sep 2016 06:30:39 -0400 Subject: [PATCH] Fix Python 3.x named param and kwargs bug --- test/bytecode_3.3/02_named_and_kwargs.pyc | Bin 0 -> 354 bytes test/simple_source/bug33/02_named_and_kwargs.py | 4 ++++ uncompyle6/scanners/scanner2.py | 8 +++++++- uncompyle6/semantics/pysource.py | 15 +++++++++------ 4 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 test/bytecode_3.3/02_named_and_kwargs.pyc create mode 100644 test/simple_source/bug33/02_named_and_kwargs.py 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 0000000000000000000000000000000000000000..259063d5d03d44783f465d137999b7898f5ff81c GIT binary patch literal 354 zcmb77I|{-;6nrt_4{bfeVqwHI79yS?78Zg{h}lKNBpb3m#NG>d0q^6joEIV5y6l^s z8D`%+hoiwFdhH%Wlwz9G23up?7@%=|(jMs+-O1a7__S4$;V$5E%8lhqy}*O^G4gIO zPEuH~RpLYnKuQ9?Ke-R1w52JM>gc!wb-oJy#36|%0C&pE%*4)em73td$1n_L^SDTI yqvNE|@#ojHys^}#NtQ{KYXQh>yhw>r%g7d{@xN^~`?s=(rOVuE&djQ=mDV@4d`EQv literal 0 HcmV?d00001 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: