Skip to content

Conversation

@shiva-sai-824
Copy link

Fixes #20590

When using 'is' operator or match/case patterns to check type objects of @Final classes, mypy now properly narrows the types since @Final classes cannot have subclasses at runtime.

Changes:

  • typeops.py: Updated is_singleton_identity_type() to recognize CallableType and TypeType representing @Final class constructors as singleton types for identity-based narrowing
  • checker.py: Modified narrowing logic to:
    1. Allow @Final class type objects in narrowable_operand check
    2. Preserve else-branch narrowing for @Final class identity checks since no subclasses can exist

This enables exhaustiveness checking with assert_never() when all @Final class cases are handled in if/elif or match/case branches.

Fixes python#20590

When using 'is' operator or match/case patterns to check type objects
of @Final classes, mypy now properly narrows the types since @Final
classes cannot have subclasses at runtime.

Changes:
- typeops.py: Updated is_singleton_identity_type() to recognize
  CallableType and TypeType representing @Final class constructors
  as singleton types for identity-based narrowing
- checker.py: Modified narrowing logic to:
  1. Allow @Final class type objects in narrowable_operand check
  2. Preserve else-branch narrowing for @Final class identity checks
     since no subclasses can exist

This enables exhaustiveness checking with assert_never() when all
@Final class cases are handled in if/elif or match/case branches.
@shiva-sai-824 shiva-sai-824 force-pushed the fix-final-class-type-narrowing branch from a0e722e to 7b928ed Compare January 21, 2026 20:38
@shiva-sai-824
Copy link
Author

@p-sawicki , @JukkaL , @hauntsaninja , @ilevkivskyi can you guys please review this one ?

@hauntsaninja
Copy link
Collaborator

I'm in the middle of landing large refactoring to narrowing, so this will need to wait

A correct change would be simpler (and also have tests)

@github-actions
Copy link
Contributor

Diff from mypy_primer, showing the effect of this PR on open source code:

pytest (https://github.com/pytest-dev/pytest)
+ src/_pytest/raises.py:1486: error: Unused "type: ignore" comment  [unused-ignore]

trio (https://github.com/python-trio/trio)
+ src/trio/_core/_local.py:54: error: Unused "type: ignore" comment  [unused-ignore]
+ src/trio/_core/_local.py:57: error: Unused "type: ignore" comment  [unused-ignore]

isort (https://github.com/pycqa/isort)
+ isort/settings.py:893: error: Argument 2 to "isinstance" has incompatible type "Callable[[str], Any] | type[Any]"; expected "_ClassInfo"  [arg-type]

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.

Narrowing types does not consider the @final decorator

2 participants