Fix bug in 3.8 with .. as

This commit is contained in:
rocky
2020-06-04 05:24:22 -04:00
parent 40a653cd3b
commit 9acb3cf068
10 changed files with 60 additions and 29 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -2,6 +2,7 @@
# Bug was code not knowing which Python versions # Bug was code not knowing which Python versions
# have kwargs coming before positional args in code. # have kwargs coming before positional args in code.
"""This program is self-checking!"""
# RUNNABLE! # RUNNABLE!
def tometadata(self, metadata, schema, Table, args, name=None): def tometadata(self, metadata, schema, Table, args, name=None):

View File

@@ -16,3 +16,11 @@ def withas_bug(self, nested, a, b):
with self.assertRaises(ZeroDivisionError): with self.assertRaises(ZeroDivisionError):
with nested(a(), b()) as (x, y): with nested(a(), b()) as (x, y):
1 // 0 1 // 0
# Adapted from 3.8 distutils/command/config.py
# In 3.8 the problem was in handling "with .. as" code
def _gen_temp_sourcefile(x, a, headers, lang):
with x as y:
if a:
y = 2
return 5

View File

@@ -127,6 +127,7 @@ class Python37BaseParser(PythonParser):
"RAISE", "RAISE",
"SETUP", "SETUP",
"UNPACK", "UNPACK",
"WITH",
) )
) )
@@ -993,55 +994,70 @@ class Python37BaseParser(PythonParser):
) )
custom_ops_processed.add(opname) custom_ops_processed.add(opname)
elif opname == "WITH_CLEANUP_START":
rules_str = """
stmt ::= with_null
with_null ::= with_suffix
with_suffix ::= WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
"""
self.addRule(rules_str, nop_func)
elif opname == "SETUP_WITH": elif opname == "SETUP_WITH":
rules_str = """ rules_str = """
stmt ::= with stmt ::= with
stmt ::= withasstmt stmt ::= withasstmt
with ::= expr SETUP_WITH POP_TOP suite_stmts_opt COME_FROM_WITH with ::= expr
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY SETUP_WITH POP_TOP
suite_stmts_opt
COME_FROM_WITH
with_suffix
withasstmt ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH withasstmt ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY with_suffix
with ::= expr
SETUP_WITH POP_TOP
suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH
with_suffix
withasstmt ::= expr
SETUP_WITH store suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH
with_suffix
with ::= expr with ::= expr
SETUP_WITH POP_TOP suite_stmts_opt SETUP_WITH POP_TOP suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH POP_BLOCK LOAD_CONST COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY with_suffix
withasstmt ::= expr withasstmt ::= expr
SETUP_WITH store suite_stmts_opt SETUP_WITH store suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH POP_BLOCK LOAD_CONST COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY with_suffix
with ::= expr
SETUP_WITH POP_TOP suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
withasstmt ::= expr
SETUP_WITH store suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
""" """
if self.version < 3.8: if self.version < 3.8:
rules_str += """ rules_str += """
with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK
LOAD_CONST LOAD_CONST
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY with_suffix
""" """
else: else:
rules_str += """ rules_str += """
with ::= expr with ::= expr
SETUP_WITH POP_TOP suite_stmts_opt SETUP_WITH POP_TOP suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH POP_BLOCK LOAD_CONST COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY with_suffix
withasstmt ::= expr withasstmt ::= expr
SETUP_WITH store suite_stmts_opt SETUP_WITH store suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH POP_BLOCK LOAD_CONST COME_FROM_WITH
with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK withasstmt ::= expr
SETUP_WITH store suite_stmts
POP_BLOCK BEGIN_FINALLY COME_FROM_WITH with_suffix
with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK
BEGIN_FINALLY COME_FROM_WITH BEGIN_FINALLY COME_FROM_WITH
WITH_CLEANUP_START WITH_CLEANUP_FINISH with_suffix
END_FINALLY
""" """
self.addRule(rules_str, nop_func) self.addRule(rules_str, nop_func)

View File

@@ -8,22 +8,28 @@ FIXME idea: extend parsing system to do same kinds of checks or nonterminal
before reduction and don't reduce when there is a problem. before reduction and don't reduce when there is a problem.
""" """
def checker(ast, in_loop, errors): def checker(ast, in_loop, errors):
if ast is None: if ast is None:
return return
in_loop = (in_loop or (ast.kind in ('while1stmt', 'whileTruestmt', in_loop = (
'whilestmt', 'whileelsestmt', 'while1elsestmt', in_loop
'for_block')) or ast.kind.startswith("while")
or ast.kind.startswith('async_for')) or ast.kind.startswith("async_for")
if ast.kind in ('aug_assign1', 'aug_assign2') and ast[0][0] == 'and': )
if ast.kind in ("aug_assign1", "aug_assign2") and ast[0][0] == "and":
text = str(ast) text = str(ast)
error_text = '\n# improper augmented assigment (e.g. +=, *=, ...):\n#\t' + '\n# '.join(text.split("\n")) + '\n' error_text = (
"\n# improper augmented assigment (e.g. +=, *=, ...):\n#\t"
+ "\n# ".join(text.split("\n"))
+ "\n"
)
errors.append(error_text) errors.append(error_text)
for node in ast: for node in ast:
if not in_loop and node.kind in ('continue', 'break'): if not in_loop and node.kind in ("continue", "break"):
text = str(node) text = str(node)
error_text = '\n# not in loop:\n#\t' + '\n# '.join(text.split("\n")) error_text = "\n# not in loop:\n#\t" + "\n# ".join(text.split("\n"))
errors.append(error_text) errors.append(error_text)
if hasattr(node, '__repr1__'): if hasattr(node, "__repr1__"):
checker(node, in_loop, errors) checker(node, in_loop, errors)