From da06d83a875256ff3f50348f08bf316dda6d48d2 Mon Sep 17 00:00:00 2001 From: rocky Date: Wed, 21 Mar 2018 15:14:23 -0400 Subject: [PATCH] 3.6 subclass extraction bug --- test/bytecode_3.6/04_class_kwargs.pyc | Bin 1234 -> 1743 bytes test/simple_source/bug36/04_class_kwargs.py | 6 +++++ uncompyle6/semantics/pysource.py | 26 +++++++++++++++++--- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/test/bytecode_3.6/04_class_kwargs.pyc b/test/bytecode_3.6/04_class_kwargs.pyc index f9a4e7fd72a42c6b8f2c0477f7a58599ba0545f0..d3d220f94a12881e43513756927163c615fc445a 100644 GIT binary patch delta 572 zcma)3O-sW-5S_`UHI1f`x^w00Z;xBXH#3e>A<|*?7lZMZ}X9Rx60d=Wqv-ty5}0e7yJsH_WP8P^H|=n zbeT!H=7c!u!%=-u|9%hxQ7OE)vG~h3CubK(<0&Z+B(T z6rOB{U1zrw`d%m6b1KtW)yyhus)2HtPJmTm(B4K-h zlLBMU$;`oF<%CGKCe)jy!ik|Zb&yss{$au*X8I&xVje|_KJ83A(u-J%J8UI>(=Ai| KW&;geG`<0sfO~8J delta 73 zcmX@ldx=xon3tC;&vR2$A0q?9V+JI^0%SV?ak1J&Wi?jDU)GTd PFJ@EX04d>M~#yu diff --git a/test/simple_source/bug36/04_class_kwargs.py b/test/simple_source/bug36/04_class_kwargs.py index da90d30a..55797a27 100644 --- a/test/simple_source/bug36/04_class_kwargs.py +++ b/test/simple_source/bug36/04_class_kwargs.py @@ -9,3 +9,9 @@ class TestABCWithInitSubclass(unittest.TestCase): super().__init_subclass__() class Receiver(ReceivesClassKwargs, abc.ABC, x=1, y=2, z=3): pass + +def test_abstractmethod_integration(self): + for abstractthing in [abc.abstractmethod]: + class C(metaclass=abc.ABCMeta): + @abstractthing + def foo(self): pass # abstract diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index ca4a34f2..031b3504 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -1523,6 +1523,13 @@ class SourceWalker(GenericASTTraversal, object): # class definition ('class X(A,B,C):') cclass = self.currentclass + # Pick out various needed bits of information + # * class_name - the name of the class + # * subclass_info - the parameters to the class e.g. + # class Foo(bar, baz) + # ----------- + # * subclass_code - the code for the subclass body + subclass_info = None if self.version > 3.0: if node == 'classdefdeco2': if self.version >= 3.6: @@ -1535,6 +1542,16 @@ class SourceWalker(GenericASTTraversal, object): else: build_class = node[0] if self.version >= 3.6: + if build_class == 'build_class_kw': + mkfunc = build_class[1] + assert mkfunc == 'mkfunc' + subclass_info = build_class + if hasattr(mkfunc[0], 'attr') and iscode(mkfunc[0].attr): + subclass_code = mkfunc[0].attr + else: + assert mkfunc[0] == 'load_closure' + subclass_code = mkfunc[1].attr + assert iscode(subclass_code) if build_class[1][0] == 'load_closure': code_node = build_class[1][1] else: @@ -1581,7 +1598,8 @@ class SourceWalker(GenericASTTraversal, object): else: raise 'Internal Error n_classdef: cannot find class body' if hasattr(build_class[3], '__len__'): - subclass_info = build_class[3] + if not subclass_info: + subclass_info = build_class[3] elif hasattr(build_class[2], '__len__'): subclass_info = build_class[2] else: @@ -1589,7 +1607,7 @@ class SourceWalker(GenericASTTraversal, object): elif self.version >= 3.6 and node == 'classdefdeco2': subclass_info = node subclass_code = build_class[1][0].attr - else: + elif not subclass_info: subclass_code = build_class[1][0].attr subclass_info = node[0] else: @@ -1718,8 +1736,10 @@ class SourceWalker(GenericASTTraversal, object): pass pass else: - self.write('(') + if self.version >= 3.6 and node[0] == 'LOAD_CONST': + return value = self.traverse(node[0]) + self.write('(') self.write(value) pass