Skip to content

Wrong type inference (object instead of List) #6968

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

Closed
cdesvernois opened this issue Jun 11, 2019 · 4 comments
Closed

Wrong type inference (object instead of List) #6968

cdesvernois opened this issue Jun 11, 2019 · 4 comments

Comments

@cdesvernois
Copy link

Bug: the following code (Python 3.6.7, mypy 0.701)

o = [[1, 2], ["foo", "bar"]]
reveal_type(o)

Outputs a type of builtins.list[builtins.object*] instead of something like builtins.list[builtins.list[Any]]. This in turn makes mypy raise an error (in my case) when I try to apply a len operation on elements of that list:

[len(x) for x in o]

Outputs: error: Argument 1 to "len" has incompatible type "object"; expected "Sized"

This is probably related to #4975 but only the union of Tuple was evoked there, and it seems that there is the same problem on lists.

Thanks!

@ilevkivskyi
Copy link
Member

There is a policy that mypy never infers Any in joins of precise types. So this is more related to #3830, in the sense should we instead infer List[Sized] in this case? On one hand I would say we can, but on the other hand this is quite tricky in general (see #3257) and therefore low priority. You can just use explicit annotations in such cases:

o: List[Sized] = [[1, 2], ["foo", "bar"]]

@cdesvernois
Copy link
Author

Thanks for your investigation, I don't have any legitimacy to discuss your policies, from an external eye it seems too bad to prefer the inference of List[object] over the correct (and imprecise) List[List[Any]].
You're right it would also be sufficient in this case to have a List[Sized], but it would still be incorrect and could lead to false positives with things like:

o: List[Sized] = [[1, 2], ["foo", "bar"]]
[x.count(1) for x in o]

I will try your suggestion to use explicit type annotation :)

@GPHemsley
Copy link

GPHemsley commented Dec 9, 2020

The workaround gets a little tedious when your problematic list is being defined as part of a dictionary. You still have to explicitly assert its type after the fact:

assert isinstance(foo["o"], list)

@hauntsaninja
Copy link
Collaborator

This is a won't fix. mypy's inference should never produce Any. It would be expensive for mypy to construct ad hoc protocols and any time you create a type that a user cannot easily name it creates usability issues

@hauntsaninja hauntsaninja closed this as not planned Won't fix, can't repro, duplicate, stale Aug 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants