Whole file

lark-parser/lark

The author described this change as Fix types for tree_templates, better error messages. It counts as a record because the check below fails on the code as it stood at 66c22d001 and passes on 242c4a574, with nothing else changed between the two runs.

Fix saved2022-05-24
Sharing licenceMIT · LICENSE
Change size+15 5

What the code was meant to do, written into the code itself as a save note

Fix types for tree_templates, better error messages

The change

99 from lark import Tree, Transformer
1010 from lark.exceptions import MissingVariableError
1111
12+Branch = Union[Tree[str], str]
1213 TreeOrCode = Union[Tree[str], str]
14+MatchResult = Dict[str, Tree]
1315 _TEMPLATE_MARKER = '$'
1416
1517
1719 """Template Configuration
1820
1921 Allows customization for different uses of Template
22+
23+ parse() must return a Tree instance.
2024 """
2125
2226 def __init__(self, parse=None):
4953 assert self._parse
5054 template = self._parse(template)
5155
52- assert isinstance(template, Tree)
56+ if not isinstance(template, Tree):
57+ raise TypeError("template parser must return a Tree instance")
58+
5359 return template
5460
5561 def __call__(self, template: Tree[str]) -> 'Template':
5662 return Template(template, conf=self)
5763
58- def _match_tree_template(self, template: TreeOrCode, tree: TreeOrCode) -> Optional[Dict[str, TreeOrCode]]:
64+ def _match_tree_template(self, template: TreeOrCode, tree: Branch) -> Optional[MatchResult]:
65+ """Returns dict of {var: match} if found a match, else None
66+ """
5967 template_var = self.test_var(template)
6068 if template_var:
69+ if not isinstance(tree, Tree):
70+ raise TypeError(f"Template variables can only match Tree instances. Not {tree}")
6171 return {template_var: tree}
6272
6373 if isinstance(template, str):
100110
101111
102112 class Template:
103- """Represents a tree templates, tied to a specific configuration
113+ """Represents a tree template, tied to a specific configuration
104114
105115 A tree template is a tree that contains nodes that are template variables.
106116 Those variables will match any tree.
111121 self.conf = conf
112122 self.tree = conf._get_tree(tree)
113123
114- def match(self, tree: TreeOrCode) -> Optional[Dict[str, TreeOrCode]]:
124+ def match(self, tree: TreeOrCode) -> Optional[MatchResult]:
115125 """Match a tree template to a tree.
116126
117127 A tree template without variables will only match ``tree`` if it is equal to the template.
127137 tree = self.conf._get_tree(tree)
128138 return self.conf._match_tree_template(self.tree, tree)
129139
130- def search(self, tree: TreeOrCode) -> Iterator[Tuple[Tree[str], Dict[str, TreeOrCode]]]:
140+ def search(self, tree: TreeOrCode) -> Iterator[Tuple[Tree[str], MatchResult]]:
131141 """Search for all occurances of the tree template inside ``tree``.
132142 """
133143 tree = self.conf._get_tree(tree)

The check that tells the two apart

failpass·tests/test_tree_templates.py::TestTreeTemplatesConf::test_template_match__only_tree

Check file tests/test_tree_templates.py, taken without changes from the fix and copied onto the older code, so the exact same check runs against both versions.

Origin and history

The code before it66c22d0019170ad4d6bfb45e881776e0dad32625
Broken version dated2022-05-24
Modulelark.tree_templates
Units changedTemplate, TemplateConf
Fingerprint83d9d0d77f91583e
Checked2026-08-18 by goldset/0.1

Every field above is generated by our program. None of it is written by hand.

Other bugs found in lark-parser/lark