Guard get_ipython() being Optional (fixes mypy on master) - #1088
Merged
Conversation
The linters workflow has been failing on master since IPython 9.16 started annotating get_ipython() as returning Optional[InteractiveShell] (history_manager is optional too). mypy 2.3 reports four union-attr errors in scalene_tracing.py and scalene_magics.py; the existing "type: ignore[no-untyped-call, unused-ignore]" on those lines does not cover that error code, and says so. No commit caused this -- master's last linters run (2026-07-05) passed and nothing has landed since, so it broke when CI's unpinned "pip install mypy ruff ..." picked up the newer versions. Guard both levels. _handle_jupyter_cell() returns False without a live shell, falling through to the ordinary filename rules, which is the behavior it already had when the cell regex didn't match. run_code() prints a plain message and returns; neither value can actually be None there, since a magic only runs inside a live shell. The ignore comments stay put: on older IPython, get_ipython() is untyped, so no-untyped-call still applies, and unused-ignore keeps the comment valid once it doesn't. Verified in a venv pinned to CI's exact versions (mypy 2.3.0, IPython 9.16.0): 4 errors before, clean after, ruff clean. Also re-checked against the older pair (mypy 1.19.0, IPython 9.9.0) so the fix holds in both directions. Behavior spot-checked for all three shapes -- live shell (recovers the cell and returns True), get_ipython() None, and history_manager None. Full pytest suite: 442 passed, 13 skipped. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
emeryberger
added a commit
that referenced
this pull request
Jul 31, 2026
Picks up the get_ipython() Optional guard (#1088) so this branch's linters check runs against a fixed master.
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.
The
lintersworkflow is failing on master, independently of any PR.IPython 9.16 annotates
get_ipython()as returningOptional[InteractiveShell], andhistory_manageris itself optional. mypy 2.3 therefore reports fourunion-attrerrors inscalene_tracing.py:157andscalene_magics.py:43. The existing# type: ignore[no-untyped-call, unused-ignore]on those lines doesn't cover that error code — mypy says so explicitly:No commit caused this. Master's last
lintersrun was 2026-07-05 and passed, and nothing has landed since — it broke on its own when CI's unpinnedpip install mypy ruff types-PyYAML pydanticstarted resolving newer versions. Confirmed by dispatching the workflow against unmodified master: run 30640136643 fails with the identical four errors.Fix
Guard both levels — the shell and its history manager:
_handle_jupyter_cell()returnsFalsewithout a live shell, falling through to the ordinary filename rules. That's the behavior it already had when the cell regex didn't match.run_code()prints a plain message and returns. Neither value can really beNonethere — a magic only runs inside a live shell — so this exists to satisfy the type checker without anAttributeErroras the fallback.The
# type: ignorecomments stay: on older IPythonget_ipython()is untyped, sono-untyped-callstill applies, andunused-ignorekeeps the comment valid once it no longer does.Verification
Success: no issues found in 66 source filesafter.ruff check scaleneclean.scalene_signal_manager.py:314one that mypy 2.3 doesn't flag.True),get_ipython()returningNone, andhistory_managerbeingNone— the last two return cleanly instead of raising.Found while checking CI on #1087, which is blocked by this same failure.
🤖 Generated with Claude Code