python / python/mypy

Incorrect type-var error when passing a Callable with a generic return type to a function

Open
#21,559 0 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

While running mypy on a repository, I get a type error that seems incorrect: Value of type variable "_F" of "force_delegate" cannot be "Callable[[ASTRenderer, RawText], dict[str, Any]]" [type-var]

from this snippet:

_FT = TypeVar("_FT")
_F = TypeVar("_F", bound=Callable[..., _FT])


def force_delegate(func: _F) -> _F:
    """
    A decorator to allow delegation for the specified method even if cls.delegate = False
    """
    func._force_delegate = True
    return func

(taken from https://github.com/frostming/marko/blob/57e042bc39f4a82c7f0d74ecdcd37434dd7b072b/marko/renderer.py#L98-L107)

My understanding of the error (from the docs) message is that it's a problem with type bounds, but that shouldn't be a problem here. The upper bound is just a Callable with a generic return type.

The only working solution I've found is to remove the _F type variable entirely and change the signature to def force_delegate(func: Callable[..., _FT]) -> Callable[..., _FT]

To Reproduce

from typing import Any, Callable, TypeVar

class RawText: pass

class ASTRenderer:
    @force_delegate
    def f(self, arg: RawText) -> dict[str, Any]:
        return {}

_FT = TypeVar("_FT")
_F = TypeVar("_F", bound=Callable[..., _FT])

def force_delegate(func: _F) -> _F:
    """
    A decorator to allow delegation for the specified method even if cls.delegate = False
    """
    func._force_delegate = True  # type: ignore[attr-defined]
    return func

Expected Behavior

Mypy should return successfully

Actual Behavior

Mypy exits with the error
Value of type variable "_F" of "force_delegate" cannot be "Callable[[Foo, RawText], dict[str, Any]]" [type-var]

Your Environment

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

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 mypy on the provided reproduction with the stated Python and mypy versions, then compare it with the Callable[..., _FT] workaround. Trace the type-variable diagnostic for the generic return bound. Done means the original _F-based decorator example type-checks successfully without the reported [type-var] error.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
compilers, devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.