You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 08:49:51 +08:00
Fix Python 1.5- bug in handling unpack list
This commit is contained in:
BIN
test/bytecode_1.4/02_continue.pyc
Normal file
BIN
test/bytecode_1.4/02_continue.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_1.4/test_del.pyc
Normal file
BIN
test/bytecode_1.4/test_del.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_1.5/00_unpack_list.pyc
Normal file
BIN
test/bytecode_1.5/00_unpack_list.pyc
Normal file
Binary file not shown.
3
test/simple_source/bug14/00_unpack_list.py
Normal file
3
test/simple_source/bug14/00_unpack_list.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Python 1.4 tzparse.py, but also appears in 1.5
|
||||||
|
|
||||||
|
[tzname, delta] = __file__
|
@@ -13,6 +13,7 @@ class Python14Parser(Python15Parser):
|
|||||||
# SET_FUNC_ARGS, and RESERVE_FAST
|
# SET_FUNC_ARGS, and RESERVE_FAST
|
||||||
|
|
||||||
# FIXME: should check that this indeed around __doc__
|
# FIXME: should check that this indeed around __doc__
|
||||||
|
# Possibly not strictly needed
|
||||||
stmt ::= doc_junk
|
stmt ::= doc_junk
|
||||||
doc_junk ::= LOAD_CONST POP_TOP
|
doc_junk ::= LOAD_CONST POP_TOP
|
||||||
|
|
||||||
@@ -35,6 +36,26 @@ class Python14Parser(Python15Parser):
|
|||||||
super(Python14Parser, self).__init__(debug_parser)
|
super(Python14Parser, self).__init__(debug_parser)
|
||||||
self.customized = {}
|
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):
|
class Python14ParserSingle(Python14Parser, PythonParserSingle):
|
||||||
pass
|
pass
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
# Copyright (c) 2000-2002 by hartmut Goebel <hartmut@goebel.noris.de>
|
# Copyright (c) 2000-2002 by hartmut Goebel <hartmut@goebel.noris.de>
|
||||||
|
|
||||||
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
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
|
from uncompyle6.parsers.parse21 import Python21Parser
|
||||||
|
|
||||||
class Python15Parser(Python21Parser):
|
class Python15Parser(Python21Parser):
|
||||||
@@ -23,6 +23,17 @@ class Python15Parser(Python21Parser):
|
|||||||
importlist ::= IMPORT_FROM
|
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):
|
class Python15ParserSingle(Python15Parser, PythonParserSingle):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@@ -294,7 +294,6 @@ class Python2Parser(PythonParser):
|
|||||||
|
|
||||||
# The order of opname listed is roughly sorted below
|
# The order of opname listed is roughly sorted below
|
||||||
if opname_base in ('BUILD_LIST', 'BUILD_SET', 'BUILD_TUPLE'):
|
if opname_base in ('BUILD_LIST', 'BUILD_SET', 'BUILD_TUPLE'):
|
||||||
v = token.attr
|
|
||||||
collection = opname_base[opname_base.find('_')+1:].lower()
|
collection = opname_base[opname_base.find('_')+1:].lower()
|
||||||
rule = '%s ::= %s%s' % (collection, (token.attr * 'expr '), opname)
|
rule = '%s ::= %s%s' % (collection, (token.attr * 'expr '), opname)
|
||||||
self.add_unique_rules([
|
self.add_unique_rules([
|
||||||
@@ -395,7 +394,6 @@ class Python2Parser(PythonParser):
|
|||||||
""", nop_func)
|
""", nop_func)
|
||||||
continue
|
continue
|
||||||
elif opname == 'JUMP_IF_NOT_DEBUG':
|
elif opname == 'JUMP_IF_NOT_DEBUG':
|
||||||
v = token.attr
|
|
||||||
self.addRule("""
|
self.addRule("""
|
||||||
jmp_true_false ::= POP_JUMP_IF_TRUE
|
jmp_true_false ::= POP_JUMP_IF_TRUE
|
||||||
jmp_true_false ::= POP_JUMP_IF_FALSE
|
jmp_true_false ::= POP_JUMP_IF_FALSE
|
||||||
|
@@ -25,3 +25,17 @@ class Scanner15(scan.Scanner21):
|
|||||||
self.version = 1.5
|
self.version = 1.5
|
||||||
self.genexpr_name = '<generator expression>'
|
self.genexpr_name = '<generator expression>'
|
||||||
return
|
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
|
||||||
|
Reference in New Issue
Block a user