Skip to content

Fix mypy type narrowing false positive in cfg.py#190

Merged
MatthieuDartiailh merged 4 commits intomainfrom
copilot/fix-ci-failure-main
Apr 3, 2026
Merged

Fix mypy type narrowing false positive in cfg.py#190
MatthieuDartiailh merged 4 commits intomainfrom
copilot/fix-ci-failure-main

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 3, 2026

mypy 1.20.0 CI lint job fails due to type narrowing behavior: when evaluating te.entry is self._current_try_begin, mypy narrows te.entry from TryBegin to TryBegin | None because the RHS (self._current_try_begin) is Optional[TryBegin].

Change

  • src/bytecode/cfg.py: Add explicit self._current_try_begin is not None guard before the identity comparison, giving mypy enough information to narrow both sides correctly:
# Before
) and te.entry is self._current_try_begin:

# After
) and self._current_try_begin is not None and te.entry is self._current_try_begin:

Semantically equivalent — the identity check can never be True when self._current_try_begin is None.

…dentity comparison

Agent-Logs-Url: https://github.com/MatthieuDartiailh/bytecode/sessions/b7904bd0-bbc8-412f-8f14-de2ed29696a1

Co-authored-by: MatthieuDartiailh <4481740+MatthieuDartiailh@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix current CI failure on main branch Fix mypy type narrowing false positive in cfg.py Apr 3, 2026
Copilot AI requested a review from MatthieuDartiailh April 3, 2026 10:42
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 3, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.16%. Comparing base (1757c49) to head (29a1e71).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #190   +/-   ##
=======================================
  Coverage   95.16%   95.16%           
=======================================
  Files           7        7           
  Lines        2028     2028           
  Branches      449      449           
=======================================
  Hits         1930     1930           
  Misses         54       54           
  Partials       44       44           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

# through a particular jump. So we are lenient here.
if (
te := self.block.get_trailing_try_end(i)
) and te.entry is self._current_try_begin:
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

TryEnd.entry cannot be None so the error from Mypy is weird. Could you try flipping the test around self._current_try_begin is te.entry to see if it satisfies Mypy ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Tried flipping to self._current_try_begin is te.entry — it produces the same 3 errors. The root cause is mypy's identity-narrowing behavior: when evaluating x is y where y is Optional[T], mypy narrows x into T | None in the truthy branch (reasoning: if y were None and x is y is True, then x must also be None). This applies regardless of which side the optional is on.

You're right that TryEnd.entry can never actually be None — but mypy doesn't exploit that to suppress the narrowing. The explicit is not None guard is the minimal fix that teaches mypy self._current_try_begin is non-None before the identity check, preventing the spurious narrowing of te.entry.

Copy link
Copy Markdown
Owner

@MatthieuDartiailh MatthieuDartiailh Apr 3, 2026

Choose a reason for hiding this comment

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

@copilot Did you try of just assume the behavior ? Also be mindful of the formatting which is currently erroring in CI

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I did try it — flipped to self._current_try_begin is te.entry produces the same errors. Mypy's identity narrowing widens the non-optional operand to include None regardless of which side of is it's on, so the is not None guard is required.

The formatting issue has been fixed in commit 7702d3e — black now reformats the walrus-operator if condition and the ternary expression to use the parenthesised multi-line style it expects.

Copy link
Copy Markdown
Owner

@MatthieuDartiailh MatthieuDartiailh left a comment

Choose a reason for hiding this comment

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

Address the formatting issue identified by the CI (lint job)

@MatthieuDartiailh
Copy link
Copy Markdown
Owner

@copilot fix the formatting issue

Agent-Logs-Url: https://github.com/MatthieuDartiailh/bytecode/sessions/8ed3b0c7-8cc3-4d4c-9421-7a291774fbd9

Co-authored-by: MatthieuDartiailh <4481740+MatthieuDartiailh@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 3, 2026

Address the formatting issue identified by the CI (lint job)

Fixed in commit 7702d3e — ran black on cfg.py to apply the required formatting changes.

@copilot fix the formatting issue

Done in commit 7702d3e.

@MatthieuDartiailh MatthieuDartiailh marked this pull request as ready for review April 3, 2026 11:43
@MatthieuDartiailh MatthieuDartiailh merged commit f0378fe into main Apr 3, 2026
10 checks passed
@MatthieuDartiailh MatthieuDartiailh deleted the copilot/fix-ci-failure-main branch April 3, 2026 12:00
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.

3 participants