Skip to content

Unexpected error when creating a Dict from a list of lists len 2 #2862

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
adamtheturtle opened this issue Mar 13, 2019 · 5 comments
Closed
Labels
reason: inexpressable Closed, because this can't be expressed within the current type system stubs: false positive Type checkers report false errors

Comments

@adamtheturtle
Copy link
Contributor

I have the following code which works.

from typing import Dict

my_list = ['a', 'b']
my_dict: Dict[str, str] = dict([my_list])
print(my_dict)  # {'a': 'b'}

mypy gives the following error:

example.py:4: error: List item 0 has incompatible type "List[str]"; expected "Tuple[str, str]"

I expect that in this case mypy would not show an error because the code is valid.

From https://docs.python.org/3/library/stdtypes.html#dict:

Each item in the iterable must itself be an iterable with exactly two objects.

From python/mypy#6542 (comment) (@srittau):

Seems like a typeshed issue. Possibly dict.__init__() is missing an overload like:

    @overload
    def __init__(self, iterable: Iterable[Iterable[Union[_KT, _VT]]], **kwargs: _VT) -> None: ...
@ilevkivskyi
Copy link
Member

There is no such thing as fixed length lists in PEP 484. You should use tuples instead.

I propose to just close this as wontfix, since the proposed additional overload will produce too many false negatives, plus inferred types will be often weird, e.g. dict([[1, "hi"]]) will be Dict[object, object], which will produce even more false positives down the road.

@adamtheturtle
Copy link
Contributor Author

@ilevkivskyi - I appreciate that this case is perhaps too annoying to make work.

For more context, some code which is closer to the original that I am trying to type hint:

from typing import Dict

my_strings = ['foo=bar', 'baz=bat', 'apple=pair=orange']
my_dict: Dict[str, str] = dict(my_string.split('=', 1) for my_string in my_strings)
print(my_dict)  # {'foo': 'bar', 'baz': 'bat', 'apple': 'pair=orange'}

What this will likely change to is:

from typing import Dict

my_strings = ['foo=bar', 'baz=bat', 'apple=pair=orange']
my_dict: Dict[str, str] = dict((my_string.split('=', 1)[0], my_string.split('=', 1)[1]) for my_string in my_strings)
print(my_dict)  # {'foo': 'bar', 'baz': 'bat', 'apple': 'pair=orange'}

This is in a legacy codebase, where convincing folks to add type hints is already a challenge, never mind convincing them that it needs code changes in the logic itself!

@srittau
Copy link
Collaborator

srittau commented Mar 13, 2019

Personally, I prefer false negatives over false positives, but I think @ilevkivskyi's argument about weird inferred types is pretty compelling. Actually, this already came up in #2287 and there is an open typing issue: python/typing#592. I am inclined to close this here for now.

Maybe we should create a label for things we can't fix in the current type system, so we can revisit those things later?

@ilevkivskyi
Copy link
Member

OK, let's then close this as a duplicate of python/typing#592.

@ilevkivskyi
Copy link
Member

Maybe we should create a label for things we can't fix in the current type system, so we can revisit those things later?

This is a good idea assuming someone volunteers to find and label such closed issues :-)

@srittau srittau added the reason: inexpressable Closed, because this can't be expressed within the current type system label Mar 13, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
reason: inexpressable Closed, because this can't be expressed within the current type system stubs: false positive Type checkers report false errors
Projects
None yet
Development

No branches or pull requests

3 participants