Skip to content

Implement termios.tcgetwinsize/tcsetwinsize#8347

Draft
sigmaith wants to merge 5 commits into
RustPython:mainfrom
sigmaith:termios
Draft

Implement termios.tcgetwinsize/tcsetwinsize#8347
sigmaith wants to merge 5 commits into
RustPython:mainfrom
sigmaith:termios

Conversation

@sigmaith

@sigmaith sigmaith commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Summary

The termios module was missing tcgetwinsize/tcsetwinsize, so calling termios.tcgetwinsize(fd) raised AttributeError. This PR adds both functions, following CPython's implementation Modules/termios.c#L417-L444:

  • crates/host_env/src/termios.rs: low-level ioctl(TIOCGWINSZ/TIOCSWINSZ) wrappers
  • crates/stdlib/src/termios.rs: #[pyfunction]s that expose them to Python, reusing the existing Fildes fd conversion and termios_error helper
  • Lib/test/test_termios.py: removes the expectedFailure markers for test_tcgetwinsize, test_tcgetwinsize_errors, test_tcsetwinsize, test_tcsetwinsize_errors, which now pass

Summary by CodeRabbit

  • New Features
    • Added termios.tcgetwinsize() to retrieve terminal window dimensions.
    • Added termios.tcsetwinsize() to update terminal window dimensions.
    • Added validation for window size input and clear errors for invalid values or terminal operations.

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
Copilot AI review requested due to automatic review settings July 22, 2026 13:02
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: d66e4830-b2ab-464c-806c-44237ebe1e5c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds terminal window-size retrieval and update functions to the host termios layer and exposes them through Python’s termios module with input validation and error translation.

Changes

Terminal window sizing

Layer / File(s) Summary
Host window-size ioctl helpers
crates/host_env/src/termios.rs
Adds functions to retrieve and apply terminal rows and columns using TIOCGWINSZ and TIOCSWINSZ, mapping ioctl failures to OS errors.
Python termios bindings
crates/stdlib/src/termios.rs
Exports tcgetwinsize and tcsetwinsize, validates the two-element size input, and converts host errors to Python termios errors.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: copilot, youknowone

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding termios.tcgetwinsize and tcsetwinsize.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

📦 Library Dependencies

The following Lib/ modules were modified. Here are their dependencies:

[x] test: cpython/Lib/test/test_termios.py (TODO: 1)

dependencies:

dependent tests: (8 tests)

  • termios: test_getpass test_pyrepl
    • getpass:
      • imaplib: test_imaplib
    • tty: test_asyncio test_pty test_sundry
      • pty: test_builtin test_repl

Legend:

  • [+] path exists in CPython
  • [x] up-to-date, [ ] outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 in crates/host_env.
  • Exposed tcgetwinsize/tcsetwinsize as #[pyfunction]s in the termios stdlib module.
  • Removed @unittest.expectedFailure markers 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.

Comment thread crates/stdlib/src/termios.rs Outdated
Comment thread crates/host_env/src/termios.rs Outdated
Comment thread crates/host_env/src/termios.rs Outdated
Comment thread crates/host_env/src/termios.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between dd9bce5 and d09e9b8.

⛔ Files ignored due to path filters (1)
  • Lib/test/test_termios.py is excluded by !Lib/**
📒 Files selected for processing (2)
  • crates/host_env/src/termios.rs
  • crates/stdlib/src/termios.rs

Comment thread crates/stdlib/src/termios.rs Outdated
Comment thread crates/stdlib/src/termios.rs Outdated
@sigmaith
sigmaith marked this pull request as draft July 22, 2026 13:16
sigmaith and others added 2 commits July 22, 2026 22:18
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
Copilot AI review requested due to automatic review settings July 22, 2026 13:26

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment thread crates/stdlib/src/termios.rs Outdated
Comment thread crates/stdlib/src/termios.rs Outdated
`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
Copilot AI review requested due to automatic review settings July 22, 2026 14:16

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copilot AI review requested due to automatic review settings July 23, 2026 06:17

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants