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

Dict constructor typing is incorrect (too restrictive) #2287

Closed
beamerblvd opened this issue Jun 27, 2018 · 1 comment
Closed

Dict constructor typing is incorrect (too restrictive) #2287

beamerblvd opened this issue Jun 27, 2018 · 1 comment
Labels
stubs: false positive Type checkers report false errors

Comments

@beamerblvd
Copy link

The dict type has several supported constructor signatures. The one in question is this:

def __init__(self, iterable: Iterable[Tuple[_KT, _VT]], **kwargs: _VT) -> None: ...

I believe this signature is improperly restrictive. Consider this code:

parameters = dict(
    map(str.strip, p.split('=', 1)) if '=' in p else (p.strip(), None)
    for p in encoded_parameters.split(';')
) if encoded_parameters else {}  # type: Dict

This is perfectly valid and works well. The code in the dict constructor doesn't actually require the iterable argument to contain two-tuples. It merely requires the iterable argument to contain values that can be unpacked each into exactly two values. (It's for k, v in iterable: ...). It can be a tuple, a list, or any iterable. However, my static type checker (mypy) complains that the types are incompatible (says it must be an iterable of Tuple[Any, Any]).

I'm not, however, certain what the ideal signature would be. Unfortunately, there's no Unpackable type. Some possible options:

def __init__(self, iterable: Iterable[Iterable[Union[_KT, _VT]]], **kwargs: _VT) -> None: ...
def __init__(self, iterable: Iterable[Iterable[Any]], **kwargs: _VT) -> None: ...

Thoughts?

@srittau
Copy link
Collaborator

srittau commented Nov 19, 2018

Unfortunately I don't think that there is anything that typeshed can do at the moment. Type checkers can not assert that map() returns an iterable with at least two items of the correct type. I have opened discussion about this in python/typing#592.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stubs: false positive Type checkers report false errors
Projects
None yet
Development

No branches or pull requests

2 participants