Skip to content

bound TypeVar messes with argument type resolving #12846

Closed
@headtr1ck

Description

@headtr1ck

Bug Report

When using a TypeVar bound to a class to annotate the return value of a method (same as the Circle-Tire example https://docs.python.org/3/library/typing.html) I get incompatible type errors.
Something seems to go really wrong, as mypy also complains that dict has conflicts related to __hash__?

To Reproduce

from typing import Hashable, Mapping, Any, TypeVar

T = TypeVar("T", bound="A")

class A:
    def a(
        self: T,
        x: Hashable | Mapping[Any, Any]
    ) -> T:
        return self


s = A()
s.a("asd")  # ok
s.a({"a": 1})  # fails

Expected Behavior

I expect that both calls are ok, since they are either Hashable or a Mapping (same as a "normal" function definition with return value = A).

Actual Behavior

raises:

error: Argument 1 to "a" of "A" has incompatible type "Dict[str, int]"; expected "Hashable" [arg-type]
note: Following member(s) of "Dict[str, int]" have conflicts:
note: hash: expected "Callable[[], int]", got "None"
note: Protocol member Hashable.hash expected instance variable, got class variable

Interestingly when you replace the T by A everything works as expected.
Also, reveal_type(A.a) returns

Revealed type is "def [T <: xarray.core.mypy.A] (self: T`-1, x: Union[typing.Hashable, typing.Mapping[Any, Any]]) -> T`-1"

so the Mapping is found, while in the error Message it seems to only expect Hashable.

Your Environment

  • Mypy version used: 0.950
  • Mypy command-line flags: --strict
  • Python version used: 3.9.12
  • Operating system and version: win10

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions