A visitor that checks if a name is accessed without being declared. This is different from the frame visitor as it will not stop at closure frames.
| 269 | |
| 270 | |
| 271 | class UndeclaredNameVisitor(NodeVisitor): |
| 272 | """A visitor that checks if a name is accessed without being |
| 273 | declared. This is different from the frame visitor as it will |
| 274 | not stop at closure frames. |
| 275 | """ |
| 276 | |
| 277 | def __init__(self, names: t.Iterable[str]) -> None: |
| 278 | self.names = set(names) |
| 279 | self.undeclared: t.Set[str] = set() |
| 280 | |
| 281 | def visit_Name(self, node: nodes.Name) -> None: |
| 282 | if node.ctx == "load" and node.name in self.names: |
| 283 | self.undeclared.add(node.name) |
| 284 | if self.undeclared == self.names: |
| 285 | raise VisitorExit() |
| 286 | else: |
| 287 | self.names.discard(node.name) |
| 288 | |
| 289 | def visit_Block(self, node: nodes.Block) -> None: |
| 290 | """Stop visiting a blocks.""" |
| 291 | |
| 292 | |
| 293 | class CompilerExit(Exception): |