Show More
@@ -97,14 +97,22 b' class _AsyncSyntaxErrorVisitor(ast.NodeVisitor):' | |||||
97 | the implementation involves wrapping the repl in an async function, it |
|
97 | the implementation involves wrapping the repl in an async function, it | |
98 | is erroneously allowed (e.g. yield or return at the top level) |
|
98 | is erroneously allowed (e.g. yield or return at the top level) | |
99 | """ |
|
99 | """ | |
|
100 | def __init__(self): | |||
|
101 | self.depth = 0 | |||
|
102 | super().__init__() | |||
100 |
|
103 | |||
101 | def generic_visit(self, node): |
|
104 | def generic_visit(self, node): | |
102 | func_types = (ast.FunctionDef, ast.AsyncFunctionDef) |
|
105 | func_types = (ast.FunctionDef, ast.AsyncFunctionDef) | |
103 | invalid_types = (ast.Return, ast.Yield, ast.YieldFrom) |
|
106 | invalid_types_by_depth = { | |
104 |
|
107 | 0: (ast.Return, ast.Yield, ast.YieldFrom), | ||
105 | if isinstance(node, func_types): |
|
108 | 1: (ast.Nonlocal,) | |
106 | return # Don't recurse into functions |
|
109 | } | |
107 | elif isinstance(node, invalid_types): |
|
110 | ||
|
111 | should_traverse = self.depth < max(invalid_types_by_depth.keys()) | |||
|
112 | if isinstance(node, func_types) and should_traverse: | |||
|
113 | self.depth += 1 | |||
|
114 | super().generic_visit(node) | |||
|
115 | elif isinstance(node, invalid_types_by_depth[self.depth]): | |||
108 | raise SyntaxError() |
|
116 | raise SyntaxError() | |
109 | else: |
|
117 | else: | |
110 | super().generic_visit(node) |
|
118 | super().generic_visit(node) |
@@ -227,6 +227,35 b' if sys.version_info > (3, 5):' | |||||
227 | else: |
|
227 | else: | |
228 | iprc(cell) |
|
228 | iprc(cell) | |
229 |
|
229 | |||
|
230 | def test_nonlocal(self): | |||
|
231 | # fails if outer scope is not a function scope or if var not defined | |||
|
232 | with self.assertRaises(SyntaxError): | |||
|
233 | iprc("nonlocal x") | |||
|
234 | iprc(""" | |||
|
235 | x = 1 | |||
|
236 | def f(): | |||
|
237 | nonlocal x | |||
|
238 | x = 10000 | |||
|
239 | yield x | |||
|
240 | """) | |||
|
241 | iprc(""" | |||
|
242 | def f(): | |||
|
243 | def g(): | |||
|
244 | nonlocal x | |||
|
245 | x = 10000 | |||
|
246 | yield x | |||
|
247 | """) | |||
|
248 | ||||
|
249 | # works if outer scope is a function scope and var exists | |||
|
250 | iprc(""" | |||
|
251 | def f(): | |||
|
252 | x = 20 | |||
|
253 | def g(): | |||
|
254 | nonlocal x | |||
|
255 | x = 10000 | |||
|
256 | yield x | |||
|
257 | """) | |||
|
258 | ||||
230 |
|
259 | |||
231 | def test_execute(self): |
|
260 | def test_execute(self): | |
232 | iprc(""" |
|
261 | iprc(""" |
General Comments 0
You need to be logged in to leave comments.
Login now