python / python/mypy

Inconsistent narrowing of Union and TypeVar with constraints and neglect of @final

Open
#10,898 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug topic-final topic-type-narrowing
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

I had a short discussion about this with @JelleZijlstra on Gitter.

When narrowing the constrained type variable, Mypy seems to ignore the final decorator. When removing the final decorator, Mypy's output changes neither for the non-generic function f nor the generic function g. Shouldn't Mypy consistently report an error or not in both cases (regardless of marking the classes as final or not)? If I understand correctly, Mypy allows changing the signature of __init__ when subclassing. So the reports are correct for f when using final and correct for g when not using final, aren't they?

from typing import final, Type, TypeVar, Union

@final
class A:
    def __init__(self, a: int) -> None:
        ...

@final
class B:
    def __init__(self, b: str) -> None:
        ...

U = Union[A, B]
T = TypeVar("T", A, B)

def f(x: Type[U]) -> U:
    if issubclass(x, A):
        reveal_type(x)
        # Revealed type is "A"
        return x(a=1)
    return x(b="a")

def g(x: Type[T]) -> T:
    if issubclass(x, A):
        reveal_type(x)
        # Revealed type is "A*"
        # Revealed type is "<subclass of "B" and "A">"
        return x(a=1)
        # Unexpected keyword argument "a" for <subclass of "B" and "A">
    return x(b="b")

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the issue's Python snippet through mypy and compare the diagnostics and revealed types with and without @final. Trace the handling of constrained TypeVars, Union narrowing, subclass checks, and constructor signatures; done means the behavior is consistent for both f and g when the classes are final or non-final.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
32/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.