Uh oh!
There was an error while loading. Please reload this page.
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 AsyncGeneratorGenerator, AsyncGenerator, and CoroutineGenerator, AsyncGenerator, and CoroutineGenerator and AsyncGenerator82aeba8 to
0974b0aCompare0974b0a to
01172b4CompareDiff 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] |
srittau
left a comment
There was a problem hiding this comment.
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 >>>fromtypingimportGenerator>>>Generator[int]
Traceback (mostrecentcalllast):
File"<stdin>", line1, in<module>File"/usr/lib64/python3.12/typing.py", line398, ininnerreturnfunc(*args, **kwds)
^^^^^^^^^^^^^^^^^^^File"/usr/lib64/python3.12/typing.py", line1455, in__getitem___check_generic(self, params, self._nparams)
File"/usr/lib64/python3.12/typing.py", line304, in_check_genericraiseTypeError(f"Too {'many'ifalen>elenelse'few'} arguments for {cls};"TypeError: Toofewargumentsfortyping.Generator; actual1, expected3>>>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 |
JelleZijlstra
commented
May 6, 2024
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. |
max-muoto
commented
May 6, 2024
Thanks! In that case, let me make this conditional on Python 3.13 |
JelleZijlstra
commented
May 6, 2024
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? |
Daverball
commented
May 6, 2024
That's fair, for some reason in the back of my mind |
AlexWaygood
commented
May 6, 2024
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: fromwarningsimportcatch_warningsx: 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 |
max-muoto
commented
May 13, 2024
Following up here, to see if we see any blockers to merging @JelleZijlstra! |
Make use of
TypeVardefaults, 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.