From 0a08b8d3fc06d091ce1e25490df026105ce0e1fb Mon Sep 17 00:00:00 2001 From: rocky Date: Sat, 17 Feb 2024 19:46:57 -0500 Subject: [PATCH 1/6] Simplify double quote preference in string --- uncompyle6/scanner.py | 8 ++++---- uncompyle6/scanners/scanner3.py | 2 +- uncompyle6/scanners/scanner37base.py | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/uncompyle6/scanner.py b/uncompyle6/scanner.py index 474856e5..46124aec 100644 --- a/uncompyle6/scanner.py +++ b/uncompyle6/scanner.py @@ -24,7 +24,7 @@ scanners, e.g. for Python 2.7 or 3.4. from array import array from collections import namedtuple from types import ModuleType -from typing import Optional, Tuple, Union +from typing import Optional, Union import xdis from xdis import ( @@ -654,9 +654,9 @@ def prefer_double_quote(string: str) -> str: Prefer a double quoted string over a single quoted string when possible """ - if string.find("'") == -1: - return f'"{string}"' - return repr(string) + if string.find("'") == -1 and not string.startswith("'''"): + return f'"{string[1:-2]}"' + return string if __name__ == "__main__": diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index 7058cbac..6f8533e9 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -612,7 +612,7 @@ class Scanner3(Scanner): pattr = "" elif isinstance(const, str): opname = "LOAD_STR" - pattr = prefer_double_quote(inst.argval) + pattr = prefer_double_quote(inst.argrepr) else: if isinstance(inst.arg, int) and inst.arg < len(co.co_consts): argval, _ = _get_const_info(inst.arg, co.co_consts) diff --git a/uncompyle6/scanners/scanner37base.py b/uncompyle6/scanners/scanner37base.py index 257fc79f..69e010ea 100644 --- a/uncompyle6/scanners/scanner37base.py +++ b/uncompyle6/scanners/scanner37base.py @@ -386,7 +386,7 @@ class Scanner37Base(Scanner): pattr = "" elif isinstance(const, str): opname = "LOAD_STR" - pattr = prefer_double_quote(inst.argval) + pattr = prefer_double_quote(inst.argrepr) else: if isinstance(inst.arg, int) and inst.arg < len(co.co_consts): argval, _ = _get_const_info(inst.arg, co.co_consts) From 8c3143ce4ca689cd335d862fe80d04f0ca5cb64e Mon Sep 17 00:00:00 2001 From: rocky Date: Sat, 17 Feb 2024 20:14:30 -0500 Subject: [PATCH 2/6] Sync with decompyle3 --- uncompyle6/semantics/pysource.py | 44 ++++++++++++++++---------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index f2bf4357..31dc542a 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -134,7 +134,7 @@ from io import StringIO from typing import Optional from spark_parser import GenericASTTraversal -from xdis import COMPILER_FLAG_BIT, iscode +from xdis import COMPILER_FLAG_BIT, IS_PYPY, iscode from xdis.version_info import PYTHON_VERSION_TRIPLE from uncompyle6.parser import get_python_parser, parse @@ -149,6 +149,7 @@ from uncompyle6.semantics.consts import ( MAP, MAP_DIRECT, NAME_MODULE, + NO_PARENTHESIS_EVER, NONE, PASS, PRECEDENCE, @@ -189,8 +190,6 @@ PARSER_DEFAULT_DEBUG = { "dups": False, } -IS_PYPY = "__pypy__" in sys.builtin_module_names - TREE_DEFAULT_DEBUG = {"before": False, "after": False} DEFAULT_DEBUG_OPTS = { @@ -210,7 +209,7 @@ class SourceWalkerError(Exception): class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin): """ - Class to traverses a Parse Tree of the bytecode instruction built from parsing to + Class to traverse a Parse Tree of the bytecode instruction built from parsing to produce some sort of source text. The Parse tree may be turned an Abstract Syntax tree as an intermediate step. """ @@ -267,27 +266,32 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin): is_pypy=is_pypy, ) - self.ast_errors = [] - self.currentclass = None - self.classes = [] - self.debug_parser = dict(debug_parser) - self.line_number = 1 - self.linemap = {} - self.params = params - self.param_stack = [] self.ERROR = None - self.prec = 100 - self.return_none = False - self.mod_globs = set() - self.showast = showast - self.pending_newlines = 0 + self.ast_errors = [] + self.classes = [] + self.compile_mode = compile_mode + self.currentclass = None + self.debug_parser = dict(debug_parser) + self.is_pypy = is_pypy + self.linemap = {} + self.line_number = 1 self.linestarts = linestarts + self.mod_globs = set() + self.name = None + self.offset2inst_index = scanner.offset2inst_index + self.param_stack = [] + self.params = params + self.pending_newlines = 0 + self.prec = NO_PARENTHESIS_EVER + self.return_none = False + self.showast = showast + self.version = version + self.treeTransform = TreeTransform(version=self.version, show_ast=showast) # FIXME: have p.insts update in a better way # modularity is broken here self.insts = scanner.insts - self.offset2inst_index = scanner.offset2inst_index # Initialize p_lambda on demand self.p_lambda = None @@ -312,10 +316,6 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin): # An example is: # __module__ = __name__ self.hide_internal = True - self.compile_mode = compile_mode - self.name = None - self.version = version - self.is_pypy = is_pypy customize_for_version(self, is_pypy, version) return From 40c476449283f501ed1d3f63b85b07ab9bdefd59 Mon Sep 17 00:00:00 2001 From: rocky Date: Sat, 17 Feb 2024 20:37:12 -0500 Subject: [PATCH 3/6] prefer string double quote, yet again. --- uncompyle6/scanner.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/uncompyle6/scanner.py b/uncompyle6/scanner.py index 46124aec..87c42bf9 100644 --- a/uncompyle6/scanner.py +++ b/uncompyle6/scanner.py @@ -654,8 +654,8 @@ def prefer_double_quote(string: str) -> str: Prefer a double quoted string over a single quoted string when possible """ - if string.find("'") == -1 and not string.startswith("'''"): - return f'"{string[1:-2]}"' + if string[1:-1].find('"') == -1: + return f'"{string[1:-1]}"' return string From 3e00880c1b7018ac651988bb138247baa339e0df Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 18 Feb 2024 08:21:07 -0500 Subject: [PATCH 4/6] remove double-quote preference here.... it is now done in xdis which is where it is better done --- uncompyle6/scanner.py | 10 ---------- uncompyle6/scanners/scanner3.py | 3 +-- uncompyle6/scanners/scanner37base.py | 3 +-- 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/uncompyle6/scanner.py b/uncompyle6/scanner.py index 87c42bf9..d6651836 100644 --- a/uncompyle6/scanner.py +++ b/uncompyle6/scanner.py @@ -649,16 +649,6 @@ def get_scanner(version: Union[str, tuple], is_pypy=False, show_asm=None) -> Sca return scanner -def prefer_double_quote(string: str) -> str: - """ - Prefer a double quoted string over a - single quoted string when possible - """ - if string[1:-1].find('"') == -1: - return f'"{string[1:-1]}"' - return string - - if __name__ == "__main__": import inspect diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index 6f8533e9..5ac4ab55 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -46,7 +46,7 @@ from xdis import Instruction, instruction_size, iscode from xdis.bytecode import _get_const_info from xdis.opcodes.opcode_3x import parse_fn_counts_30_35 -from uncompyle6.scanner import CONST_COLLECTIONS, Scanner, prefer_double_quote +from uncompyle6.scanner import CONST_COLLECTIONS, Scanner from uncompyle6.scanners.tok import Token from uncompyle6.util import get_code_name @@ -612,7 +612,6 @@ class Scanner3(Scanner): pattr = "" elif isinstance(const, str): opname = "LOAD_STR" - pattr = prefer_double_quote(inst.argrepr) else: if isinstance(inst.arg, int) and inst.arg < len(co.co_consts): argval, _ = _get_const_info(inst.arg, co.co_consts) diff --git a/uncompyle6/scanners/scanner37base.py b/uncompyle6/scanners/scanner37base.py index 69e010ea..01ded28a 100644 --- a/uncompyle6/scanners/scanner37base.py +++ b/uncompyle6/scanners/scanner37base.py @@ -39,7 +39,7 @@ 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, Token, prefer_double_quote +from uncompyle6.scanner import Scanner, Token globals().update(op3.opmap) @@ -386,7 +386,6 @@ class Scanner37Base(Scanner): pattr = "" elif isinstance(const, str): opname = "LOAD_STR" - pattr = prefer_double_quote(inst.argrepr) else: if isinstance(inst.arg, int) and inst.arg < len(co.co_consts): argval, _ = _get_const_info(inst.arg, co.co_consts) From 1ef631dd761f7fb4e2b64cace50c0b66f4efaf3a Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 18 Feb 2024 21:13:30 -0500 Subject: [PATCH 5/6] Track change in xdis Instruction ... we now need to set positions which will be used in newer Pythons. --- uncompyle6/scanners/scanner37base.py | 36 +++++++++++++++------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/uncompyle6/scanners/scanner37base.py b/uncompyle6/scanners/scanner37base.py index 01ded28a..61268cd7 100644 --- a/uncompyle6/scanners/scanner37base.py +++ b/uncompyle6/scanners/scanner37base.py @@ -293,20 +293,21 @@ class Scanner37Base(Scanner): # but the operator and operand properties come from the other # instruction self.insts[i] = Instruction( - jump_inst.opname, - jump_inst.opcode, - jump_inst.optype, - jump_inst.inst_size, - jump_inst.arg, - jump_inst.argval, - jump_inst.argrepr, - jump_inst.has_arg, - inst.offset, - inst.starts_line, - inst.is_jump_target, - inst.has_extended_arg, - None, - None, + opcode=jump_inst.opcode, + opname=jump_inst.opname, + arg=jump_inst.arg, + argval=jump_inst.argval, + argrepr=jump_inst.argrepr, + offset=inst.offset, + starts_line=inst.starts_line, + is_jump_target=inst.is_jump_target, + positions=None, + optype=jump_inst.optype, + has_arg=jump_inst.has_arg, + inst_size=jump_inst.inst_size, + has_extended_arg=inst.has_extended_arg, + tos_str=None, + start_offset=None, ) # Get jump targets @@ -939,7 +940,7 @@ class Scanner37Base(Scanner): if __name__ == "__main__": from xdis.version_info import PYTHON_VERSION_TRIPLE, version_tuple_to_str - if PYTHON_VERSION_TRIPLE[:2] == (3, 7): + if (3, 7) <= PYTHON_VERSION_TRIPLE[:2] < (3, 9): import inspect co = inspect.currentframe().f_code # type: ignore @@ -948,5 +949,8 @@ if __name__ == "__main__": for t in tokens: print(t) else: - print(f"Need to be Python 3.7 to demo; I am version {version_tuple_to_str()}.") + print( + "Need to be Python 3.7..3.8 to demo; " + f"I am version {version_tuple_to_str()}." + ) pass From e77ccba40e3fa73392fd9867baf0dc4c7251ceb7 Mon Sep 17 00:00:00 2001 From: rocky Date: Sat, 24 Feb 2024 07:15:47 -0500 Subject: [PATCH 6/6] Merge hell --- uncompyle6/scanners/scanner37base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/uncompyle6/scanners/scanner37base.py b/uncompyle6/scanners/scanner37base.py index c6b5936f..4bdcd831 100644 --- a/uncompyle6/scanners/scanner37base.py +++ b/uncompyle6/scanners/scanner37base.py @@ -303,6 +303,7 @@ class Scanner37Base(Scanner): has_arg=jump_inst.has_arg, inst_size=jump_inst.inst_size, has_extended_arg=inst.has_extended_arg, + fallthrough=False, tos_str=None, start_offset=None, )