Skip to content

gh-144259: Fix Windows EOL wrap by syncing real console cursor #144297

Closed
hyongtao-code wants to merge 14 commits intopython:mainfrom
hyongtao-code:fix-issue-144259
Closed

gh-144259: Fix Windows EOL wrap by syncing real console cursor #144297
hyongtao-code wants to merge 14 commits intopython:mainfrom
hyongtao-code:fix-issue-144259

Conversation

@hyongtao-code
Copy link
Contributor

@hyongtao-code hyongtao-code commented Jan 28, 2026

Long log:

Windows VT terminals do not consistently wrap the cursor when a line
exactly fills the terminal width.
Previously we assumed a wrap always happened, which could desynchronize
the logical cursor from the real console cursor and break subsequent
cursor movement.
This change queries the real cursor position and updates posxy
accordingly, and adds regression tests for both wrap and no-wrap cases.

Video with the patch

fix-issue-144259-V2.mp4

Signed-off-by: Yongtao Huang yongtaoh2022@gmail.com

Windows VT terminals do not consistently wrap the cursor when a line
exactly fills the terminal width.
Previously we assumed a wrap always happened, which could desynchronize
the logical cursor from the real console cursor and break subsequent
cursor movement.
This change queries the real cursor position and updates posxy
accordingly, and adds regression tests for both wrap and no-wrap cases.

Signed-off-by: Yongtao Huang <yongtaoh2022@gmail.com>
Co-authored-by: Chris Eibl <138194463+chris-eibl@users.noreply.github.com>
@hyongtao-code hyongtao-code changed the title gh-144259: Fix Windows VT EOL wrap by syncing real console cursor gh-144259: Fix Windows EOL wrap by syncing real console cursor Feb 1, 2026
@hyongtao-code
Copy link
Contributor Author

Thanks for the review! I agree with your point, so I’ve removed the VT-specific references and updated the tests to exercise both VT and legacy console modes.

Fall back gracefully when querying the console cursor fails with
an invalid handle, instead of raising an exception.

Failed link: https://github.com/python/cpython/actions/runs/21563046527/job/62130029686?pr=144297
@chris-eibl
Copy link
Member

As you've seen, many Windows tests fail now, because in headless mode GetConsoleScreenBufferInfo() fails with The handle is invalid.

Instead of swallowing the error, maybe introduce something like

_HasWrappedToNextRow(self, y)

Then, we can simply mock this for most of the tests.

And you can also write an explicit test for _HasWrappedToNextRow by mocking the "bare" GetConsoleScreenBufferInfo() just for this one test?

@hyongtao-code
Copy link
Contributor Author

Thanks for the suggestion — these failed cases were indeed quite tricky. I decided to follow your proposed approach to fix the failing cases.

hyongtao-code and others added 4 commits February 2, 2026 00:40
Co-authored-by: Chris Eibl <138194463+chris-eibl@users.noreply.github.com>
Co-authored-by: Chris Eibl <138194463+chris-eibl@users.noreply.github.com>
@hyongtao-code
Copy link
Contributor Author

Thanks for the review and guidance. With mocks, we can preserve the original logic and avoid hacky workarounds for CI-specific failures.

@chris-eibl chris-eibl self-requested a review February 2, 2026 20:05
@hyongtao-code
Copy link
Contributor Author

Thanks for your patience.

@chris-eibl
Copy link
Member

Thanks for your patience and contribution.
This lgtm now and is ready for a core dev review.

@chris-eibl
Copy link
Member

#140333 fixes this, too. Both PRs fix both issues for me.
@hyongtao-code + @tanloong: can you verify?

#140333 does not need to call GetConsoleScreenBufferInfo() and looks simpler, but it lacks tests ...

@tanloong
Copy link
Contributor

tanloong commented Feb 9, 2026

Yes, I tried and #140333 also fixes #144259. I once added tests to #140333 but failed and reverted. I would like to try adding again.

@hyongtao-code
Copy link
Contributor Author

Both PRs fix both issues for me.

Oh, thanks! I think both approaches address the issue. Since @tanloong ’s PR is more concise and came earlier, I’ve decided to close my PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants