Skip to content

Inferencing type reference of abstract class inferred from concrete type values #8050

Closed
@achimnol

Description

@achimnol
import abc

class MyAbstractType(metaclass=abc.ABCMeta):
  @abc.abstractmethod
  def do(self): pass

class MyConcreteA(MyAbstractType):
  def do(self):
    print('A')

class MyConcreteB(MyAbstractType):
  def do(self):
    print('B')

my_types = {
  'A': MyConcreteA,
  'B': MyConcreteB,
}
reveal_type(my_types)  # Revealed type is 'builtins.dict[builtins.str*, def () -> test-abc.MyAbstractType]'

a = my_types['A']()  # Cannot instantiate abstract class 'MyAbstractType' with abstract attribute 'do'
a.do()
b = my_types['B']()  # Cannot instantiate abstract class 'MyAbstractType' with abstract attribute 'do'
b.do()

The above example does not pass the type check as-is.
I need to change it to pass the type check as follows:

import abc
from typing import Mapping, Type

class MyAbstractType(metaclass=abc.ABCMeta):
  @abc.abstractmethod
  def do(self): pass

class MyConcreteA(MyAbstractType):
  def do(self):
    print('A')

class MyConcreteB(MyAbstractType):
  def do(self):
    print('B')

my_types: Mapping[str, Type[MyAbstractType]] = {  # explicit annotation
  'A': MyConcreteA,
  'B': MyConcreteB,
}
reveal_type(my_types)  # Revealed type is 'typing.Mapping[builtins.str, Type[test-abc.MyAbstractType]]'

a = my_types['A']()
a.do()
b = my_types['B']()
b.do()

Since mypy is able to infer MyAbstractType from the dictionary in the first snippet, I believe that it should be also able to infer Type[MyAbstractType] since the dictionary values are not instances but class names.

My setup: Python 3.8.0 + mypy 0.750

Related issues/PRs:

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions