python / python/mypy

Wrong return type inferred for overload with a type variable

Open
#18,233 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Bug Report

from typing import TypeVar, overload

_T = TypeVar("_T")

@overload
def getenv(key: str) -> str | None: ...

@overload
def getenv(key: str, default: _T) -> str | _T: ...

def getenv(key, default):
    return key


def test(custom_var: str) -> str:
    return getenv(custom_var) or getenv("V", "D")

https://mypy-play.net/?mypy=latest&python=3.12&gist=4d959cd7069a8495533bfeca1cd40729

Actual Behavior

main.py:16: error: Incompatible return value type (got "str | None", expected "str")  [return-value]

Expected Behavior

This should type check without errors, since we have an or with a call that always returns str.

It works if I replace type variable with just str:

@overload
def getenv(key: str, default: str) -> str: ...

but something about _T and the union upsets it.

Your Environment

  • Mypy version used: 1.13.0
  • Mypy command-line flags: none
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: 3.10-3.13

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 with the supplied Python reproduction and confirm the behavior using mypy 1.13.0 with no configuration flags. Trace overload resolution and type-variable inference for the two getenv calls, then add a regression test showing that the expression is accepted when the fallback returns str.

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
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.