-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Use TypeVar defaults for Generator
and AsyncGenerator
#11867
Conversation
Generator
and AsyncGenerator
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Quick analysis of the new error from mypy primer: def _internal_run_as_gen(self) -> Generator: The main change would be for MyPy users not providing generics, as |
Generator
and AsyncGenerator
Generator
, AsyncGenerator
, and Coroutine
Generator
, AsyncGenerator
, and Coroutine
Generator
and AsyncGenerator
82aeba8
to
0974b0a
Compare
0974b0a
to
01172b4
Compare
Diff from mypy_primer, showing the effect of this PR on open source code: ignite (https://github.com/pytorch/ignite)
+ ignite/engine/engine.py:1010: error: No return value expected [return-value]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! This looks like a good change to me, but I'll leave it open for a bit, in case another maintainer disagrees.
Unfortunately this will not work at runtime, if you try to omit just one or both of the optional type parameters, I ran into a similar issue when I tried to retain the extra parameter I added for >>> from typing import Generator
>>> Generator[int]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python3.12/typing.py", line 398, in inner
return func(*args, **kwds)
^^^^^^^^^^^^^^^^^^^
File "/usr/lib64/python3.12/typing.py", line 1455, in __getitem__
_check_generic(self, params, self._nparams)
File "/usr/lib64/python3.12/typing.py", line 304, in _check_generic
raise TypeError(f"Too {'many' if alen > elen else 'few'} arguments for {cls};"
TypeError: Too few arguments for typing.Generator; actual 1, expected 3
>>> It's not great that the type checker is hiding a runtime error this way, but it still might be worth the overall convenience for the subset of type annotations that never need to be evaluated at runtime. Either way, if this change were to be accepted, we should probably also open pull requests for CPython and Ideally we can then keep the old parametrization for Python <=3.12 and 3.13 and the |
Added a CPython PR to add defaults to typing.Generator and AsyncGenerator. Note though that the collections.abc versions will already work fine; those don't check their argument counts. |
Thanks! In that case, let me make this conditional on Python 3.13 |
I'm not sure that is right since the |
Sounds good, so we're fine with this not working at runtime with In that case, is there anything left we need to ship this? |
That's fair, for some reason in the back of my mind |
There's plenty of things relating to type params that work at "typing time" but not at runtime. We try to keep these to a minimum, but it's not always possible. For example, mypy accepts the following: from warnings import catch_warnings
x: catch_warnings[None] But it fails at runtime: Python 3.12.2 (main, Feb 15 2024, 19:30:27) [Clang 15.0.0 (clang-1500.1.0.2.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import warnings
>>> warnings.catch_warnings[None]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: type 'catch_warnings' is not subscriptable
>>> So this definitely wouldn't be unprecedented. Ultimately we can't really distinguish between the real classes in |
Following up here, to see if we see any blockers to merging @JelleZijlstra! |
Make use of
TypeVar
defaults, so thatGenerator[int, None, None]
andAsyncGenerator[int, None, None]
can simply be represented asGenerator[int]
andAsyncGenerator[int]
as recommended in PEP 696: https://peps.python.org/pep-0696/There might be good reasons to push this back, but mostly wanted to put this out to get the ball rolling, and see if there was any discussion/thoughts around this.