Skip to content

Improve dict's constructor type #8517

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

Merged
merged 20 commits into from
Aug 10, 2022
Merged

Improve dict's constructor type #8517

merged 20 commits into from
Aug 10, 2022

Conversation

sobolevn
Copy link
Member

This is quite hard. So, let me explain.

Right now when doing something like this:

from typing import Iterable, Tuple
x1: Iterable[Tuple[str, bool]]
reveal_type(dict(x1, arg=True))  # N: Revealed type is "builtins.dict[builtins.str, builtins.bool]"

x2: Iterable[Tuple[int, bool]]
reveal_type(dict(x2, arg=True))  # E: Keyword argument only valid with "str" key type in call to "dict"

mypy has to special-case this check. Which is not good.

I think this can be easily expressed by the type-system itself.

@AlexWaygood
Copy link
Member

Please note the comments on lines 1017-1018 :)

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

1 similar comment
@github-actions

This comment has been minimized.

Copy link
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add some test cases for the various exotic ways of constructing a dict that the stub is trying to account for? 6 overloads is frying my brain a little :(

@github-actions

This comment has been minimized.

@sobolevn
Copy link
Member Author

Looks like pyright does a lot of quite different things to mypy in terms of dict analysis 🤔

@sobolevn
Copy link
Member Author

What should we do in this case? All mypy tests pass, but pyright fails

@github-actions

This comment has been minimized.

1 similar comment
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

1 similar comment
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

1 similar comment
@github-actions

This comment has been minimized.

@sobolevn
Copy link
Member Author

  /home/runner/work/typeshed/typeshed/test_cases/stdlib/builtins/test_dict.py:39:13 - error: "assert_type" mismatch: expected "int" but received "Literal[1, 2]"
  /home/runner/work/typeshed/typeshed/test_cases/stdlib/builtins/test_dict.py:40:13 - error: "assert_type" mismatch: expected "str" but received "Literal['a', 'b']"

🤣

@github-actions

This comment has been minimized.

1 similar comment
@github-actions

This comment has been minimized.

@sobolevn
Copy link
Member Author

sobolevn commented Aug 10, 2022

I think I finally solved it! 🎉
(by removing ones that were problematic, but anyways)

I think in the future we can end up doing something like the runtime does:

>>> i = [(1, True)]
>>> dict(i, arg=1.5)
{1: True, 'arg': 1.5}

Probably like:

class dict(MutableMapping[_KT, _VT], Generic[_KT, _VT]):
    def __init__(self: dict[_KT | str, _VT | _NVT], __iterable: Iterable[tuple[_KT, _VT]], **kwargs: _NVT) -> None: ...

But, this will be very major change! This 100% needs proper discussion.

For now, I consider this PR complete 🙂

@github-actions

This comment has been minimized.

@sobolevn
Copy link
Member Author

Adding suggetions now work again, I think it is a proper time for an old meme!
index

Copy link
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hooray!

@github-actions
Copy link
Contributor

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

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

Successfully merging this pull request may close these issues.

2 participants