diff --git a/uncompyle6/bin/uncompile.py b/uncompyle6/bin/uncompile.py index b7177d22..5bc6bd40 100755 --- a/uncompyle6/bin/uncompile.py +++ b/uncompyle6/bin/uncompile.py @@ -15,8 +15,8 @@ from typing import List import click from xdis.version_info import version_tuple_to_str -from uncompyle6 import verify from uncompyle6.main import main, status_msg +from uncompyle6.verify import VerifyCmpError from uncompyle6.version import __version__ program = "uncompyle6" @@ -245,7 +245,7 @@ def main_bin( sys.exit(2) except KeyboardInterrupt: pass - except verify.VerifyCmpError: + except VerifyCmpError: raise else: from multiprocessing import Process, Queue @@ -266,18 +266,18 @@ def main_bin( tot_files = okay_files = failed_files = verify_failed_files = 0 def process_func(): + (tot_files, okay_files, failed_files, verify_failed_files) = ( + 0, + 0, + 0, + 0, + ) try: - (tot_files, okay_files, failed_files, verify_failed_files) = ( - 0, - 0, - 0, - 0, - ) while 1: f = fqueue.get() if f is None: break - (t, o, f, v) = main(src_base, out_base, [f], [], outfile, **options) + (t, o, f, v) = main(src_base, out_base, [f], [], outfile) tot_files += t okay_files += o failed_files += f diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index f25ae5d7..969d9109 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2023 Rocky Bernstein +# Copyright (c) 2015-2024 Rocky Bernstein # Copyright (c) 2005 by Dan Pascu # Copyright (c) 2000-2002 by hartmut Goebel # Copyright (c) 1999 John Aycock @@ -1221,9 +1221,24 @@ class Python3Parser(PythonParser): ) ) else: - rule = "mkfunc ::= %s%sload_closure LOAD_CODE LOAD_STR %s" % ( - kwargs_str, - "pos_arg " * pos_args_count, + if self.version == (3, 3): + # 3.3 puts kwargs before pos_arg + pos_kw_tuple = ( + ("kwargs " * kw_args_count), + ("pos_arg " * pos_args_count), + ) + else: + # 3.4 and 3.5 puts pos_arg before kwargs + pos_kw_tuple = ( + "pos_arg " * (pos_args_count), + ("kwargs " * kw_args_count), + ) + rule = ( + "mkfunc ::= %s%s%s " "load_closure LOAD_CODE LOAD_STR %s" + ) % ( + pos_kw_tuple[0], + pos_kw_tuple[1], + "annotate_pair " * (annotate_args), opname, ) self.add_unique_rule(rule, opname, token.attr, customize) @@ -1465,12 +1480,12 @@ class Python3Parser(PythonParser): ) self.add_unique_rule(rule, opname, token.attr, customize) rule = ( - "mkfunc_annotate ::= %s%sannotate_tuple LOAD_CODE LOAD_STR %s" - % ( - ("pos_arg " * pos_args_count), - ("annotate_arg " * annotate_args), - opname, - ) + "mkfunc_annotate ::= %s%sannotate_tuple LOAD_CODE " + "LOAD_STR %s" + ) % ( + ("pos_arg " * pos_args_count), + ("annotate_arg " * annotate_args), + opname, ) if self.version >= (3, 3): if self.version == (3, 3): @@ -1480,29 +1495,19 @@ class Python3Parser(PythonParser): ("pos_arg " * pos_args_count), ) else: - # 3.4 and 3.5puts pos_arg before kwargs + # 3.4 and 3.5 puts pos_arg before kwargs pos_kw_tuple = ( "pos_arg " * (pos_args_count), ("kwargs " * kw_args_count), ) rule = ( - "mkfunc_annotate ::= %s%s%sannotate_tuple LOAD_CODE LOAD_STR %s" - % ( - pos_kw_tuple[0], - pos_kw_tuple[1], - ("annotate_arg " * annotate_args), - opname, - ) - ) - self.add_unique_rule(rule, opname, token.attr, customize) - rule = ( - "mkfunc_annotate ::= %s%s%sannotate_tuple LOAD_CODE LOAD_STR %s" - % ( - pos_kw_tuple[0], - pos_kw_tuple[1], - ("annotate_arg " * annotate_args), - opname, - ) + "mkfunc_annotate ::= %s%s%sannotate_tuple LOAD_CODE " + "LOAD_STR %s" + ) % ( + pos_kw_tuple[0], + pos_kw_tuple[1], + ("annotate_arg " * annotate_args), + opname, ) else: rule = ( diff --git a/uncompyle6/parsers/parse33.py b/uncompyle6/parsers/parse33.py index ce1fc672..fd3a888f 100644 --- a/uncompyle6/parsers/parse33.py +++ b/uncompyle6/parsers/parse33.py @@ -16,6 +16,12 @@ class Python33Parser(Python32Parser): stmt ::= genexpr_func """ + def p_33_function_def(self, args): + """ + annotate_pair ::= LOAD_NAME LOAD_CONST + + """ + def customize_grammar_rules(self, tokens, customize): self.remove_rules( """ diff --git a/uncompyle6/scanners/scanner35.py b/uncompyle6/scanners/scanner35.py index 9af3aaed..52a82572 100644 --- a/uncompyle6/scanners/scanner35.py +++ b/uncompyle6/scanners/scanner35.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017, 2021-2022 by Rocky Bernstein +# Copyright (c) 2017, 2021-2022, 2024 by Rocky Bernstein # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -22,21 +22,22 @@ This sets up opcodes Python's 3.5 and calls a generalized scanner routine for Python 3. """ -from __future__ import print_function +# bytecode verification, verify(), uses JUMP_OPs from here +from xdis.opcodes import opcode_35 as opc from uncompyle6.scanners.scanner3 import Scanner3 -# bytecode verification, verify(), uses JUMP_OPs from here -from xdis.opcodes import opcode_35 as opc JUMP_OPS = opc.JUMP_OPS -class Scanner35(Scanner3): +class Scanner35(Scanner3): def __init__(self, show_asm=None, is_pypy=False): Scanner3.__init__(self, (3, 5), show_asm, is_pypy) return + pass + if __name__ == "__main__": from xdis.version_info import PYTHON_VERSION_TRIPLE, version_tuple_to_str diff --git a/uncompyle6/scanners/scanner37base.py b/uncompyle6/scanners/scanner37base.py index 93a834fb..01ded28a 100644 --- a/uncompyle6/scanners/scanner37base.py +++ b/uncompyle6/scanners/scanner37base.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020, 2022-2023 by Rocky Bernstein +# Copyright (c) 2015-2020, 2022-2024 by Rocky Bernstein # Copyright (c) 2005 by Dan Pascu # Copyright (c) 2000-2002 by hartmut Goebel # @@ -15,7 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . """ -Python 37 bytecode scanner/deparser base. +Python 3.7 bytecode scanner/deparser base. Also we *modify* the instruction sequence to assist deparsing code. For example: @@ -29,20 +29,17 @@ For example: Finally we save token information. """ +import sys from typing import Any, Dict, List, Set, Tuple -from xdis import iscode, instruction_size, Instruction -from xdis.bytecode import _get_const_info - -from uncompyle6.scanner import Token import xdis # Get all the opcodes into globals import xdis.opcodes.opcode_37 as op3 +from xdis import Instruction, instruction_size, iscode +from xdis.bytecode import _get_const_info -from uncompyle6.scanner import Scanner - -import sys +from uncompyle6.scanner import Scanner, Token globals().update(op3.opmap) @@ -51,7 +48,9 @@ CONST_COLLECTIONS = ("CONST_LIST", "CONST_SET", "CONST_DICT") class Scanner37Base(Scanner): - def __init__(self, version: Tuple[int, int], show_asm=None, debug="", is_pypy=False): + def __init__( + self, version: Tuple[int, int], show_asm=None, debug="", is_pypy=False + ): super(Scanner37Base, self).__init__(version, show_asm, is_pypy) self.offset2tok_index = None self.debug = debug @@ -254,7 +253,6 @@ class Scanner37Base(Scanner): n = len(self.insts) for i, inst in enumerate(self.insts): - # We need to detect the difference between: # raise AssertionError # and @@ -284,7 +282,6 @@ class Scanner37Base(Scanner): # To simplify things we want to untangle this. We also # do this loop before we compute jump targets. for i, inst in enumerate(self.insts): - # One artifact of the "too-small" operand problem, is that # some backward jumps, are turned into forward jumps to another # "extended arg" backward jump to the same location. @@ -321,16 +318,9 @@ class Scanner37Base(Scanner): j = 0 for i, inst in enumerate(self.insts): - argval = inst.argval op = inst.opcode - if inst.opname == "EXTENDED_ARG": - # FIXME: The EXTENDED_ARG is used to signal annotation - # parameters - if i + 1 < n and self.insts[i + 1].opcode != self.opc.MAKE_FUNCTION: - continue - if inst.offset in jump_targets: jump_idx = 0 # We want to process COME_FROMs to the same offset to be in *descending*