python / python/mypy

Generic type inference incorrectly handled in edge case

Open
#13,921 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

Bug Report

If you try to widdle down the type of a generic class in a certain manner, it only works if you use an intermediate variable. A little tough to explain without looking at the example

To Reproduce

https://mypy-play.net/?mypy=latest&python=3.10&gist=d3ebef88a57147cef8a8d311e1b33fb7

from abc import ABC, abstractmethod
from typing import Generic, TypeVar

T = TypeVar("T")

class A(ABC, Generic[T]):

    @abstractmethod
    def t(self) -> T:
        pass

def get_a_does_work(a: A[T]) -> T:
    t_value = a.t()
    if t_value is None:
        return None 
    return a.t()

def get_a_should_work(a: A[T]) -> T:
    if a.t() is None:
        return None 
    return a.t()

Expected Behavior

Both get_a_does_work and get_a_should_work should pass type checking.

Actual Behavior

get_a_should_work outouts:
main.py:20: error: Incompatible return value type (got "None", expected "T")

Your Environment

You can see on the playground

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

Reproduce the behavior in the linked mypy playground using the get_a_does_work and get_a_should_work examples. Start by tracing generic type inference and narrowing for repeated a.t() calls; done when both functions pass type checking without an intermediate variable.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.