You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
Python 3.x class decorator bug
This commit is contained in:
BIN
test/bytecode_3.4/10_class_deco.pyc
Normal file
BIN
test/bytecode_3.4/10_class_deco.pyc
Normal file
Binary file not shown.
6
test/simple_source/def/10_class_deco.py
Normal file
6
test/simple_source/def/10_class_deco.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# From 3.4 tracemalloc.py
|
||||||
|
from functools import total_ordering
|
||||||
|
|
||||||
|
@total_ordering
|
||||||
|
class Frame:
|
||||||
|
pass
|
@@ -193,7 +193,7 @@ class Python3Parser(PythonParser):
|
|||||||
classdefdeco ::= classdefdeco1 designator
|
classdefdeco ::= classdefdeco1 designator
|
||||||
classdefdeco1 ::= expr classdefdeco1 CALL_FUNCTION_1
|
classdefdeco1 ::= expr classdefdeco1 CALL_FUNCTION_1
|
||||||
classdefdeco1 ::= expr classdefdeco2 CALL_FUNCTION_1
|
classdefdeco1 ::= expr classdefdeco2 CALL_FUNCTION_1
|
||||||
classdefdeco2 ::= LOAD_CONST expr mkfunc CALL_FUNCTION_0 BUILD_CLASS
|
classdefdeco2 ::= LOAD_BUILD_CLASS mkfunc LOAD_CONST CALL_FUNCTION_2
|
||||||
|
|
||||||
assert ::= assert_expr jmp_true LOAD_ASSERT RAISE_VARARGS_1
|
assert ::= assert_expr jmp_true LOAD_ASSERT RAISE_VARARGS_1
|
||||||
assert2 ::= assert_expr jmp_true LOAD_ASSERT expr CALL_FUNCTION_1 RAISE_VARARGS_1
|
assert2 ::= assert_expr jmp_true LOAD_ASSERT expr CALL_FUNCTION_1 RAISE_VARARGS_1
|
||||||
|
@@ -730,15 +730,20 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
|||||||
cclass = self.currentclass
|
cclass = self.currentclass
|
||||||
|
|
||||||
if self.version > 3.0:
|
if self.version > 3.0:
|
||||||
currentclass = node[1][0].pattr
|
if node == 'classdefdeco2':
|
||||||
buildclass = node[0]
|
currentclass = node[1][2].pattr
|
||||||
|
buildclass = node
|
||||||
|
else:
|
||||||
|
currentclass = node[1][0].pattr
|
||||||
|
buildclass = node[0]
|
||||||
|
|
||||||
if buildclass[0] == 'LOAD_BUILD_CLASS':
|
if buildclass[0] == 'LOAD_BUILD_CLASS':
|
||||||
start = len(self.f.getvalue())
|
start = len(self.f.getvalue())
|
||||||
self.set_pos_info(buildclass[0], start, start + len('class')+2)
|
self.set_pos_info(buildclass[0], start, start + len('class')+2)
|
||||||
|
|
||||||
if buildclass[1][0] == 'kwargs':
|
if buildclass[1][0] == 'kwargs':
|
||||||
subclass = buildclass[1][1].attr
|
subclass = buildclass[1][1].attr
|
||||||
subclass_info = node[0]
|
subclass_info = node if node == 'classdefdeco2' else node[0]
|
||||||
elif buildclass[1][0] == 'load_closure':
|
elif buildclass[1][0] == 'load_closure':
|
||||||
# Python 3 with closures not functions
|
# Python 3 with closures not functions
|
||||||
load_closure = buildclass[1]
|
load_closure = buildclass[1]
|
||||||
@@ -762,7 +767,7 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
|||||||
subclass = buildclass[1][0].attr
|
subclass = buildclass[1][0].attr
|
||||||
subclass_info = node[0]
|
subclass_info = node[0]
|
||||||
else:
|
else:
|
||||||
buildclass = node[0]
|
buildclass = node if (node == 'classdefdeco2') else node[0]
|
||||||
build_list = buildclass[1][0]
|
build_list = buildclass[1][0]
|
||||||
if hasattr(buildclass[-3][0], 'attr'):
|
if hasattr(buildclass[-3][0], 'attr'):
|
||||||
subclass = buildclass[-3][0].attr
|
subclass = buildclass[-3][0].attr
|
||||||
@@ -773,7 +778,11 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
|||||||
else:
|
else:
|
||||||
raise 'Internal Error n_classdef: cannot find class name'
|
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)
|
self.currentclass = str(currentclass)
|
||||||
start = len(self.f.getvalue())
|
start = len(self.f.getvalue())
|
||||||
self.write(self.indent, 'class ', self.currentclass)
|
self.write(self.indent, 'class ', self.currentclass)
|
||||||
@@ -798,6 +807,8 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
|||||||
|
|
||||||
self.prune()
|
self.prune()
|
||||||
|
|
||||||
|
n_classdefdeco2 = n_classdef
|
||||||
|
|
||||||
def gen_source(self, ast, name, customize, isLambda=False, returnNone=False):
|
def gen_source(self, ast, name, customize, isLambda=False, returnNone=False):
|
||||||
"""convert AST to Python source code"""
|
"""convert AST to Python source code"""
|
||||||
|
|
||||||
|
@@ -1187,11 +1187,16 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
cclass = self.currentclass
|
cclass = self.currentclass
|
||||||
|
|
||||||
if self.version > 3.0:
|
if self.version > 3.0:
|
||||||
currentclass = node[1][0].pattr
|
if node == 'classdefdeco2':
|
||||||
buildclass = node[0]
|
currentclass = node[1][2].pattr
|
||||||
|
buildclass = node
|
||||||
|
else:
|
||||||
|
currentclass = node[1][0].pattr
|
||||||
|
buildclass = node[0]
|
||||||
|
|
||||||
if buildclass[1][0] == 'kwargs':
|
if buildclass[1][0] == 'kwargs':
|
||||||
subclass = buildclass[1][1].attr
|
subclass = buildclass[1][1].attr
|
||||||
subclass_info = node[0]
|
subclass_info = node if node == 'classdefdeco2' else node[0]
|
||||||
elif buildclass[1][0] == 'load_closure':
|
elif buildclass[1][0] == 'load_closure':
|
||||||
# Python 3 with closures not functions
|
# Python 3 with closures not functions
|
||||||
load_closure = buildclass[1]
|
load_closure = buildclass[1]
|
||||||
|
Reference in New Issue
Block a user