3.7+ "from import" vs "import as" disambiguation

This commit is contained in:
rocky
2020-01-02 09:36:16 -05:00
parent c42e16fafe
commit 7bd81efe9b
4 changed files with 49 additions and 10 deletions

View File

@@ -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

View File

@@ -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):

View File

@@ -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

View File

@@ -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