Closed
Description
When I create an iterator of classes, all of which inherit from the same super class, itself inheriting from abc.ABC
, I expect the inferred type to be an Iterator[Type[common super class]]
. However, instead I get Iterator[abc.ABCMeta*]
, which seems to be a bit too far up the inheritance chain for me. Note that when I infer the types of instances of these same classes, I do get Iterator[Edit*]
, as expected.
Below is a simplified example of when I got this behavior:
# example.py
from abc import ABC, abstractmethod
from typing import TYPE_CHECKING
class Edit(ABC):
@classmethod
@abstractmethod
def do_something(cls) -> None: ...
class Insertion(Edit):
@classmethod
def do_something(cls):
print("foo")
class Deletion(Edit):
@classmethod
def do_something(cls):
print("foo")
class Substitution(Edit):
@classmethod
def do_something(cls):
print("baz")
if not TYPE_CHECKING:
# define reveal_type as a noop outside of mypy
reveal_type = lambda *x: ...
# mypy infers common subclass for instances.
instances = Insertion(), Deletion(), Substitution()
# Revealed type is 'typing.Iterator[example.Edit*]
reveal_type(iter(instances))
# mypy does NOT infer common subclass for classes themselves.
classes = [Insertion, Deletion, Substitution]
# This assert passes; however...
assert all(issubclass(cls, Edit) for cls in classes)
# Revealed type is 'typing.Iterator[abc.ABCMeta*]
reveal_type(iter(classes))
# I expect: Revealed type is 'typing.Iterator[example.Edit*]
for cls in Insertion, Deletion, Substitution:
# Revealed type is 'abc.ABCMeta'
reveal_type(cls)
# I expect: Revealed Type is 'Type[example.Edit]'
This is a simplified diagram of the inheritance hierarchy:
ABC (metaclass=ABCMeta)
^
|
Edit
^
,-------------------'-----------------.
Insertion Deletion Substitution
Explcitly typing works, however:
from typing import Sequence, Type
klasses: Sequence[Type[Edit]] = [Insertion, Deletion, Substitution]
for kls in klasses:
# Revealed type is 'Type[example.Edit]'
reveal_type(kls)
Possibly related to: #2922.
Metadata
Metadata
Assignees
Labels
No labels