Skip to content

__subclasses__() -> "Only concrete class can be given where "Type[C]" is expected" #6199

Closed
@asottile

Description

@asottile

this seems related to #5374 but only in the error message (?)

I'm trying to port a section of code that was previously using a metaclass to just using __subclasses__. Here's a minimal example of what I'm trying to do:

import abc
import inspect
from typing import Dict
from typing import List
from typing import Type


class C(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def foo(self):
        raise NotImplementedError(foo.__name__)


def _make_reg() -> Dict[str, Type[C]]:
    ret: Dict[str, Type[C]] = {}

    #subclasses: List[Type[C]] = C.__subclasses__()
    subclasses = C.__subclasses__()
    reveal_type(C.__subclasses__())
    reveal_type(subclasses)
    while subclasses:
        cls = subclasses.pop()
        subclasses.extend(cls.__subclasses__())

        if inspect.isabstract(cls):
            continue

        if cls.__name__ in ret:
            raise AssertionError(cls.__name__, ret[cls.__name__], cls)
        else:
            ret[cls.__name__] = cls

    return ret


REG = _make_reg()

This, as written, fails with:

$ mypy --version
mypy 0.650
$ mypy t.py
t.py:19: error: Revealed type is 'builtins.list[def () -> t.C]'
t.py:20: error: Revealed type is 'builtins.list[def () -> t.C]'
t.py:31: error: Only concrete class can be given where "Type[C]" is expected

If I replace the assignment of subclasses with the commented out line, it succeeds:

$ mypy t.py
t.py:19: error: Revealed type is 'builtins.list[def () -> t.C]'
t.py:20: error: Revealed type is 'builtins.list[Type[t.C]]'
  1. why does the annotation make this allowable?
  2. is the original message a bug? I believe I'm dealing entirely in Type[C] objects in a typesafe manner even without the inspect.isabstract call (notice I'm never even attempting to construct a Type[C])

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions