Implement termios.tcgetwinsize/tcsetwinsize#8347
Conversation
Adds ioctl(TIOCGWINSZ/TIOCSWINSZ) wrappers in host_env and the corresponding Python-facing functions in the termios stdlib module, removing the associated expectedFailure markers in test_termios.py. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RbzcYLnX5tMfTM9BP7FDTT
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughAdds terminal window-size retrieval and update functions to the host termios layer and exposes them through Python’s ChangesTerminal window sizing
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
📦 Library DependenciesThe following Lib/ modules were modified. Here are their dependencies: [x] test: cpython/Lib/test/test_termios.py (TODO: 1) dependencies: dependent tests: (8 tests)
Legend:
|
There was a problem hiding this comment.
Pull request overview
This PR implements the missing termios.tcgetwinsize() / termios.tcsetwinsize() APIs in RustPython so Python code can query and set terminal window size, and it unblocks upstream Lib/test/test_termios.py tests that were previously marked as expected failures due to AttributeError.
Changes:
- Added low-level
ioctl(TIOCGWINSZ/TIOCSWINSZ)wrappers incrates/host_env. - Exposed
tcgetwinsize/tcsetwinsizeas#[pyfunction]s in thetermiosstdlib module. - Removed
@unittest.expectedFailuremarkers for the newly-working termios winsize tests.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| Lib/test/test_termios.py | Removes expectedFailure decorators now that winsize APIs exist and tests pass. |
| crates/stdlib/src/termios.rs | Adds Python-facing tcgetwinsize/tcsetwinsize bindings on top of host termios support. |
| crates/host_env/src/termios.rs | Adds platform-level ioctl wrappers to get/set terminal window size. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@crates/stdlib/src/termios.rs`:
- Around line 281-283: Update the size extraction in tcsetwinsize to use a
tuple/list-only conversion instead of extract_elements_with, rejecting
dictionaries and other iterables while preserving the existing two-element
validation and error behavior.
- Around line 285-292: Update the row and col conversion logic in the
tcsetwinsize implementation to use the VM’s index-protocol conversion rather
than direct PyInt downcasts, accepting integer-like objects implementing
__index__. Normalize every conversion failure, including negative or otherwise
out-of-range values, to OverflowError while preserving the existing winsize
validation behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: 5975d213-b9d3-41d1-8919-28c91cbd4bf7
⛔ Files ignored due to path filters (1)
Lib/test/test_termios.pyis excluded by!Lib/**
📒 Files selected for processing (2)
crates/host_env/src/termios.rscrates/stdlib/src/termios.rs
POSIX ioctl only guarantees -1 on failure, not exactly 0 on success; matches the existing check_libc_neg convention used elsewhere in host_env (e.g. fcntl.rs, posix.rs::get_terminal_size). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RbzcYLnX5tMfTM9BP7FDTT
extract_elements_with also accepted dicts (treating keys as elements). Switch to try_sequence(), matching CPython's PySequence_Check, so only real sequences (tuple/list/etc.) are accepted. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RbzcYLnX5tMfTM9BP7FDTT
`std::mem` just re-exports `core::mem`, but clippy prefers importing from core when there's no OS dependency. This was breaking the wasm CI build. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RbzcYLnX5tMfTM9BP7FDTT
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
crates/stdlib/src/termios.rs:292
- tcsetwinsize currently requires both winsize items to be actual PyInt objects via downcast_ref::(), which rejects valid int-like inputs (e.g. objects implementing index, and bool). CPython uses PyLong_AsLong for each item, which accepts index and bool, so this is a behavior incompatibility.
let row: u16 = row
.downcast_ref::<PyInt>()
.ok_or_else(|| vm.new_type_error("tcsetwinsize: winsize values must be integers"))?
.try_to_primitive(vm)?;
let col: u16 = col
CPython's PyLong_AsLong calls __index__ on non-int objects before converting, so downcast_ref::<PyInt> was stricter than CPython. try_index matches that behavior and is more concise. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RbzcYLnX5tMfTM9BP7FDTT
Summary
The termios module was missing
tcgetwinsize/tcsetwinsize, so callingtermios.tcgetwinsize(fd)raisedAttributeError. This PR adds both functions, following CPython's implementation Modules/termios.c#L417-L444:Summary by CodeRabbit
termios.tcgetwinsize()to retrieve terminal window dimensions.termios.tcsetwinsize()to update terminal window dimensions.