Skip to content

Incorrect definition of collection builtins causes type checking error related to false MRO #11543

Closed as not planned
@abravalheri

Description

@abravalheri

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,

class list(MutableSequence[_T]):
defines list as "inheriting from 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions