From ffbce9cb77f81c80a72c58e84df4afc5f8589bc2 Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 4 Mar 2018 17:25:42 -0500 Subject: [PATCH] 3.6 class signature problems... This time getting the class name in when a "load_closure" is added. --- test/bytecode_3.6/01_call_function.pyc | Bin 249 -> 1035 bytes test/bytecode_3.6/bug36.10_long_elif.pyc | Bin 1272 -> 0 bytes test/simple_source/bug36.10_long_elif.py | 49 ----------------- test/simple_source/bug36/01_call_function.py | 24 ++++++++- uncompyle6/semantics/pysource.py | 54 ++++++++++--------- 5 files changed, 51 insertions(+), 76 deletions(-) delete mode 100644 test/bytecode_3.6/bug36.10_long_elif.pyc delete mode 100644 test/simple_source/bug36.10_long_elif.py diff --git a/test/bytecode_3.6/01_call_function.pyc b/test/bytecode_3.6/01_call_function.pyc index 82336180bf61731e11bff6fcac1e1d5cf66f0ebd..f3d0e595da84f53b25aca2b4459e1a8d9f618846 100644 GIT binary patch literal 1035 zcmaJYx15FOk5)wF@Cv;slI740R3R6-o8suG7vM9QT%U##ugi9&a?sW%a%5~o&z zQ-1;C&R_DCQ~v@dW_FV%B?U{K@z;AZo;L^0W}|7p%Xb3c7px52!!geC0~!sQWsoz; zaxQr;q{uz#<-YV87&d?#K<^u7c%K{bgB$OL$v|^0u0e*{(?0r02d5B+x5x*v?^xf3 zdYEJ;oj5PCgVK5DpLFR0YZ7g2%IF;qj?=?Q36;;#oWNJ;GtD%=jx?XZmH5ImAhqbF zczrhrK%)W~koZXQB~%J65aeC%rTJJ*3UzK~?Zd1{ldL>yckfYAE>DOmK=Tc*C>rbi z1RLT$X3o!NNK);7zbc3MI5Vm&rZzSEXVbyK+x^#X6!K=OKOLo$VKHitXD(1`V3gV; zUiu`k%hrRbwCjhx*mIFmqa;U^Ybcc$dWwOR+fwRcnq>8jZ6MV=F&iz`b^}+Ab$8KK z(IRFa;Tn?Ld@&ebb1e7AsfrgszQ(=z;=b*M!%-jdps;D)Co2Y>IDDOiT-}P z04#K>VRsrm#qgbVkveNCoe~ixrx|L*d$&HWtMB}6=v!5-S_GL3@bVvVmJ--a!flah zE*Ku7cD&npv0%nx@8CLS_A$A6rRit|TGe@TC4uJzuM52`ES0?%Z%ENE3QOr)YH&;U lw)!OXremKgMXJ{;+|;La3q*%?+Z<7Alw?{w@^`!_`~!Fdz#jkr delta 96 zcmeC?_{pej%*)I5z>% diff --git a/test/bytecode_3.6/bug36.10_long_elif.pyc b/test/bytecode_3.6/bug36.10_long_elif.pyc deleted file mode 100644 index 391c123079b859621a7d1154c28bc6a531f0b45f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1272 zcmZuw&2Jk;6rY*>UfIT^RcHegLsC(z!UP3HJ%orTAC;;$tw>bbRnThjjNP@@yW5#@ zNUSl3x^S-G!oR@3!*NbXh=XsOd*aQyL;*3@d;5NG-kbO4H_sdOdibaOIr_;(=nr&h z5wO1m5j9X0QT!4`h>|1Jwz?2otq^n_WEVsnV}ukMKqMtIGIbRxm#8)Mlv}PS53u_R z^Lxsj5^7Iz73nOriH8hddHlusn#9zl-bQ%gAmhc=WC)dGp7D?JsM zQ{mh|`o^Yj4GI5E1vI#hrdECe*8AZ3-DKy7fNl)QE5!ezR{(DV{s1uMh+YNU0oc$ z+Y~ZYZ8TZEe2W;`>uhC3H_60y=OSL?&K#oA+~mw{P!s2qgm<4sRxgp0dS#!8+qX`R zZnx*=TG~!G?rdtSEW6r0yR#W@ejYi{Im;p&QZ}>$JH`h9KEXIoPZ<|UHo3W1283oEIEilBcEidTCCREYq$ixMWmY z0@AFE<=Pu1XCj@jb{N&-ZjtxWetep6q1{5{$%tu>vy3GIj5j<$^10B2vucunuPB6_ zH&Kz>?PW<{L{7y~H5UsNK+C%M-)F7{?!a8fs$n1d#KktY$yLw= (10, 4)) and '-arch' in cflags.strip(): - machine = 'fat' - - archs = re.findall(r'-arch\s+(\S+)', cflags) - archs = tuple(sorted(set(archs))) - - if len(archs) == 1: - machine = archs[0] - elif archs == ('i386', 'ppc'): - machine = 'fat' - elif archs == ('i386', 'x86_64'): - machine = 'intel' - elif archs == ('i386', 'ppc', 'x86_64'): - machine = 'fat3' - elif archs == ('ppc64', 'x86_64'): - machine = 'fat64' - elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'): - machine = 'universal' - else: - raise ValueError( - "Don't know machine value for archs=%r" % (archs,)) - - elif machine == 'i386': - if sys.maxsize >= 2**32: - machine = 'x86_64' - - return (osname, release, machine) diff --git a/test/simple_source/bug36/01_call_function.py b/test/simple_source/bug36/01_call_function.py index a758e5cb..3f1666c7 100644 --- a/test/simple_source/bug36/01_call_function.py +++ b/test/simple_source/bug36/01_call_function.py @@ -1,10 +1,30 @@ # Python 3.6's changes for calling functions. # See https://github.com/rocky/python-uncompyle6/issues/58 -# CALL_FUNCTION_EX takes 2 to 3 arguments on the stack: the function, the tuple of positional arguments, -# and optionally the dict of keyword arguments if bit 0 of oparg is 1. + +# CALL_FUNCTION_EX takes 2 to 3 arguments on the stack: +# * the function, +# * the tuple of positional arguments, and optionally +# * the dict of keyword arguments if bit 0 of oparg is 1. from foo import f, dialect, args, kwds, reader f(*[]) # From Python 3.6 csv.py +# (f, dialect) are positional arg tuples, *args, is by itself, i.e. +# no tuple. x = reader(f, dialect, *args, **kwds) + +# From 3.6 functools.py +# Below there is a load_closure instruction added +def cmp_to_key(mycmp): + class K(object): + def __ge__(): + return mycmp() + return + +# In this situation though, there is no load_closure +def cmp2_to_key(mycmp): + class K2(object): + def __ge__(): + return 5 + return diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index bf57a753..b32abc83 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -1531,17 +1531,21 @@ class SourceWalker(GenericASTTraversal, object): class_name = node[2][0].pattr else: class_name = node[1][2].pattr - buildclass = node + build_class = node else: + build_class = node[0] if self.version >= 3.6: - class_name = node[0][1][0].attr.co_name - buildclass = node[0] + if build_class[1][0] == 'load_closure': + code_node = build_class[1][1] + else: + code_node = build_class[1][0] + class_name = code_node.attr.co_name else: class_name = node[1][0].pattr - buildclass = node[0] + build_class = node[0] - assert 'mkfunc' == buildclass[1] - mkfunc = buildclass[1] + assert 'mkfunc' == build_class[1] + mkfunc = build_class[1] if mkfunc[0] == 'kwargs': if 3.0 <= self.version <= 3.2: for n in mkfunc: @@ -1563,9 +1567,9 @@ class SourceWalker(GenericASTTraversal, object): subclass_info = node else: subclass_info = node[0] - elif buildclass[1][0] == 'load_closure': + elif build_class[1][0] == 'load_closure': # Python 3 with closures not functions - load_closure = buildclass[1] + load_closure = build_class[1] if hasattr(load_closure[-3], 'attr'): # Python 3.3 classes with closures work like this. # Note have to test before 3.2 case because @@ -1576,34 +1580,34 @@ class SourceWalker(GenericASTTraversal, object): subclass_code = load_closure[-2].attr else: raise 'Internal Error n_classdef: cannot find class body' - if hasattr(buildclass[3], '__len__'): - subclass_info = buildclass[3] - elif hasattr(buildclass[2], '__len__'): - subclass_info = buildclass[2] + if hasattr(build_class[3], '__len__'): + subclass_info = build_class[3] + elif hasattr(build_class[2], '__len__'): + subclass_info = build_class[2] else: raise 'Internal Error n_classdef: cannot superclass name' elif self.version >= 3.6 and node == 'classdefdeco2': subclass_info = node - subclass_code = buildclass[1][0].attr + subclass_code = build_class[1][0].attr else: - subclass_code = buildclass[1][0].attr + subclass_code = build_class[1][0].attr subclass_info = node[0] else: if node == 'classdefdeco2': - buildclass = node + build_class = node else: - buildclass = node[0] - build_list = buildclass[1][0] - if hasattr(buildclass[-3][0], 'attr'): - subclass_code = buildclass[-3][0].attr - class_name = buildclass[0].pattr - elif (buildclass[-3] == 'mkfunc' and + build_class = node[0] + build_list = build_class[1][0] + if hasattr(build_class[-3][0], 'attr'): + subclass_code = build_class[-3][0].attr + class_name = build_class[0].pattr + elif (build_class[-3] == 'mkfunc' and node == 'classdefdeco2' and - buildclass[-3][0] == 'load_closure'): - subclass_code = buildclass[-3][1].attr - class_name = buildclass[-3][0][0].pattr + build_class[-3][0] == 'load_closure'): + subclass_code = build_class[-3][1].attr + class_name = build_class[-3][0][0].pattr elif hasattr(node[0][0], 'pattr'): - subclass_code = buildclass[-3][1].attr + subclass_code = build_class[-3][1].attr class_name = node[0][0].pattr else: raise 'Internal Error n_classdef: cannot find class name'