Skip to content

mypy doesn't narrow Final objects in nested contexts #19080

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ktbarrett opened this issue May 12, 2025 · 0 comments · Fixed by #19083
Closed

mypy doesn't narrow Final objects in nested contexts #19080

ktbarrett opened this issue May 12, 2025 · 0 comments · Fixed by #19083
Labels
bug mypy got something wrong topic-final PEP 591

Comments

@ktbarrett
Copy link

Bug Report

I have a global constant I've marked with Final. In a class definition, I use this constant to swap out implementations of a method. While inside a type guarding block, but outside the method definition, the type of the Final object is narrowed, but inside of the method it is not narrowed.

To Reproduce

https://mypy-play.net/?mypy=latest&python=3.12&gist=2d4c97cffea1dd6710bf5cc7283f7290

from typing import *

def _init() -> None | str:
    return None

RESOLVE_X: Final = _init()

class Example:
    
    if RESOLVE_X is not None:
        
        reveal_type(RESOLVE_X)  # note: Revealed type is "builtins.str"
        
        def __str__(self) -> str:
            return RESOLVE_X  # error: Incompatible return value type (got "str | None", expected "str")  [return-value]
            
    else:
        def __str__(self) -> str:
            return "example"

Expected Behavior

Inside the __str__ definition in the if RESOLVE_X is not None: block, RESOLVE_X should stay narrowed as it cannot be reassigned and have its type re-widened in the future.

Actual Behavior

main.py:12: note: Revealed type is "builtins.str"
main.py:15: error: Incompatible return value type (got "str | None", expected "str")  [return-value]
Found 1 error in 1 file (checked 1 source file)

Your Environment

Mypy version 1.15.0.
Python 3.12.

@ktbarrett ktbarrett added the bug mypy got something wrong label May 12, 2025
@sterliakov sterliakov added the topic-final PEP 591 label May 12, 2025
hauntsaninja added a commit that referenced this issue May 13, 2025
Fixes #19080. There is no point applying our heuristics if the variable
is declared Final - it is not reassigned anywhere.

---------

Co-authored-by: Shantanu <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-final PEP 591
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants