From 096563cf911b45c95d2a1d0c8fb3050aa39e4cf0 Mon Sep 17 00:00:00 2001 From: rocky Date: Mon, 4 Jun 2018 10:32:55 -0400 Subject: [PATCH] Fix Python 1.5- bug in handling unpack list --- test/bytecode_1.4/02_continue.pyc | Bin 0 -> 348 bytes test/bytecode_1.4/test_del.pyc | Bin 0 -> 784 bytes test/bytecode_1.5/00_unpack_list.pyc | Bin 0 -> 152 bytes test/simple_source/bug14/00_unpack_list.py | 3 +++ uncompyle6/parsers/parse14.py | 21 +++++++++++++++++++++ uncompyle6/parsers/parse15.py | 13 ++++++++++++- uncompyle6/parsers/parse2.py | 2 -- uncompyle6/scanners/scanner15.py | 14 ++++++++++++++ 8 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 test/bytecode_1.4/02_continue.pyc create mode 100644 test/bytecode_1.4/test_del.pyc create mode 100644 test/bytecode_1.5/00_unpack_list.pyc create mode 100644 test/simple_source/bug14/00_unpack_list.py diff --git a/test/bytecode_1.4/02_continue.pyc b/test/bytecode_1.4/02_continue.pyc new file mode 100644 index 0000000000000000000000000000000000000000..052a3ff2277cbc328089a31745860faf6f9c56d9 GIT binary patch literal 348 zcmb78v2MaJ6g-DO)K;iNRq+K#QHKPovbJ-VEDT66M8UDZDzQ_ZBZ1T^L;I0@PM^cl zfd%X7`Fy^2_rlTe_VoI=lIRXS@YQmKD1l#K36ui!IAC4|2+#w)drgS8kHgIOFTg%Q zv;&W{@B=>rcF0r&7vLK(5kGG5*_Bwdcb=bf#MwEckUdRNskq002HfgmUsOa9!)-zN zhdOqm%o^2g^Iz2W`cg|rV@64mlCJ8V%E>l+snT_`nZBfx=UiIjv}sgQAL;&_K`O7B VozooWvRE*A=_h6$SD1UBw?9=^PHq4I literal 0 HcmV?d00001 diff --git a/test/bytecode_1.4/test_del.pyc b/test/bytecode_1.4/test_del.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f6c02ff6ba56312eebd9b3cf9904fb82cde3bc7b GIT binary patch literal 784 zcmYLHOK%e~5T3mHF!V)B(@>xW4hcxf3e;YZDvoeMNZ}L?EANieSnS%XwWBDfm5};B z_RA`;q#Z~ z2y_du1A|!`nq$B&lPB1<`LjN+%zw^Bats7*#o4p4&c5+hF5@xT#{S;5igl@=@sBHmtM!x3G?@D zKpKQU&r6(UgL^Se*yZRy|4fP literal 0 HcmV?d00001 diff --git a/test/bytecode_1.5/00_unpack_list.pyc b/test/bytecode_1.5/00_unpack_list.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0db4cedecf7d50382d2c3918babd8be98943cb3f GIT binary patch literal 152 zcmbQ~$IF%NBO0B|00c}xTr378>Vb%vA(eq4mWd&Xks*qSA%%e$32JxkN1&PVo@j02rC3*#w#USJDnHh>fIstBnAa4Kw literal 0 HcmV?d00001 diff --git a/test/simple_source/bug14/00_unpack_list.py b/test/simple_source/bug14/00_unpack_list.py new file mode 100644 index 00000000..92b24632 --- /dev/null +++ b/test/simple_source/bug14/00_unpack_list.py @@ -0,0 +1,3 @@ +# Python 1.4 tzparse.py, but also appears in 1.5 + +[tzname, delta] = __file__ diff --git a/uncompyle6/parsers/parse14.py b/uncompyle6/parsers/parse14.py index 51289d0d..55c856f3 100644 --- a/uncompyle6/parsers/parse14.py +++ b/uncompyle6/parsers/parse14.py @@ -13,6 +13,7 @@ class Python14Parser(Python15Parser): # SET_FUNC_ARGS, and RESERVE_FAST # FIXME: should check that this indeed around __doc__ + # Possibly not strictly needed stmt ::= doc_junk doc_junk ::= LOAD_CONST POP_TOP @@ -35,6 +36,26 @@ class Python14Parser(Python15Parser): super(Python14Parser, self).__init__(debug_parser) self.customized = {} + def customize_grammar_rules(self, tokens, customize): + super(Python14Parser, self).customize_grammar_rules(tokens, customize) + self.remove_rules(""" + whileelsestmt ::= SETUP_LOOP testexpr l_stmts_opt + jb_pop + POP_BLOCK else_suitel COME_FROM + """) + self.check_reduce['doc_junk'] = 'tokens' + + + def reduce_is_invalid(self, rule, ast, tokens, first, last): + invalid = super(Python14Parser, + self).reduce_is_invalid(rule, ast, + tokens, first, last) + if invalid or tokens is None: + return invalid + if rule[0] == 'doc_junk': + return not isinstance(tokens[first].pattr, str) + + class Python14ParserSingle(Python14Parser, PythonParserSingle): pass diff --git a/uncompyle6/parsers/parse15.py b/uncompyle6/parsers/parse15.py index 159653a0..d6e4a811 100644 --- a/uncompyle6/parsers/parse15.py +++ b/uncompyle6/parsers/parse15.py @@ -2,7 +2,7 @@ # Copyright (c) 2000-2002 by hartmut Goebel from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG -from uncompyle6.parser import PythonParserSingle +from uncompyle6.parser import PythonParserSingle, nop_func from uncompyle6.parsers.parse21 import Python21Parser class Python15Parser(Python21Parser): @@ -23,6 +23,17 @@ class Python15Parser(Python21Parser): importlist ::= IMPORT_FROM """ + def customize_grammar_rules(self, tokens, customize): + super(Python15Parser, self).customize_grammar_rules(tokens, customize) + for i, token in enumerate(tokens): + opname = token.kind + opname_base = opname[:opname.rfind('_')] + + if opname_base == 'UNPACK_LIST': + self.addRule("store ::= unpack_list", nop_func) + + + class Python15ParserSingle(Python15Parser, PythonParserSingle): pass diff --git a/uncompyle6/parsers/parse2.py b/uncompyle6/parsers/parse2.py index 3064cf35..9a67aa16 100644 --- a/uncompyle6/parsers/parse2.py +++ b/uncompyle6/parsers/parse2.py @@ -294,7 +294,6 @@ class Python2Parser(PythonParser): # The order of opname listed is roughly sorted below if opname_base in ('BUILD_LIST', 'BUILD_SET', 'BUILD_TUPLE'): - v = token.attr collection = opname_base[opname_base.find('_')+1:].lower() rule = '%s ::= %s%s' % (collection, (token.attr * 'expr '), opname) self.add_unique_rules([ @@ -395,7 +394,6 @@ class Python2Parser(PythonParser): """, nop_func) continue elif opname == 'JUMP_IF_NOT_DEBUG': - v = token.attr self.addRule(""" jmp_true_false ::= POP_JUMP_IF_TRUE jmp_true_false ::= POP_JUMP_IF_FALSE diff --git a/uncompyle6/scanners/scanner15.py b/uncompyle6/scanners/scanner15.py index eb2525c6..1b3c62e3 100644 --- a/uncompyle6/scanners/scanner15.py +++ b/uncompyle6/scanners/scanner15.py @@ -25,3 +25,17 @@ class Scanner15(scan.Scanner21): self.version = 1.5 self.genexpr_name = '' return + + def ingest(self, co, classname=None, code_objects={}, show_asm=None): + """ + Pick out tokens from an uncompyle6 code object, and transform them, + returning a list of uncompyle6 Token's. + + The transformations are made to assist the deparsing grammar. + """ + tokens, customize = scan.Scanner21.ingest(self, co, classname, code_objects, show_asm) + for t in tokens: + if t.op == self.opc.UNPACK_LIST: + t.kind = 'UNPACK_LIST_%d' % t.attr + pass + return tokens, customize