From 2c121545f0d701cca071e9799857f559231d7c4c Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 15 May 2016 18:14:22 -0400 Subject: [PATCH] Fix bug in Python 3 lambda expression handling Some other small cleanup changes --- test/bytecode_3.5/05_lambda.pyc | Bin 0 -> 271 bytes test/simple_source/expression/05_lambda.py | 10 ++++++++++ test/test_pyenvlib.py | 8 ++++---- uncompyle6/parsers/parse3.py | 5 +++-- uncompyle6/scanners/scanner3.py | 7 ++++++- uncompyle6/semantics/pysource.py | 5 ++++- 6 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 test/bytecode_3.5/05_lambda.pyc create mode 100644 test/simple_source/expression/05_lambda.py diff --git a/test/bytecode_3.5/05_lambda.pyc b/test/bytecode_3.5/05_lambda.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d37884b097ad991c0e7532af808f3c7d936e4b99 GIT binary patch literal 271 zcmWgR<>li0Vi7LK$iVQJ0ST}G*$zNlECnP|85pt{8B!P+Qh+2ALkj~#GXo=I3Nu5n zCQB4|T7FS(Vo6zIPHAc~&=@cP(ID&$#Kj=9N*I8O8T~XFZ*j!Or)B1(#>WHMtYBR$ z8H$*JN`9#pXXX|FWs37li;`3IQ!5IJQj3c-^Yio#OyhGBbCXgM^$IF)ao9lEc3dFC xftaC)6-fALGTma&%quQPO)iPzhd3&+C>?A=G1vkm0^}s1LAm)Ur8%hxg8+x8JlFsL literal 0 HcmV?d00001 diff --git a/test/simple_source/expression/05_lambda.py b/test/simple_source/expression/05_lambda.py new file mode 100644 index 00000000..42e5c454 --- /dev/null +++ b/test/simple_source/expression/05_lambda.py @@ -0,0 +1,10 @@ +# Bug in Python 3 + +# mklambda ::= LOAD_LAMBDA LOAD_CONST MAKE_FUNCTION_0 +# _mklambda ::= mklambda +# expr ::= _mklambda +# kwarg ::= LOAD_CONST expr +# exprlist ::= exprlist expr +# call_function ::= expr kwarg CALL_FUNCTION_256 + +inspect.formatargvalues(formatvalue=lambda value: __file__) diff --git a/test/test_pyenvlib.py b/test/test_pyenvlib.py index 01bdb708..366a842f 100755 --- a/test/test_pyenvlib.py +++ b/test/test_pyenvlib.py @@ -5,10 +5,10 @@ test_pyenvlib -- uncompyle and verify Python libraries Usage-Examples: - test_pyenvlib --all # decompile all tests (suite + libs) - test_pyenvlib --all --verify # decomyile all tests and verify results - test_pyenvlib --test # decompile only the testsuite - test_pyenvlib --2.2 --verify # decompile and verify python lib 2.2 + test_pyenvlib.py --all # decompile all tests (suite + libs) + test_pyenvlib.py --all --verify # decomyile all tests and verify results + test_pyenvlib.py --test # decompile only the testsuite + test_pyenvlib.py --2.7.11 --verify # decompile and verify python lib 2.7.11 Adding own test-trees: diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index 9d190574..074de9c1 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -524,8 +524,9 @@ class Python3Parser(PythonParser): rule = 'unpack_list ::= ' + opname + ' designator' * token.attr elif opname_base.startswith('MAKE_FUNCTION'): args_pos, args_kw, annotate_args = token.attr - self.addRule('mklambda ::= %sLOAD_LAMBDA %s' % - ('pos_arg ' * args_pos, opname), nop_func) + rule = ('mklambda ::= %sLOAD_LAMBDA LOAD_CONST %s' % + ('pos_arg '* args_pos, opname)) + self.add_unique_rule(rule, opname, token.attr, customize) if self.version > 3.2: rule = ('mkfunc ::= %skwargs %s %s' % ('pos_arg ' * args_pos, diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index a2710087..341523b6 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -43,12 +43,15 @@ class Scanner3(scan.Scanner): ## FIXME opnames should be passed in here def __init__(self, version): self.version = version + self.opnames = {} # will eventually get passed in scan.Scanner.__init__(self, version) ## FIXME opnames should be moved to init def disassemble3(self, co, opnames, classname=None, code_objects={}): + self.opnames = opnames # will eventually disasppear + # import dis; dis.disassemble(co) # DEBUG # Container for tokens @@ -829,7 +832,9 @@ class Scanner3(scan.Scanner): if __name__ == "__main__": import inspect co = inspect.currentframe().f_code - tokens, customize = Scanner3().disassemble_generic(co) + from uncompyle6 import PYTHON_VERSION + from opcode import opname + tokens, customize = Scanner3(PYTHON_VERSION).disassemble3(co, opname) for t in tokens: print(t) pass diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 51704667..64e40c8d 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -1605,7 +1605,10 @@ class SourceWalker(GenericASTTraversal, object): pos_args = args_node.attr pass - code = node[code_index].attr + if self.version > 3.0 and isLambda and iscode(node[-3].attr): + code = node[-3].attr + else: + code = node[code_index].attr assert iscode(code) code = Code(code, self.scanner, self.currentclass)