Description
Bug Report
I want to create a generic metaclass base which will automatically register all classes under it by their identifiers into a tracking dictionary of the metaclass.
Then, all the real metaclasses and base classes will inherit that, and can do this registration automatically and independently for each metaclass.
However, mypy raises an unexpected error.
from typing import Generic, Dict, TypeVar, Any, Type, cast
SelfProtoMeta = TypeVar("SelfProtoMeta", bound="ProtoMeta[Any]")
VartBase = TypeVar("VartBase", bound="Any")
class ProtoMeta(type, Generic[VartBase]):
REGISTRY: Dict[str, VartBase]
@staticmethod
def __new__(
cls: Type[SelfProtoMeta], /, *args: Any, **kwargs: Any
) -> Type[VartBase]:
obj = cast(Type[VartBase], type.__new__(cls, *args, **kwargs))
cls.registrate(obj)
return obj
@classmethod
def registrate(cls: Type[SelfProtoMeta], obj: VartBase, /) -> None:
pass
class ProtoBase(object, metaclass=ProtoMeta):
IDENTIFIER: str
SelfMeta1 = TypeVar("SelfMeta1", bound="Meta1")
class Meta1(ProtoMeta["Base1"]):
REGISTRY = {}
@classmethod
def registrate(cls: Type[SelfMeta1], obj: "Base1", /) -> None:
cls.REGISTRY[obj.IDENTIFIER] = obj
class Base1(ProtoBase, metaclass=Meta1):
IDENTIFIER = "base1"
assert issubclass(Meta1, type)
assert issubclass(Meta1, ProtoMeta)
assert issubclass(Base1, object)
assert issubclass(Base1, ProtoBase)
$ mypy yard.py --strict
yard.py:39: error: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases [misc]
Found 1 error in 1 file (checked 1 source file)
I think the error message means that Meta1
, the metaclass of Base1
, is not a subclass of ProtoMeta
, the metaclass of ProtoBase
(parent of Base1
).
But as you can see, I have verified that Meta1
is a subclass of ProtoMeta
, so I don't think this error is raised (or reported) correctly.
To Reproduce
mypy yard.py --strict
Expected Behavior
No error should be raised, or a different error message should be raised.
Actual Behavior
Get unexpected error message: error: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases [misc]
.
Your Environment
- Mypy version used:
mypy 1.10.0 (compiled: yes)
- Mypy command-line flags:
--strict --verbose
- Mypy configuration options from
mypy.ini
(and other config files): - Python version used:
Python 3.8.19