From 078f15013e31614335b9f28fe431edb987b25853 Mon Sep 17 00:00:00 2001 From: rocky Date: Mon, 20 Jun 2016 00:32:00 -0400 Subject: [PATCH] Python 3.x class decorator bug --- test/bytecode_3.4/10_class_deco.pyc | Bin 0 -> 332 bytes test/simple_source/def/10_class_deco.py | 6 ++++++ uncompyle6/parsers/parse3.py | 2 +- uncompyle6/semantics/fragments.py | 21 ++++++++++++++++----- uncompyle6/semantics/pysource.py | 11 ++++++++--- 5 files changed, 31 insertions(+), 9 deletions(-) create mode 100644 test/bytecode_3.4/10_class_deco.pyc create mode 100644 test/simple_source/def/10_class_deco.py diff --git a/test/bytecode_3.4/10_class_deco.pyc b/test/bytecode_3.4/10_class_deco.pyc new file mode 100644 index 0000000000000000000000000000000000000000..93a5f67d7b7296e887aa337e995293575c51c283 GIT binary patch literal 332 zcmYLEu};G<5IsAs2vtD+2DS`Pm|LMvu(5PNVmU>&Q&n=})=mcI@-zIBS0)xdfQjcs zEhpd8^S!%w_D^v&TOPKrH4%Lw&oKd8Bf~8~;|Q`uji5I{!U%fSl5|ENP%=77IzmBZ zLYs2>jS(tEyzX3AS$19f4lc)@(=D?2Km 3.0: - currentclass = node[1][0].pattr - buildclass = node[0] + if node == 'classdefdeco2': + currentclass = node[1][2].pattr + buildclass = node + else: + currentclass = node[1][0].pattr + buildclass = node[0] + if buildclass[0] == 'LOAD_BUILD_CLASS': start = len(self.f.getvalue()) self.set_pos_info(buildclass[0], start, start + len('class')+2) if buildclass[1][0] == 'kwargs': subclass = buildclass[1][1].attr - subclass_info = node[0] + subclass_info = node if node == 'classdefdeco2' else node[0] elif buildclass[1][0] == 'load_closure': # Python 3 with closures not functions load_closure = buildclass[1] @@ -762,7 +767,7 @@ class FragmentsWalker(pysource.SourceWalker, object): subclass = buildclass[1][0].attr subclass_info = node[0] else: - buildclass = node[0] + buildclass = node if (node == 'classdefdeco2') else node[0] build_list = buildclass[1][0] if hasattr(buildclass[-3][0], 'attr'): subclass = buildclass[-3][0].attr @@ -773,7 +778,11 @@ class FragmentsWalker(pysource.SourceWalker, object): else: raise 'Internal Error n_classdef: cannot find class name' - self.write('\n\n') + if (node == 'classdefdeco2'): + self.write('\n') + else: + self.write('\n\n') + self.currentclass = str(currentclass) start = len(self.f.getvalue()) self.write(self.indent, 'class ', self.currentclass) @@ -798,6 +807,8 @@ class FragmentsWalker(pysource.SourceWalker, object): self.prune() + n_classdefdeco2 = n_classdef + def gen_source(self, ast, name, customize, isLambda=False, returnNone=False): """convert AST to Python source code""" diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 09170b4f..028168a5 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -1187,11 +1187,16 @@ class SourceWalker(GenericASTTraversal, object): cclass = self.currentclass if self.version > 3.0: - currentclass = node[1][0].pattr - buildclass = node[0] + if node == 'classdefdeco2': + currentclass = node[1][2].pattr + buildclass = node + else: + currentclass = node[1][0].pattr + buildclass = node[0] + if buildclass[1][0] == 'kwargs': subclass = buildclass[1][1].attr - subclass_info = node[0] + subclass_info = node if node == 'classdefdeco2' else node[0] elif buildclass[1][0] == 'load_closure': # Python 3 with closures not functions load_closure = buildclass[1]