fix: CapturedIO.__init__ type annotations to accept Optional[StringIO]#15172
Merged
Conversation
Carreau
approved these changes
Apr 10, 2026
Member
|
thanks ! |
Carreau
added a commit
that referenced
this pull request
Apr 23, 2026
- Fill out whatsnew/version9.rst with all 6 milestone PRs: terminal image rendering via Kitty protocol (#15184), Python 3.11 support restoration (#15175), theme-aware color fix (#15156), CapturedIO type annotation fix (#15172), docs and contributing improvements - Mark release.py as a full release (_version_extra = "") https://claude.ai/code/session_016yXG8tqxaMuYxyw2bqZBEP
pull Bot
pushed a commit
to Stars1233/ipython
that referenced
this pull request
Apr 23, 2026
- Fill out whatsnew/version9.rst with all 6 milestone PRs: terminal image rendering via Kitty protocol (ipython#15184), Python 3.11 support restoration (ipython#15175), theme-aware color fix (ipython#15156), CapturedIO type annotation fix (ipython#15172), docs and contributing improvements - Mark release.py as a full release (_version_extra = "") https://claude.ai/code/session_016yXG8tqxaMuYxyw2bqZBEP
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.
Problem
CapturedIO.__init__declares itsstdoutandstderrparameters asStringIO, butcapture_output.__enter__passesNonefor either parameter when the corresponding capture flag isFalse:The runtime behaviour is correct — the
stdoutandstderrproperties already handleNonegracefully:But the type annotations don't reflect this, causing false positives in static analysis tools.
Origin
The incorrect annotation was introduced in IPython 9.12.0 via 74904ca ("Extend MonkeyType annotations to terminal, testing, and more utils modules"). MonkeyType infers types from runtime traces, and the tracing run apparently never exercised the
capture_output(stdout=False)orcapture_output(stderr=False)paths — so it only observedStringIObeing passed, neverNone.How to reproduce
Run pyright 1.1.396+ on any code that constructs
CapturedIOwithNonearguments, or on IPython's owncapture_output.__enter__:Note: this is not caught by IPython's own mypy CI because
IPython.utils.captureis listed in the mypy overrides inpyproject.tomlwithignore_errors = true.Fix
stdout: StringIO→stdout: Optional[StringIO](same forstderr) inCapturedIO.__init__.CapturedIO(None, None)and asserts the expected empty-string behaviour. Existing tests (test_capture_output_no_stdout,test_capture_output_no_stderr) exercise theNonepath indirectly viacapture_output, but never constructCapturedIOdirectly withNone.No runtime behaviour change.
Fixes #15181