##// END OF EJS Templates
Improve async detection mechanism with blacklist...
Paul Ganssle -
Show More
@@ -80,6 +80,40 b' def _asyncify(code: str) -> str:'
80 return res
80 return res
81
81
82
82
83 class _AsyncSyntaxErrorVisitor(ast.NodeVisitor):
84 """
85 Find syntax errors that would be an error in an async repl, but because
86 the implementation involves wrapping the repl in an async function, it
87 is erroneously allowed (e.g. yield or return at the top level)
88 """
89 def generic_visit(self, node):
90 func_types = (ast.FunctionDef, ast.AsyncFunctionDef)
91 invalid_types = (ast.Return, ast.Yield, ast.YieldFrom)
92
93 if isinstance(node, func_types):
94 return # Don't recurse into functions
95 elif isinstance(node, invalid_types):
96 raise SyntaxError()
97 else:
98 super().generic_visit(node)
99
100
101 def _async_parse_cell(cell: str) -> ast.AST:
102 """
103 This is a compatibility shim for pre-3.7 when async outside of a function
104 is a syntax error at the parse stage.
105
106 It will return an abstract syntax tree parsed as if async and await outside
107 of a function were not a syntax error.
108 """
109 if sys.version_info < (3, 7):
110 # Prior to 3.7 you need to asyncify before parse
111 wrapped_parse_tree = ast.parse(_asyncify(cell))
112 return wrapped_parse_tree.body[0].body[0]
113 else:
114 return ast.parse(cell)
115
116
83 def _should_be_async(cell: str) -> bool:
117 def _should_be_async(cell: str) -> bool:
84 """Detect if a block of code need to be wrapped in an `async def`
118 """Detect if a block of code need to be wrapped in an `async def`
85
119
@@ -99,8 +133,12 b' def _should_be_async(cell: str) -> bool:'
99 return False
133 return False
100 except SyntaxError:
134 except SyntaxError:
101 try:
135 try:
102 ast.parse(_asyncify(cell))
136 parse_tree = _async_parse_cell(cell)
103 # TODO verify ast has not "top level" return or yield.
137
138 # Raise a SyntaxError if there are top-level return or yields
139 v = _AsyncSyntaxErrorVisitor()
140 v.visit(parse_tree)
141
104 except SyntaxError:
142 except SyntaxError:
105 return False
143 return False
106 return True
144 return True
General Comments 0
You need to be logged in to leave comments. Login now