From 3ef4ab4944a6f19eba40a179552d2c23e25eac56 Mon Sep 17 00:00:00 2001 From: rocky Date: Sat, 17 Feb 2024 12:57:48 -0500 Subject: [PATCH] Prefer using double quote for strings --- uncompyle6/scanner.py | 23 ++++++----------------- uncompyle6/scanners/scanner3.py | 4 +++- uncompyle6/scanners/scanner37base.py | 3 ++- uncompyle6/semantics/n_actions.py | 1 + 4 files changed, 12 insertions(+), 19 deletions(-) diff --git a/uncompyle6/scanner.py b/uncompyle6/scanner.py index ee3e73bd..1cee9130 100644 --- a/uncompyle6/scanner.py +++ b/uncompyle6/scanner.py @@ -597,25 +597,14 @@ class Scanner: return self.Token -# TODO: after the next xdis release, use from there instead. -def parse_fn_counts_30_35(argc: int) -> Tuple[int, int, int]: +def prefer_double_quote(string: str) -> str: """ - In Python 3.0 to 3.5 MAKE_CLOSURE and MAKE_FUNCTION encode - arguments counts of positional, default + named, and annotation - arguments a particular kind of encoding where each of - the entry a a packed byted value of the lower 24 bits - of ``argc``. The high bits of argc may have come from - an EXTENDED_ARG instruction. Here, we unpack the values - from the ``argc`` int and return a triple of the - positional args, named_args, and annotation args. + Prefer a double quoted string over a + single quoted string when possible """ - annotate_count = (argc >> 16) & 0x7FFF - # For some reason that I don't understand, annotate_args is off by one - # when there is an EXENDED_ARG instruction from what is documented in - # https://docs.python.org/3.4/library/dis.html#opcode-MAKE_CLOSURE - if annotate_count > 1: - annotate_count -= 1 - return ((argc & 0xFF), (argc >> 8) & 0xFF, annotate_count) + if string.find("'") == -1: + return f'"{string}"' + return str(string) def get_scanner(version: Union[str, tuple], is_pypy=False, show_asm=None) -> Scanner: diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index 4b871c52..7058cbac 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -44,8 +44,9 @@ import xdis import xdis.opcodes.opcode_33 as op3 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, parse_fn_counts_30_35 +from uncompyle6.scanner import CONST_COLLECTIONS, Scanner, prefer_double_quote from uncompyle6.scanners.tok import Token from uncompyle6.util import get_code_name @@ -611,6 +612,7 @@ class Scanner3(Scanner): pattr = "" elif isinstance(const, str): opname = "LOAD_STR" + pattr = prefer_double_quote(inst.argval) 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 01ded28a..257fc79f 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 +from uncompyle6.scanner import Scanner, Token, prefer_double_quote globals().update(op3.opmap) @@ -386,6 +386,7 @@ class Scanner37Base(Scanner): pattr = "" elif isinstance(const, str): opname = "LOAD_STR" + pattr = prefer_double_quote(inst.argval) 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/semantics/n_actions.py b/uncompyle6/semantics/n_actions.py index 2c3a6b69..ea7a923b 100644 --- a/uncompyle6/semantics/n_actions.py +++ b/uncompyle6/semantics/n_actions.py @@ -39,6 +39,7 @@ class NonterminalActions: # parenthesis surrounding it. A high value indicates no # parenthesis are needed. self.prec = 1000 + self.in_format_string = False def n_alias(self, node): if self.version <= (2, 1):