{{ message }}
Repository navigation
Conversation
The outer exception handler in get_tokens_unprocessed() called error_till_line_end() but dropped the position it returns, so start and end stayed where they were and the loop returned to the same offset. With ensurenl=False, a malformed input without a trailing newline therefore never terminated. Assign the returned position, as the other five call sites do. The new test bounds the error recovery so that the unpatched lexer fails instead of hanging, and checks that the token stream still round-trips.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

What
Fixes #3418 — the
TNTLexernever terminates on malformed input without a trailing newline whenensurenl=False.The outer
except IndexError:handler inget_tokens_unprocessed()calledself.error_till_line_end(start, text)but dropped the position that call returns.startandendtherefore stayed where they were, and thewhile start <= end < len(text)loop came back to the same offset forever. Every other call site in the lexer assigns the returned position.The fix is that one line:
error_till_line_end()always returns a position paststart(it either stops at the newline or runs to the end of the text), so the recovery now always makes progress.Tests
tests/test_tnt.pygainstest_error_recovery_progress, which is the test sketched in the issue: it replaceserror_till_line_endon the instance with a wrapper that raises when the same(start, source)recovery state is seen twice. The unpatched lexer therefore fails the test instead of hanging, and the test also checks that the token stream still round-trips to the input.Verified locally:
pytest -q --ignore=tests/contrast— 5333 passed, 16 skippedpytest tests/test_tnt.py— 73 passedruff check --ignore UP031 .,scripts/check_crlf.py,scripts/detect_missing_analyse_text.py --skip-no-aliases,scripts/check_sources.py,scripts/count_token_references.py— all clean@archetelos — your report asked whether such a pull request would be welcome, so this is the one-line change plus the test as you sketched it. The open policy question from the issue (whether
ensurenl=Falseshould be supported for this lexer, or whether returning error tokens is the right answer) is left to you and the maintainers: the change here only makes the existing error path terminate and does not alter the tokens produced for well-formed input.AI usage disclosure: the fix and the test were prepared with AI assistance, based on the analysis in the issue; all test results above were produced locally and reviewed.