Skip to content

abstractmethod + generic subclass resulting in failed inference #8873

Closed
@beezee

Description

@beezee

This appears to be a bug.

Minimal repro:

from abc import ABC, abstractmethod
from typing import Generic, TypeVar

A = TypeVar('A')
B = TypeVar('B')
C = TypeVar('C')

class TwoTypes(Generic[A, B]): pass

class ReproBase(ABC, Generic[C]):

  @abstractmethod
  def repro(self, a: A) -> TwoTypes[C, A]: pass

class ReproSub(ReproBase[C]):

  @abstractmethod
  def repro_defer(self, a: A) -> TwoTypes[C, A]: pass

  def repro(self, a: A) -> TwoTypes[C, A]:
    return self.repro_defer(a)

class ReproSub2(ReproBase[C], Generic[C]):

  @abstractmethod
  def repro_defer(self, a: A) -> TwoTypes[C, A]: pass

  def repro(self, a: A) -> TwoTypes[C, A]:
    return self.repro_defer(a)

Type-checking results in error: Incompatible return value type (got "TwoTypes[A, A]", expected "TwoTypes[C, A]")

mypy doesn't like ReproSub or ReproSub2 for the same reason, but interestingly only complains about the first it encounters, depending on which order you put the subclasses in.

I'd expect C to be captured correctly and the return type inferred on any concrete definition of the repro method to be TwoTypes[C, A], as is specified by the delegated defer_repro method in both cases.

Using mypy 0.770, Python 3.7.6

Issue appears to be fixed in master

Not using any flags

Considering it's fixed in master, if someone knows specifically what the fix is, I'd love a link to the commit(s) just to understand what I'm running into on current release, and any info about when the fix might become generally available.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions