diff --git a/test/bytecode_2.7_run/05_string_constants.pyc b/test/bytecode_2.7_run/05_string_constants.pyc new file mode 100644 index 000000000..0bc8f9e13 Binary files /dev/null and b/test/bytecode_2.7_run/05_string_constants.pyc differ diff --git a/test/bytecode_3.6_run/05_string_constants.pyc b/test/bytecode_3.6_run/05_string_constants.pyc new file mode 100644 index 000000000..70d68321e Binary files /dev/null and b/test/bytecode_3.6_run/05_string_constants.pyc differ diff --git a/test/simple_source/bug27+/05_string_constants.py b/test/simple_source/bug27+/05_string_constants.py new file mode 100644 index 000000000..453a90161 --- /dev/null +++ b/test/simple_source/bug27+/05_string_constants.py @@ -0,0 +1,13 @@ +# See https://github.com/rocky/python-uncompyle6/issues/528 +# RUNNABLE! + +"""This program is self-checking!""" + +x = 1 +L = [239, 168, 254, 54, 235, 128, "fred"] +D = {239: 240, 168:169, 54:55, 128:129, "fred":"wilma"} +S = {239, 168, 254, 54, 235, 128, "fred"} + +assert L[6] == "fred" +assert "fred" in S +assert D["fred"] == "wilma" diff --git a/uncompyle6/semantics/n_actions.py b/uncompyle6/semantics/n_actions.py index 9234cea0f..8addb26f7 100644 --- a/uncompyle6/semantics/n_actions.py +++ b/uncompyle6/semantics/n_actions.py @@ -206,6 +206,22 @@ def n_classdef(self, node: SyntaxTree): n_classdefdeco2 = n_classdef + def format_const(self, elem): + """ + Render one constant collection element (ADD_VALUE) to source text. + + On 3.x the scanner already stores the element's source form (its + argrepr) in pattr, so emit that directly. On 2.x pattr holds the raw + value, so format it the way n_LOAD_CONST does. elem.attr is the + co_consts index on 2.x and must never be emitted as the value. + """ + if self.version >= (3, 0): + return elem.pattr + data = elem.pattr + if isinstance(data, (float, complex)): + return better_repr(data, self.version) + return repr(data) + def n_const_list(self, node: SyntaxTree): """ prettyprint a constant dict, list, set or tuple. @@ -242,13 +258,10 @@ def n_const_list(self, node: SyntaxTree): assert elem.kind == "ADD_VALUE" if elem.optype in ("local", "name"): value = elem.attr - elif elem.optype == "const" and not isinstance(elem.attr, str): - value = elem.attr + elif elem.optype == "const": + value = self.format_const(elem) else: - try: - value = "%r" % elem.pattr - except Exception: - value = elem.pattr + value = elem.pattr if elem.linestart is not None: if elem.linestart != self.line_number: next_indent = self.indent + INDENT_PER_LEVEL[:-1] @@ -276,7 +289,7 @@ def n_const_list(self, node: SyntaxTree): if elem.optype in ("local", "name"): value = elem.attr elif elem.optype == "const": - value = elem.pattr + value = self.format_const(elem) else: value = "%s" % repr(elem.attr) else: