Metaclasses and Typing

Edit: I found this issue after posting this, it seems there is a gap in the typing system, so I’ll take my issue there: typing.Type doesn't express type metaclass · Issue #715 · python/typing · GitHub

How to type a metaclass method that returns an instance of the derived class on which it is called?

For example we want the following:

class MyType(type): ...
class Foo(metaclass=MyType): ...

foo = Foo.bar() # revealed type is Foo

But bar is defined in the metaclass…I’m having trouble representing that. (my actual use case is a bit more complex and for __or__ & __await__ so @classmethod on the child class is not a possibility, I’m just using a regular method to simplify)

My current “solution” is:

from typing import Type, TypeVar

T = TypeVar('T')

class MyType(type):

    ...

    def bar(cls: Type[T]) -> T:
        cls._spam += 1
        return cls()

This “works” (in mypy atleast) insofar as the return type is what I want, but I get errors about the cls parameter being incompatible and it not knowing about the _spam attribute – which makes sense because Type[T] is too generic. I’m just ignoring these errors so that type checking is correct on the user side. Am I missing something or is the typing system just not capable of representing this?