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

monkeypatch: add support for TypedDict #11000

Merged
merged 14 commits into from
May 14, 2023

Conversation

adamjstewart
Copy link
Contributor

Closes #10999

This feature was added in Python 3.8. It looks like pytest still supports Python 3.7 (I'm guessing that will change in about 6 weeks). For now, it isn't easy to test or annotate this properly.

Copy link
Member

@RonnyPfannschmidt RonnyPfannschmidt left a comment

Choose a reason for hiding this comment

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

thank you for this excellent addition

lets add type triggers in https://github.com/pytest-dev/pytest/blob/main/testing/typing_checks.py as well to make sure type checks work as expected

@adamjstewart
Copy link
Contributor Author

adamjstewart commented May 13, 2023

pre-commit errors are because TypedDict doesn't exist in 3.7. Solutions include bumping language_version in .pre-commit-config.yaml from python3 to python3.8 or waiting 6 weeks until Python 3.7 support is presumably dropped.

@RonnyPfannschmidt
Copy link
Member

We just merge a pr to remove the default version,, does that help?

@bluetech
Copy link
Member

The current approach wouldn't work; TypedDict[K, V] is not something that makes sense, since TypedDict is not generic in key and value types, its keys and values are per-determined. And TypedDict on its own is not a type you can refer to, i.e. there is no common TypedDict super-type of all typed dicts in Python (I'm like 90% sure of that, so not 100%).

So some other approach is needed. Off hand I'm not sure how to refer to all typed dicts. Maybe the solution is to relax the MutableMapping to Mapping and accept that passing readonly dicts will fail at runtime.

@bluetech
Copy link
Member

See python/mypy#4976. Particularly the current last comment python/mypy#4976 (comment) matches the case here.

@adamjstewart
Copy link
Contributor Author

I'd be fine with the Mapping solution if you want me to implement that.

@adamjstewart
Copy link
Contributor Author

Confirmed that this solves the problem for me.

Copy link
Member

@bluetech bluetech left a comment

Choose a reason for hiding this comment

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

AFAIK there is no type-safe way to do this in current python, so Mapping sounds OK to me -- for the monkeypatch use case, some type unsafety seems better than forcing users to cast or type-ignore.

I left some comments.

changelog/10999.bugfix.rst Outdated Show resolved Hide resolved
src/_pytest/monkeypatch.py Outdated Show resolved Hide resolved
src/_pytest/monkeypatch.py Outdated Show resolved Hide resolved
testing/typing_checks.py Outdated Show resolved Hide resolved
testing/typing_checks.py Outdated Show resolved Hide resolved
@adamjstewart
Copy link
Contributor Author

Seems like Mapping doesn't work either since it's read-only and doesn't define __setitem__ or __delitem__. Could we use plain dict instead?

@bluetech
Copy link
Member

We will need to type: ignore the errors inside the functions, i.e. encapsulate the type unsafety for the user. It would also be nice to add a code comment explaining why we're doing it (=> typed dicts).

Copy link
Member

@bluetech bluetech left a comment

Choose a reason for hiding this comment

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

Thanks!

@bluetech bluetech merged commit 3b5b3cf into pytest-dev:main May 14, 2023
25 checks passed
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.

monkeypatch.setitem type hints do not support TypedDict
3 participants