Skip to content

mypy is unable to assign Callable taking Concatenate to Union of that Callable and another using the same ParamSpec #15177

Closed
@schuelermine

Description

@schuelermine

Bug Report

mypy is unable to assign Callable[Concatenate[B, C], D] to Union[Callable[Concatenate[B, C], D], Callable[C, D].

To Reproduce

from typing import TypeVar, ParamSpec, Concatenate, cast
from collections.abc import Callable

A = TypeVar("A")
B = TypeVar("B")
C = ParamSpec("C")
D = TypeVar("D")


def precall_guard_none(
    a: A, b: B | None, f: Callable[Concatenate[A, B, C], D]
) -> Callable[Concatenate[B, C], D] | Callable[C, D]:
    r: Callable[Concatenate[B, C], D] | Callable[C, D]
    if b is None:

        def g(b: B, *args: C.args, **kwargs: C.kwargs) -> D:
            return f(a, b, *args, **kwargs)

        r = g  # This should be permitted because the type of g is one of the variants of the type of r, a Union
    else:

        def h(*args: C.args, **kwargs: C.kwargs) -> D:
            return f(a, cast(B, b), *args, **kwargs)  # This cast is surprisingly necessary

        r = h

    return r

Expected Behavior

I expect no error.

Actual Behavior

mypy produces this error:

main.py:19: error: Incompatible types in assignment (expression has type "Callable[[B, **C], D]", variable has type "Union[Callable[[B, **C], D], Callable[C, D]]")  [assignment]

Your Environment

mypy playground

  • Mypy version used: 1.2.0
  • Mypy command-line flags: --strict
  • Python version used: 3.11

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrongtopic-paramspecPEP 612, ParamSpec, Concatenate

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions