diff --git a/test/Makefile b/test/Makefile index c8024f7f..155a28bb 100644 --- a/test/Makefile +++ b/test/Makefile @@ -100,7 +100,7 @@ check-bytecode-3: --bytecode-3.1 --bytecode-3.2 --bytecode-3.3 \ --bytecode-3.4 --bytecode-3.5 --bytecode-3.6 \ --bytecode-3.7 --bytecode-3.8 \ - --bytecode-pypy3.2 + --bytecode-pypy3.2 --bytecode-pypy3.6 #: Check deparsing on selected bytecode 3.x check-bytecode-3-short: diff --git a/test/bytecode_3.2/11_classbug.pyc b/test/bytecode_3.2/11_classbug.pyc index 239bf2fc..342ee09b 100644 Binary files a/test/bytecode_3.2/11_classbug.pyc and b/test/bytecode_3.2/11_classbug.pyc differ diff --git a/test/bytecode_3.7/04_class_kwargs.pyc b/test/bytecode_3.7/04_class_kwargs.pyc index 1c095ac6..3cbcb72e 100644 Binary files a/test/bytecode_3.7/04_class_kwargs.pyc and b/test/bytecode_3.7/04_class_kwargs.pyc differ diff --git a/test/bytecode_pypy3.6/04_class_kwargs.pyc b/test/bytecode_pypy3.6/04_class_kwargs.pyc new file mode 100644 index 00000000..0a42c9e9 Binary files /dev/null and b/test/bytecode_pypy3.6/04_class_kwargs.pyc differ diff --git a/uncompyle6/semantics/fragments.py b/uncompyle6/semantics/fragments.py index a297a15c..0a56b850 100644 --- a/uncompyle6/semantics/fragments.py +++ b/uncompyle6/semantics/fragments.py @@ -1453,25 +1453,80 @@ class FragmentsWalker(pysource.SourceWalker, object): # as a custom rule start = len(self.f.getvalue()) n = len(node) - 1 - assert node[n].kind.startswith("CALL_FUNCTION") - for i in range(n - 2, 0, -1): - if not node[i].kind in ["expr", "LOAD_CLASSNAME"]: - break - pass + if node.kind != "expr": + if node == "kwarg": + self.template_engine(("(%[0]{attr}=%c)", 1), node) + return - if i == n - 2: - return - self.write("(") - line_separator = ", " - sep = "" - i += 1 - while i < n: - value = self.traverse(node[i]) - self.node_append(sep, value, node[i]) + kwargs = None + assert node[n].kind.startswith("CALL_FUNCTION") + + if node[n].kind.startswith("CALL_FUNCTION_KW"): + if self.is_pypy: + # FIXME: this doesn't handle positional and keyword args + # properly. Need to do something more like that below + # in the non-PYPY 3.6 case. + self.template_engine(('(%[0]{attr}=%c)', 1), node[n-1]) + return + else: + kwargs = node[n - 1].attr + + assert isinstance(kwargs, tuple) + i = n - (len(kwargs) + 1) + j = 1 + n - node[n].attr + else: + i = start = n - 2 + for i in range(start, 0, -1): + if not node[i].kind in ["expr", "call", "LOAD_CLASSNAME"]: + break + pass + + if i == start: + return + i += 2 + + for i in range(n - 2, 0, -1): + if not node[i].kind in ["expr", "LOAD_CLASSNAME"]: + break + pass + + line_separator = ", " + sep = "" i += 1 - self.write(sep, value) - sep = line_separator + self.write("(") + if kwargs: + # 3.6+ does this + while j < i: + self.write(sep) + value = self.traverse(node[j]) + self.write("%s" % value) + sep = line_separator + j += 1 + + j = 0 + while i < l: + self.write(sep) + value = self.traverse(node[i]) + self.write("%s=%s" % (kwargs[j], value)) + sep = line_separator + j += 1 + i += 1 + else: + while i < l: + value = self.traverse(node[i]) + i += 1 + self.write(sep, value) + sep = line_separator + pass + pass + else: + if self.version >= 3.6 and node[0] == "LOAD_CONST": + return + value = self.traverse(node[0]) + self.write("(") + self.write(value) + pass self.write(")") self.set_pos_info(node, start, len(self.f.getvalue())) diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 19e4f37c..4bc8ba8a 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -1566,8 +1566,6 @@ class SourceWalker(GenericASTTraversal, object): assert node[n].kind.startswith("CALL_FUNCTION") if node[n].kind.startswith("CALL_FUNCTION_KW"): - # 3.6+ starts doing this - kwargs = node[n - 1].attr if self.is_pypy: # FIXME: this doesn't handle positional and keyword args # properly. Need to do something more like that below @@ -1575,7 +1573,7 @@ class SourceWalker(GenericASTTraversal, object): self.template_engine(('(%[0]{attr}=%c)', 1), node[n-1]) return else: - kwargs = node[n-1].attr + kwargs = node[n - 1].attr assert isinstance(kwargs, tuple) i = n - (len(kwargs) + 1)