diff --git a/test/simple_source/stmts/00_import.py b/test/simple_source/stmts/00_import.py index fd80daf6..a3f58355 100644 --- a/test/simple_source/stmts/00_import.py +++ b/test/simple_source/stmts/00_import.py @@ -4,6 +4,7 @@ from os import path from os import * import time as time1, os as os1 import http.client as httpclient +from sys import stdin, stdout, stderr if len(__file__) == 0: # a.b.c should force consecutive LOAD_ATTRs import a.b.c as d diff --git a/uncompyle6/parsers/parse37.py b/uncompyle6/parsers/parse37.py index 85a93822..60381ba5 100644 --- a/uncompyle6/parsers/parse37.py +++ b/uncompyle6/parsers/parse37.py @@ -329,21 +329,29 @@ class Python37Parser(Python37BaseParser): def p_import37(self, args): """ - stmt ::= import_as37 - import_as37 ::= LOAD_CONST LOAD_CONST importlist37 store POP_TOP + stmt ::= import_as37 + import_as37 ::= LOAD_CONST LOAD_CONST importlist37 store POP_TOP - importlist37 ::= importlist37 ROT_TWO IMPORT_FROM - importlist37 ::= importlist37 ROT_TWO POP_TOP IMPORT_FROM - importlist37 ::= importattr37 - importattr37 ::= IMPORT_NAME_ATTR IMPORT_FROM + importlist37 ::= importlist37 ROT_TWO IMPORT_FROM + importlist37 ::= importlist37 ROT_TWO POP_TOP IMPORT_FROM + importlist37 ::= importattr37 + importattr37 ::= IMPORT_NAME_ATTR IMPORT_FROM # The 3.7base scanner adds IMPORT_NAME_ATTR - alias ::= IMPORT_NAME_ATTR attributes store - alias ::= IMPORT_NAME_ATTR store - import_from ::= LOAD_CONST LOAD_CONST importlist POP_TOP + alias ::= IMPORT_NAME_ATTR attributes store + alias ::= IMPORT_NAME_ATTR store + import_from ::= LOAD_CONST LOAD_CONST importlist POP_TOP expr ::= attribute37 attribute37 ::= expr LOAD_METHOD + + stmt ::= import_from37 + importlist37 ::= importlist37 alias + importlist37 ::= alias37 + alias37 ::= IMPORT_NAME store + alias37 ::= IMPORT_FROM store + import_from37 ::= LOAD_CONST LOAD_CONST IMPORT_NAME_ATTR importlist37 POP_TOP + """ def p_list_comprehension(self, args): diff --git a/uncompyle6/parsers/parse37base.py b/uncompyle6/parsers/parse37base.py index 7481c303..cfa3bb48 100644 --- a/uncompyle6/parsers/parse37base.py +++ b/uncompyle6/parsers/parse37base.py @@ -974,6 +974,7 @@ class Python37BaseParser(PythonParser): pass self.check_reduce["and"] = "AST" + self.check_reduce["annotate_tuple"] = "noAST" self.check_reduce["aug_assign1"] = "AST" self.check_reduce["aug_assign2"] = "AST" self.check_reduce["while1stmt"] = "noAST" @@ -984,7 +985,7 @@ class Python37BaseParser(PythonParser): self.check_reduce["iflaststmtl"] = "AST" self.check_reduce["ifstmt"] = "AST" self.check_reduce["ifstmtl"] = "AST" - self.check_reduce["annotate_tuple"] = "noAST" + self.check_reduce["import_from37"] = "AST" self.check_reduce["or"] = "tokens" # FIXME: remove parser errors caused by the below @@ -1462,5 +1463,13 @@ class Python37BaseParser(PythonParser): ] != "JUMP_FORWARD" return False + elif lhs == "import_from37": + importlist37 = ast[3] + alias37 = importlist37[0] + if importlist37 == "importlist37" and alias37 == "alias37": + store = alias37[1] + assert store == "store" + return alias37[0].attr != store[0].attr + return False return False diff --git a/uncompyle6/semantics/customize37.py b/uncompyle6/semantics/customize37.py index 83756c36..6edcd7be 100644 --- a/uncompyle6/semantics/customize37.py +++ b/uncompyle6/semantics/customize37.py @@ -131,6 +131,9 @@ def customize_for_version37(self, version): ), "ifstmtl": ("%|if %c:\n%+%c%-", (0, "testexpr"), (1, "_ifstmts_jumpl")), 'import_as37': ( '%|import %c as %c\n', 2, -2), + 'import_from37': ( '%|from %[2]{pattr} import %c\n', + (3, 'importlist37') ), + "importattr37": ("%c", (0, "IMPORT_NAME_ATTR")), 'list_if37': ( " if %p%c", (0, 27), 1 ), "testfalse_not_or": ("not %c or %c", (0, "expr"), (2, "expr")), @@ -142,3 +145,21 @@ def customize_for_version37(self, version): "yield_from": ("yield from %c", (0, "expr")), } ) + + # Don't think we need this as long as we disambiguate + # in parse37base.py "from ... import" vs. "import .. as" + # def n_alias37(node): + # assert len(node) == 2 + # import_from = node[0] + # store = node[1] + # assert store == "store" + # if import_from == "IMPORT_FROM" and import_from.attr != store[0].attr: + # template = ("%c as %c ", 0, 1) + # else: + # template = ("%c ", 1) + # pass + # self.template_engine(template, node) + # self.prune() + # return + + # self.n_alias37 = n_alias37