3.7 "imports" and "or"

This commit is contained in:
rocky 2020-01-11 07:06:46 -05:00
parent 6cef42f6c7
commit c3d7ba6dad
13 changed files with 52 additions and 12 deletions

Binary file not shown.

Binary file not shown.

View File

@ -5,12 +5,15 @@
# RUNNABLE!
import os.path as osp
from sys import path
from sys import platform
from os import sep, name
import collections.abc
assert osp.basename("a") == "a"
assert path
assert isinstance(platform, str)
assert sep
assert name
assert collections.abc
import os.path as path
assert path

View File

@ -8,3 +8,14 @@ def foo(n):
assert foo(95)
assert not foo(94)
assert not foo(96)
# from test_buffer.py
# Bug was handling "or" inside a conditional
def rslice(a, b):
minlen = 0 if a or b else 1
return minlen
assert rslice(False, False) == 1
assert rslice(False, True) == 0
assert rslice(True, False) == 0
assert rslice(True, True) == 0

View File

@ -454,7 +454,6 @@ case $PYVERSION in
[test_compare.py]=1 # test assert fail - investigate
[test_compile.py]=1
[test_configparser.py]=1
[test_contextlib_async.py]=1 # Investigate
[test_context.py]=1
[test_coroutines.py]=1 # Parse error
[test_crypt.py]=1 # Parse error

View File

@ -913,6 +913,7 @@ class Python37Parser(Python37BaseParser):
or ::= and jitop_come_from expr COME_FROM
or ::= expr JUMP_IF_TRUE_OR_POP expr COME_FROM
or ::= expr JUMP_IF_TRUE expr COME_FROM
or ::= expr POP_JUMP_IF_TRUE expr POP_JUMP_IF_FALSE COME_FROM
testfalse_not_or ::= expr jmp_false expr jmp_false COME_FROM
testfalse_not_and ::= and jmp_true come_froms

View File

@ -3,10 +3,7 @@
def or_check(self, lhs, n, rule, ast, tokens, first, last):
if rule == ("or", ("expr", "jmp_true", "expr")):
if tokens[last] in (
"LOAD_ASSERT",
"RAISE_VARARGS_1",
):
if tokens[last] in ("LOAD_ASSERT", "RAISE_VARARGS_1",):
return True
# The following test is be the most accurate. It prevents "or" from being
@ -16,7 +13,7 @@ def or_check(self, lhs, n, rule, ast, tokens, first, last):
# The below then is useful until we get better control-flow analysis.
# Note it is too hard in the scanner right nowto turn the LOAD_GLOBAL into
# int LOAD_ASSERT, however in 3.9ish code generation does this by default.
load_global = tokens[last-1]
load_global = tokens[last - 1]
if load_global == "LOAD_GLOBAL" and load_global.attr == "AssertionError":
return True
@ -24,11 +21,14 @@ def or_check(self, lhs, n, rule, ast, tokens, first, last):
jmp_false = tokens[last]
# If the jmp is backwards
if jmp_false == "POP_JUMP_IF_FALSE":
if jmp_false.attr < jmp_false.off2int():
jmp_false_offset = jmp_false.off2int()
if jmp_false.attr < jmp_false_offset:
# For a backwards loop, well compare to the instruction *after*
# then POP_JUMP...
jmp_false = tokens[last+1]
return not (jmp_true_target == jmp_false.off2int() or
jmp_true_target < tokens[first].off2int())
jmp_false = tokens[last + 1]
return not (
(jmp_false_offset <= jmp_true_target <= jmp_false_offset + 2)
or jmp_true_target < tokens[first].off2int()
)
return False

View File

@ -287,6 +287,32 @@ class TreeTransform(GenericASTTraversal, object):
n_ifelsestmtc = n_ifelsestmtl = n_ifelsestmt
def n_import_from37(self, node):
importlist37 = node[3]
assert importlist37 == "importlist37"
if len(importlist37) == 1:
alias37 = importlist37[0]
store = alias37[1]
assert store == "store"
alias_name = store[0].attr
import_name_attr = node[2]
assert import_name_attr == "IMPORT_NAME_ATTR"
dotted_names = import_name_attr.attr.split(".")
if len(dotted_names) > 1:
# Simulate:
# Instead of
# import_from37 ::= LOAD_CONST LOAD_CONST IMPORT_NAME_ATTR importlist37 POP_TOP
# import_as37 ::= LOAD_CONST LOAD_CONST importlist37 store POP_TOP
# 'import_as37': ( '%|import %c as %c\n', 2, -2),
assert dotted_names[-1] == alias_name
node = SyntaxTree("import_as37",
[node[0], node[1], import_name_attr, store, node[-1]])
node.transformed_by="n_import_from37"
pass
pass
return node
def n_list_for(self, list_for_node):
expr = list_for_node[0]
if expr == "expr" and expr[0] == "get_iter":