Description
The way some collection builtins (e.g. list
, dict
, ...) are defined in typeshed causes false positive with type checking, due to the incorrect MRO exposed by typeshed.
For example,
Line 971 in af84d2f
MutableSequence
", however that is not true and causes the following false negative error:
from typing import Optional
from collections.abc import MutableSequence
class Item:
def __init__(self, comment: Optional[str] = None):
self._comment = comment
class Array(Item, MutableSequence, list):
def __init__(self, values: list, comment: Optional[str] = None):
Item.__init__(self, comment)
list.__init__(self, values)
if __name__ == '__main__':
a = Array([0, 1, 2])
print([p.__name__ for p in a.__class__.__mro__])
main.py:10: error: Cannot determine consistent method resolution order (MRO) for "Array" [misc]
main.py:12: error: Argument 1 to "__init__" of "Item" has incompatible type "Array"; expected "Item" [arg-type]
main.py:13: error: No overload variant of "__init__" of "list" matches argument types "Array", "list[Any]" [call-overload]
main.py:13: note: Possible overload variants:
main.py:13: note: def [_T] __init__(self: list[_T]) -> None
main.py:13: note: def [_T] __init__(self: list[_T], Iterable[_T], /) -> None
Found 3 errors in 1 file (checked 1 source file)
https://mypy-play.net/?mypy=latest&python=3.12&gist=dc0042ce469e49dc22de0c91384d4588
Note that this does not correspond to the real implementation. When I run the script above, no runtime error is found. Instead, this is the output:
$ python3.12 main.py
['Array', 'Item', 'MutableSequence', 'Sequence', 'Reversible', 'Collection', 'Sized', 'Iterable', 'Container', 'list', 'object']
So my guess is that typeshed
should not tell mypy
that "list
and co" are subclasses of "MutableSequence
and co".
Note:
while this particular choice of inheritance is debatable, it is fundamental for the way some libraries work, e.g. tomlkit
work. It uses MutableSequence
as a mixin, so that I gets MutableSequence
methods for free, but it also want the custom objects to be considered lists themselves, so the users can use the API transparently as if they were dealing with built-in objects (this is an important aspect of the design).
Related: python/mypy#11427