Skip to content

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

Closed as not planned

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

Activity

  1. AlexWaygood commented on Mar 8, 2024

    @AlexWaygood
    Member

    Duplicate of #1595

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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