Skip to content

test suite characterizing dict.get() - #13225

Merged
srittau merged 4 commits into
python:mainfrom
tungol:dict-test
Feb 28, 2025
Merged

srittau merged 4 commits into
python:mainfrom
tungol:dict-test

Conversation

@tungol

@tungol tungol commented Dec 10, 2024

Copy link
Copy Markdown
Contributor

While working on understanding the subtleties of dict.get(), I read this comment from Jelle:

It would also be good to add some more test cases to cover dict.get; it's been a very tricky function to cover in the stubs.

Here's those test cases which reflect the current behavior in several different contexts.

I also had this one, but I'm convinced this is just a mypy bug. It'd probably be a good regression test there, if this version of TypeOfAny.special_form is ever split to a new type of Any as suggested by python/mypy#15497 (comment).

# Bonus weirdness with TypeAlias
MyType: TypeAlias = Dict[str, Any]
d_type: MyType = {}
special_any = d_type["key"]

assert_type(d_any.get("key", any_value), Any)
assert_type(d_any.get("key", special_any), Any)

assert_type(d_str.get("key", any_value), Any)
assert_type(d_str.get("key", special_any), str)  # ?

@github-actions

This comment has been minimized.

@tungol

tungol commented Dec 10, 2024

Copy link
Copy Markdown
Contributor Author

For additional context: it's not obvious that all of these variants are needed, but some of them change in non-obvious ways with #13222 so I think it's reasonable.

@github-actions

This comment has been minimized.

@tungol

tungol commented Dec 11, 2024

Copy link
Copy Markdown
Contributor Author

Discovered a new type of edge case for dict.get that I wasn't thinking about before: #13229 (comment)

Analysis of some mypy primer results linked, but the theme is what happens if the default value is an empty container type. Right now for dict[str, Any], d_any.get("key", []) returns Any but any change that makes it return Ant | list[Any] opens up a huge amount of noise in mypy primer. It's even worse for nested d_any.get("key1, {}).get("key2", {}). It might be worth adding something in this genre to the tests as well.

Note that for the fully concrete dict[str, str], d_str.get("key", []) already returns str | list[Any] any mypy complains about the unknown container type. For dict[str, list[str]], d_lstr.get("key", []) returns list[str] without issue.

@github-actions

Copy link
Copy Markdown
Contributor

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

@srittau srittau left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks! It's good to have these test cases as regression tests. They can always be amended or changes as is necessary, but at least we need to make a conscious decision about that.

@srittau
srittau merged commit 1bd2a35 into python:main Feb 28, 2025
@tungol
tungol deleted the dict-test branch March 1, 2025 07:50
mmingyu pushed a commit to mmingyu/typeshed that referenced this pull request May 16, 2025
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