Skip to content

Improve the accuracy of (default)dict.__(r)or__ #10679

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 12 commits into from
Sep 8, 2023

Conversation

AlexWaygood
Copy link
Member

Fixes #10678

@github-actions

This comment has been minimized.

@AlexWaygood
Copy link
Member Author

Oh, one mypy_primer error isn't actually too bad at all. I vote for doing this, in that case!

@AlexWaygood AlexWaygood marked this pull request as ready for review September 7, 2023 12:13
@Akuli
Copy link
Collaborator

Akuli commented Sep 7, 2023

Maybe add a test case? We can't use mypy_primer to ensure we don't break this again, since the improvement doesn't show up in the diff and open-source projects are unlikely to contain CaseInsensitiveDict() | dict() anyway.

@AlexWaygood
Copy link
Member Author

Sure, I'll add a test

@srittau
Copy link
Collaborator

srittau commented Sep 7, 2023

And the one primer hit actually shows a genuine problem as using an arbitrary mapping wouldn't work either. This is actually something I wasn't aware of, so +10 for changing these annotations.

@github-actions

This comment has been minimized.

@AlexWaygood AlexWaygood marked this pull request as draft September 7, 2023 15:41
@AlexWaygood AlexWaygood marked this pull request as ready for review September 7, 2023 16:23
@github-actions

This comment has been minimized.

@AlexWaygood
Copy link
Member Author

I don't understand what's going on with the remaining pyright errors on the test cases I've added. @srittau / @Akuli, do either of you understand why they're happening? Mypy is fine with all the test cases I've added.

@github-actions

This comment has been minimized.

@AlexWaygood AlexWaygood changed the title Improve the accuracy of some __(r)or__ methods Improve the accuracy of (default)dict.__(r)or__ Sep 7, 2023
@srittau
Copy link
Collaborator

srittau commented Sep 7, 2023

One thing I'd try is using a small custom mapping-like type in the tests instead of os.environ. The latter has a lot going on, with generics and python-specific branches, and I wouldn't be surprised if a typechecker would special-case it due to its importance.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@AlexWaygood
Copy link
Member Author

Okay, for now I've just commented out the tests that were failing on pyright and left TODO comments. There's definitely a behaviour difference from mypy there -- to me it looks like a bug, but not sure. I'll file an issue with pyright later.

@AlexWaygood AlexWaygood requested review from srittau and Akuli September 7, 2023 21:52
@github-actions
Copy link
Contributor

github-actions bot commented Sep 7, 2023

Diff from mypy_primer, showing the effect of this PR on open source code:

mkosi (https://github.com/systemd/mkosi)
+ mkosi/run.py:177:11: error: No overload variant of "__or__" of "dict" matches argument type "Mapping[str, str]"  [operator]
+ mkosi/run.py:177:11: note: Possible overload variants:
+ mkosi/run.py:177:11: note:     def __or__(self, dict[str, str], /) -> dict[str, str]
+ mkosi/run.py:177:11: note:     def [_T1, _T2] __or__(self, dict[_T1, _T2], /) -> dict[Union[str, _T1], Union[str, _T2]]

Copy link
Collaborator

@Akuli Akuli left a comment

Choose a reason for hiding this comment

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

At first glance the tests seemed like too much copy/pasta, but I think it's fine because dict and defaultdict behave differently.

@AlexWaygood
Copy link
Member Author

At first glance the tests seemed like too much copy/pasta, but I think it's fine because dict and defaultdict behave differently.

Yeah, dict.__or__ always returns dict, whereas defaultdict.__or__ returns Self. I considered putting all the tests into a check_pep584.py file, but thought it would be too confusing to have some of the tests for dict in a file that had a name that didn't start with check_dict.

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.

False negatives with dict.__(r)or__
3 participants