From 039c1156796cc985b91731471477a58121f16da1 Mon Sep 17 00:00:00 2001 From: rocky Date: Fri, 6 May 2016 23:51:25 -0400 Subject: [PATCH] More Python3 deparsing - grammar rule genexpr - More Python3 docstring formatted --- test/bytecode_3.5/10-genexpr.pyc | Bin 0 -> 463 bytes .../simple_source/comprehension/10-genexpr.py | 7 +++++ uncompyle6/parsers/parse3.py | 11 +++++--- uncompyle6/semantics/fragments.py | 11 +++++--- uncompyle6/semantics/pysource.py | 25 ++++++++++++++---- 5 files changed, 43 insertions(+), 11 deletions(-) create mode 100644 test/bytecode_3.5/10-genexpr.pyc create mode 100644 test/simple_source/comprehension/10-genexpr.py diff --git a/test/bytecode_3.5/10-genexpr.pyc b/test/bytecode_3.5/10-genexpr.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9ef0c901946867043824f167d560acdb4a548332 GIT binary patch literal 463 zcmYk2%}N6?5Xb+?YFovEig@&*mmIpScrC?)=Uxg5f`m1VZgso6Cc9vzo)q;Rd;(u7 zSKp#1C!v)NnaO # Copyright (c) 2005 by Dan Pascu -# Copyright (c) 2015 Rocky Bernstein +# Copyright (c) 2015, 2016 Rocky Bernstein # # See LICENSE for license """ @@ -368,9 +368,13 @@ class Python3Parser(PythonParser): forelselaststmtl ::= SETUP_LOOP expr _for designator for_block POP_BLOCK else_suitel COME_FROM - ''' + def p_genexpr3(self, args): + ''' + load_genexpr ::= LOAD_GENEXPR + load_genexpr ::= BUILD_TUPLE_1 LOAD_GENEXPR LOAD_CONST + ''' def p_expr3(self, args): ''' expr ::= LOAD_CLASSNAME @@ -506,7 +510,8 @@ class Python3Parser(PythonParser): self.add_unique_rule('mklambda ::= %s load_closure LOAD_LAMBDA %s' % ('expr ' * token.attr, opname), opname, token.attr, customize) - self.add_unique_rule('genexpr ::= %s load_closure LOAD_GENEXPR %s ' + self.add_unique_rule('genexpr ::= %s load_closure ' + 'load_genexpr %s ' 'expr GET_ITER CALL_FUNCTION_1' % ('expr ' * token.attr, opname), opname, token.attr, customize) diff --git a/uncompyle6/semantics/fragments.py b/uncompyle6/semantics/fragments.py index 81831f68..585cb44a 100644 --- a/uncompyle6/semantics/fragments.py +++ b/uncompyle6/semantics/fragments.py @@ -478,12 +478,17 @@ class FragmentsWalker(pysource.SourceWalker, object): self.indentLess() self.prune() # stop recursing - def comprehension_walk(self, node, iter_index): + def comprehension_walk(self, node, iter_index, code_index=-5): p = self.prec self.prec = 27 - code = node[-5].attr + if hasattr(node[code_index], 'attr'): + code = node[code_index].attr + elif hasattr(node[1][1], 'attr'): + code = node[1][1].attr + else: + assert False - assert iscode(co) + assert iscode(code) code = Code(code, self.scanner, self.currentclass) # assert isinstance(code, Code) diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 61170faf..d4a9f117 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -436,6 +436,13 @@ escape = re.compile(r''' ( [{] (?P [^}]* ) [}] )) ''', re.VERBOSE) +def is_docstring(node): + try: + return (node[0][0].type == 'assign' and + node[0][0][1][0].pattr == '__doc__') + except: + return False + class ParserError(python_parser.ParserError): def __init__(self, error, tokens): self.error = error # previous exception @@ -972,7 +979,12 @@ class SourceWalker(GenericASTTraversal, object): def comprehension_walk(self, node, iter_index, code_index=-5): p = self.prec self.prec = 27 - code = node[code_index].attr + if hasattr(node[code_index], 'attr'): + code = node[code_index].attr + elif hasattr(node[1][1], 'attr'): + code = node[1][1].attr + else: + assert False assert iscode(code) code = Code(code, self.scanner, self.currentclass) @@ -1587,15 +1599,18 @@ class SourceWalker(GenericASTTraversal, object): # if docstring exists, dump it if (code.co_consts and code.co_consts[0] is not None and len(ast) > 0): do_doc = False - if (ast[0][0] == ASSIGN_DOC_STRING(code.co_consts[0])): + if is_docstring(ast[0]): i = 0 do_doc = True - elif (len(ast) > 1 and 3.0 <= self.version <= 3.2 and - ast[1][0] == ASSIGN_DOC_STRING(code.co_consts[0])): + elif (len(ast) > 1 and is_docstring(ast[1])): i = 1 do_doc = True if do_doc and self.hide_internal: - self.print_docstring(indent, code.co_consts[0]) + try: + docstring = ast[i][0][0][0][0].pattr + except: + docstring = code.co_consts[0] + self.print_docstring(indent, docstring) self.print_() del ast[i]