In Haskell terms, I think of Protocol
and type
both being two different kinds. In this analogy, mypy
gets it right with func1
; if you think of func1
as a type-level function, its argument must have kind *
. Proto
, on the other hand, has kind Protocol
.
Under this interpretation, type
is a kind, and type[Any]
is still equivalent to type
but not to Any
itself. If you want a function that that accepts a type or a protocol, you would need a union kind:
def func2a(v: type): # only accepts "real" types
def func2b(v: Protocol): # only accepts subclasses of Protocol
def func3(v: type | Protocol): # accepts real types or protocols
I realize this isn’t doable without introducing the kind of type hierarchy found in Haskell, but it might be useful for providing a basis for how to treat Protocol
.