Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
abravalheri opened this issue Mar 8, 2024 · 1 comment

Comments

@abravalheri
Copy link
Contributor

abravalheri commented Mar 8, 2024

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

@AlexWaygood
Copy link
Member

Duplicate of #1595

@AlexWaygood AlexWaygood marked this as a duplicate of #1595 Mar 8, 2024
@AlexWaygood AlexWaygood closed this as not planned Won't fix, can't repro, duplicate, stale Mar 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants