Closed as not planned
Closed as not planned
Description
typeshed claims that str
derives from Sequence
and therefore indirectly from collections_abc.Sized
whose metaclass is declared to be ABCMeta. This is done as a type-checkable alternative to Sequence.register(str)
which handles isinstance and issubclass calls.
However derivation and register are not indistinguishable, since the metaclass structure is different. issubclass(type(str), ABCMeta)
should be False, otherwise the definition class A(str, Enum): pass
would fail at runtime due to inconsistent metaclass structure:
>>> from collections import Sized
>>> from enum import Enum
>>> class A(Sized, Enum): pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
The error is that type(Enum) is EnumMeta
and type(Sized) is ABCMeta
and they are unrelated.
This bug has at least the following implications:
- It obviously implies that
a: ABCMeta = str
typechecks. - It makes it harder to warn about inconsistent metaclass structure without false positives. This is why mypy only catches specific cases.
- As exemplified above,
class A(str, Enum)
appears to have inconsistent metaclass structure, even though this is the recommended way of making an enum of strings. It might also be the case with some other builtins.