Correct 3.7 "impor"t and "from .. import"

This commit is contained in:
rocky 2022-04-20 20:03:28 -04:00
parent e2ff909603
commit c88d9de316
7 changed files with 80 additions and 26 deletions

Binary file not shown.

Binary file not shown.

View File

@ -1,11 +1,23 @@
# Tests all the different kinds of imports # Tests all the different kinds of imports
"""This program is self-checking!"""
import sys import sys
from os import path from os import path
from os import * from os import * # NOQA
import time as time1, os as os1 import time as time1, os as os1
import http.client as httpclient
from sys import stdin, stdout, stderr assert isinstance(os1.pathsep, str)
assert time1.time() > 0
import os.path as osp
assert osp == path
from os.path import join as jj
assert path.join == jj
if len(__file__) == 0: if len(__file__) == 0:
# a.b.c should force consecutive LOAD_ATTRs # a.b.c should force consecutive LOAD_ATTRs
import a.b.c as d
import stuff0.stuff1.stuff2.stuff3 as stuff3 import stuff0.stuff1.stuff2.stuff3 as stuff3
sys.exit(0)

View File

@ -152,7 +152,10 @@ class Python37Parser(Python37BaseParser):
expr ::= LOAD_NAME expr ::= LOAD_NAME
expr ::= LOAD_STR expr ::= LOAD_STR
expr ::= _lambda_body expr ::= _lambda_body
expr ::= and expr ::= and
expr ::= attribute37
expr ::= bin_op expr ::= bin_op
expr ::= call expr ::= call
expr ::= compare expr ::= compare
@ -346,28 +349,43 @@ class Python37Parser(Python37BaseParser):
def p_import37(self, args): def p_import37(self, args):
""" """
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
# The 3.7base scanner adds IMPORT_NAME_ATTR # The 3.7base scanner adds IMPORT_NAME_ATTR
alias ::= IMPORT_NAME_ATTR attributes store alias ::= IMPORT_NAME_ATTR attributes store
alias ::= IMPORT_NAME_ATTR store alias ::= IMPORT_NAME_ATTR store
alias37 ::= IMPORT_NAME store
alias37 ::= IMPORT_FROM store
attribute37 ::= expr LOAD_METHOD
import_as37 ::= LOAD_CONST LOAD_CONST importlist37 store POP_TOP
import_from ::= LOAD_CONST LOAD_CONST importlist POP_TOP import_from ::= LOAD_CONST LOAD_CONST importlist POP_TOP
import_from37 ::= LOAD_CONST LOAD_CONST IMPORT_NAME_ATTR importlist37 POP_TOP
import_from_as37 ::= LOAD_CONST LOAD_CONST import_from_attr37 store POP_TOP
expr ::= attribute37
attribute37 ::= expr LOAD_METHOD
# A single entry in a dotted import a.b.c.d
import_one ::= importlists ROT_TWO IMPORT_FROM
import_one ::= importlists ROT_TWO POP_TOP IMPORT_FROM
# Semantic checks distinguish importattr37 from import_from_attr37
# in the former the "from" slot in a prior LOAD_CONST is null.
# Used in: import .. as ..
importattr37 ::= IMPORT_NAME_ATTR IMPORT_FROM
# Used in: from xx import .. as ..
import_from_attr37 ::= IMPORT_NAME_ATTR IMPORT_FROM
importlist37 ::= import_one
importlist37 ::= importattr37
importlist37 ::= alias37+
importlists ::= importlist37+
stmt ::= import_as37
stmt ::= import_from37 stmt ::= import_from37
importlist37 ::= importlist37 alias37 stmt ::= import_from_as37
importlist37 ::= alias37
alias37 ::= IMPORT_NAME store
alias37 ::= IMPORT_FROM store
import_from37 ::= LOAD_CONST LOAD_CONST IMPORT_NAME_ATTR importlist37 POP_TOP
""" """

View File

@ -1134,6 +1134,9 @@ class Python37BaseParser(PythonParser):
self.check_reduce["while1stmt"] = "noAST" self.check_reduce["while1stmt"] = "noAST"
self.check_reduce["while1elsestmt"] = "noAST" self.check_reduce["while1elsestmt"] = "noAST"
self.check_reduce["_ifstmts_jump"] = "AST" self.check_reduce["_ifstmts_jump"] = "AST"
self.check_reduce["import_as37"] = "tokens"
self.check_reduce["import_from_as37"] = "tokens"
self.check_reduce["import_from_as37"] = "tokens"
self.check_reduce["ifelsestmt"] = "AST" self.check_reduce["ifelsestmt"] = "AST"
self.check_reduce["ifelsestmtl"] = "AST" self.check_reduce["ifelsestmtl"] = "AST"
self.check_reduce["iflaststmt"] = "AST" self.check_reduce["iflaststmt"] = "AST"
@ -1263,5 +1266,9 @@ class Python37BaseParser(PythonParser):
assert store == "store" assert store == "store"
return alias37[0].attr != store[0].attr return alias37[0].attr != store[0].attr
return False return False
elif lhs == "import_as37":
return tokens[first + 1].pattr is not None
elif lhs == "import_from_as37":
return tokens[first + 1].pattr is None
return False return False

View File

@ -146,11 +146,18 @@ def customize_for_version37(self, version):
), ),
"ifstmtl": ("%|if %c:\n%+%c%-", (0, "testexpr"), (1, "_ifstmts_jumpl")), "ifstmtl": ("%|if %c:\n%+%c%-", (0, "testexpr"), (1, "_ifstmts_jumpl")),
'import_as37': ( '%|import %c as %c\n', 2, -2), 'import_as37': ( '%|import %c as %c\n', 2, -2),
'import_from37': ( '%|from %[2]{pattr} import %c\n', "import_from_as37": (
(3, 'importlist37') ), "%|from %c as %c\n",
(2, "import_from_attr37"),
(3, "store"),
),
"import_one": ("%c", (0, "importlists"),),
"importattr37": ("%c", (0, "IMPORT_NAME_ATTR")), "importattr37": ("%c", (0, "IMPORT_NAME_ATTR")),
"import_from_attr37": (
"%c import %c",
(0, "IMPORT_NAME_ATTR"),
(1, "IMPORT_FROM"),
),
"list_afor": ( "list_afor": (
" async for %[1]{%c} in %c%[1]{%c}", " async for %[1]{%c} in %c%[1]{%c}",
(1, "store"), (0, "get_aiter"), (3, "list_iter"), (1, "store"), (0, "get_aiter"), (3, "list_iter"),

View File

@ -13,7 +13,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
Custom Nonterminal action functions Custom Nonterminal action functions. See NonterminalActions docstring.
""" """
from uncompyle6.semantics.consts import ( from uncompyle6.semantics.consts import (
@ -33,6 +33,16 @@ from uncompyle6.semantics.helper import (
) )
class NonterminalActions: class NonterminalActions:
"""
Methods here all start with n_ and the remaining portion should be a nonterminal
name defined by some rule.
These methods take priority over names defined in table constants.
All of the methods should have the same signature: (self, node) and return None.
node is the subtree of the parse tree the that nonterminal name as the root.
"""
def n_alias(self, node): def n_alias(self, node):
if self.version <= (2, 1): if self.version <= (2, 1):
if len(node) == 2: if len(node) == 2: