Skip to content

Wrong Metaclass Conflict Error #17213

Closed
Closed
@gaotako

Description

@gaotako

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions