You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Using the official Lark Python parser and using the PythonReconstructor from the examples, list comprehension produces AssertionError when the code is valid Python code.
E.g. The inputs "[a for a in range(10)]" produces the error
The reproduction test script is the code from the example but given the input "[a for a in range(10)]"
This is the full script:
from lark import Token, Lark
from lark.reconstruct import Reconstructor
from lark.indenter import PythonIndenter
# Official Python grammar by Lark
python_parser3 = Lark.open_from_package(
"lark",
"python.lark",
["grammars"],
parser="lalr",
postlex=PythonIndenter(),
start="file_input",
maybe_placeholders=False, # Necessary for reconstructor
)
SPACE_AFTER = set(',+-*/~@<>="|:')
SPACE_BEFORE = (SPACE_AFTER - set(",:")) | set("'")
def special(sym):
return Token("SPECIAL", sym.name)
def postproc(items):
stack = ["\n"]
actions = []
last_was_whitespace = True
for item in items:
if isinstance(item, Token) and item.type == "SPECIAL":
actions.append(item.value)
else:
if actions:
assert actions[0] == "_NEWLINE" and "_NEWLINE" not in actions[1:], actions
for a in actions[1:]:
if a == "_INDENT":
stack.append(stack[-1] + " " * 4)
else:
assert a == "_DEDENT"
stack.pop()
actions.clear()
yield stack[-1]
last_was_whitespace = True
if not last_was_whitespace:
if item[0] in SPACE_BEFORE:
yield " "
yield item
last_was_whitespace = item[-1].isspace()
if not last_was_whitespace:
if item[-1] in SPACE_AFTER:
yield " "
last_was_whitespace = True
yield "\n"
class PythonReconstructor:
def __init__(self, parser):
self._recons = Reconstructor(parser, {"_NEWLINE": special, "_DEDENT": special, "_INDENT": special})
def reconstruct(self, tree):
return self._recons.reconstruct(tree, postproc)
python_reconstructor = PythonReconstructor(python_parser3)
self_contents = "[a for a in range(10)]"
tree = python_parser3.parse(self_contents + "\n")
output = python_reconstructor.reconstruct(tree)
tree_new = python_parser3.parse(output)
print(tree.pretty())
print(tree_new.pretty())
# assert tree.pretty() == tree_new.pretty()
assert tree == tree_new
Running the script produces the described error. Here's the full trace:
Traceback (most recent call last):
File "/Users/ellieyhc/Documents/test/venv/lib/python3.12/site-packages/lark/visitors.py", line 115, in _call_userfunc
f = getattr(self, tree.data)
^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'WriteTokensTransformer' object has no attribute 'list_comprehension'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/ellieyhc/Documents/test/test.py", line 69, in <module>
output = python_reconstructor.reconstruct(tree)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/ellieyhc/Documents/test/test.py", line 61, in reconstruct
return self._recons.reconstruct(tree, postproc)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/ellieyhc/Documents/test/venv/lib/python3.12/site-packages/lark/reconstruct.py", line 102, in reconstruct
for item in x:
^
File "/Users/ellieyhc/Documents/test/test.py", line 28, in postproc
for item in items:
^^^^^
File "/Users/ellieyhc/Documents/test/venv/lib/python3.12/site-packages/lark/reconstruct.py", line 92, in _reconstruct
yield from self._reconstruct(item)
File "/Users/ellieyhc/Documents/test/venv/lib/python3.12/site-packages/lark/reconstruct.py", line 92, in _reconstruct
yield from self._reconstruct(item)
File "/Users/ellieyhc/Documents/test/venv/lib/python3.12/site-packages/lark/reconstruct.py", line 88, in _reconstruct
res = self.write_tokens.transform(unreduced_tree)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/ellieyhc/Documents/test/venv/lib/python3.12/site-packages/lark/visitors.py", line 286, in transform
return self._transform_tree(tree)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/ellieyhc/Documents/test/venv/lib/python3.12/site-packages/lark/visitors.py", line 280, in _transform_tree
return self._call_userfunc(tree)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/ellieyhc/Documents/test/venv/lib/python3.12/site-packages/lark/visitors.py", line 117, in _call_userfunc
return self.__default__(tree.data, children, tree.meta)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/ellieyhc/Documents/test/venv/lib/python3.12/site-packages/lark/reconstruct.py", line 58, in __default__
assert NonTerminal(x.data) == sym, (sym, x)
^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: (NonTerminal('comprehension{test_or_star_expr}'), Tree(Token('RULE', 'comprehension'), [Tree('var', [Tree(Token('RULE', 'name'), [Token('NAME', 'a')])]), Tree(Token('RULE', 'comp_fors'), [Tree(Token('RULE', 'comp_for'), [Tree('var', [Tree(Token('RULE', 'name'), [Token('NAME', 'a')])]), Tree('funccall', [Tree('var', [Tree(Token('RULE', 'name'), [Token('NAME', 'range')])]), Tree(Token('RULE', 'arguments'), [Tree(Token('RULE', 'number'), [Token('DEC_NUMBER', '10')])])])])])]))
The text was updated successfully, but these errors were encountered:
Describe the bug
Using the official Lark Python parser and using the PythonReconstructor from the examples, list comprehension produces
AssertionError
when the code is valid Python code.E.g. The inputs
"[a for a in range(10)]"
produces the errorTo Reproduce
The reproduction test script is the code from the example but given the input
"[a for a in range(10)]"
This is the full script:
Running the script produces the described error. Here's the full trace:
The text was updated successfully, but these errors were encountered: