A subclass of Protocol is also an ABC:
importabcfromtypingimportProtocolclassP(Protocol):
@abc.abstractmethoddeff(self) ->None: passclassC(P):
passC() # TypeError: Can't instantiate abstract class C with abstract method f
However, mypy doesn't detect a metaclass conflict here:
fromtypingimportProtocolclassMeta(type): pass# Metaclass conflict at runtime, but no mypy errorclassP(Protocol, metaclass=Meta): pass
At runtime this will generate a metaclass conflict:
Traceback (mostrecentcalllast):
File"/Users/jukka/src/mypy/t/t5.py", line6, in<module>classP(Protocol, metaclass=Meta): passTypeError: metaclassconflict: themetaclassofaderivedclassmustbea (non-strict) subclassofthemetaclassesofallitsbases
The actual metaclass is typing._ProtocolMeta:
>>> type(typing.Protocol)
<class 'typing._ProtocolMeta'>
Mypy should infer typing._ProtocolMeta as the metaclass of protocol classes. Maybe a custom metaclass should also be rejected, at least if it isn't a subclass of typing._ProtocolMeta.
More discussion here: python/typeshed#9058
A subclass of Protocol is also an ABC:
However, mypy doesn't detect a metaclass conflict here:
At runtime this will generate a metaclass conflict:
The actual metaclass is
typing._ProtocolMeta:Mypy should infer
typing._ProtocolMetaas the metaclass of protocol classes. Maybe a custom metaclass should also be rejected, at least if it isn't a subclass oftyping._ProtocolMeta.More discussion here: python/typeshed#9058