Skip to content

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

@absolutely-vivid

Description

@absolutely-vivid

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions