|
2 | 2 |
|
3 | 3 | import logging |
4 | 4 | import traceback |
| 5 | +from contextlib import contextmanager |
5 | 6 | from dataclasses import dataclass, field |
6 | 7 | from functools import cached_property |
7 | 8 | from pathlib import Path |
|
31 | 32 | _lark = lark.Lark(_grammar, propagate_positions=True, strict=True) |
32 | 33 |
|
33 | 34 |
|
34 | | -def _find_one_token(tree: lark.Tree, *, name: str) -> lark.Token: |
| 35 | +def _find_one_token(tree, *, name): |
35 | 36 | """Find token with a specific type name in tree. |
36 | 37 |
|
37 | 38 | Parameters |
@@ -285,25 +286,13 @@ def doctype_to_annotation(self, doctype): |
285 | 286 | A set containing tuples. Each tuple contains a qualname, its start and its |
286 | 287 | end index relative to the given `doctype`. |
287 | 288 | """ |
288 | | - try: |
289 | | - self._collected_imports = set() |
290 | | - self._unknown_qualnames = [] |
| 289 | + with self._prepare_transformation(): |
291 | 290 | tree = _lark.parse(doctype) |
292 | 291 | value = super().transform(tree=tree) |
293 | 292 | annotation = Annotation( |
294 | 293 | value=value, imports=frozenset(self._collected_imports) |
295 | 294 | ) |
296 | 295 | return annotation, self._unknown_qualnames |
297 | | - except ( |
298 | | - lark.exceptions.LexError, |
299 | | - lark.exceptions.ParseError, |
300 | | - QualnameIsKeyword, |
301 | | - ): |
302 | | - self.stats["syntax_errors"] += 1 |
303 | | - raise |
304 | | - finally: |
305 | | - self._collected_imports = None |
306 | | - self._unknown_qualnames = None |
307 | 296 |
|
308 | 297 | def qualname(self, tree): |
309 | 298 | """ |
@@ -509,6 +498,29 @@ def __default__(self, data, children, meta): |
509 | 498 | out = children |
510 | 499 | return out |
511 | 500 |
|
| 501 | + @contextmanager |
| 502 | + def _prepare_transformation(self): |
| 503 | + """Reset transformation state before entering context and restore it on exit.""" |
| 504 | + collected_imports = self._collected_imports |
| 505 | + unknown_qualnames = self._unknown_qualnames |
| 506 | + |
| 507 | + try: |
| 508 | + self._collected_imports = set() |
| 509 | + self._unknown_qualnames = [] |
| 510 | + yield |
| 511 | + |
| 512 | + except ( |
| 513 | + lark.exceptions.LexError, |
| 514 | + lark.exceptions.ParseError, |
| 515 | + QualnameIsKeyword, |
| 516 | + ): |
| 517 | + self.stats["syntax_errors"] += 1 |
| 518 | + raise |
| 519 | + |
| 520 | + finally: |
| 521 | + self._collected_imports = collected_imports |
| 522 | + self._unknown_qualnames = unknown_qualnames |
| 523 | + |
512 | 524 | def _match_import(self, qualname, *, meta): |
513 | 525 | """Match `qualname` to known imports or alias to "Incomplete". |
514 | 526 |
|
|
0 commit comments