-
-
Notifications
You must be signed in to change notification settings - Fork 30.4k
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
Add support for PEP 612 (Parameter Specification Variables) to typing.py #85731
Comments
We need stub versions of ParamSpec and Concatenate added to typing.py, plus tests that ensure these actually work in all situations required by the PEP. (It's not so important to ensure that they raise exceptions at runtime in cases where the PEP says they needn't work -- static type checkers will flag those better.) |
Thanks for working on this -- let me know when you have a question for me. Once this is ready we should also add it to the typing_extensions module so people can use it on older Python versions. (https://github.com/python/typing/tree/master/typing_extensions) |
I have a one question: Thanks for your help! |
I wrote class C(Generic[T, P]): ... and was surprised that C.__parameters__ was (T,) instead of (T, P). |
I'm now encountering many problems with how typing works which prevent what PEP-612 declare as valid from not throwing an error (these are all examples copied from the PEP):: class X(Generic[T, P]): ...
class Z(Generic[P]): ...
I have a feeling your wish of greatly loosening type checks will come true ;). Should we proceed with that? That'd fix 1, 2, 3. The only showstopper now is 4. A quick idea is to just disable the check for len(args) == len(parameters) if there's only a single ParamSpec in __parameters__. |
How would you fix it? By just allowing it? But then X.__args__ would be unhashable (see the other issue we're working on together).
I don't like using EllipsisType here, because this notation doesn't mean that we accept an ellipsis here -- it means (if I understand the PEP correctly) that we don't care about the paramspec.
Same comment.
The code should check that __parameters__ is (P,) for some ParamSpec P, and then transform this internally as if it was written Z[[int, str, bool]] and then typecheck that. **BUT...** How about an alternative implementation where as soon as we see that there's a ParamSpec in __parameters__ we just don't type-check at all, and accept anything? Leave it to the static type checker. Our goal here should be to support the syntax that PEP-612 describes so static type checkers can implement it, not to implement all the requirements described by the PEP at runtime. I wonder what Pyre has in its stub files for ParamSpec -- maybe we can borrow that? |
For reference, here's what Pyre has (though it's an older version): https://github.com/facebook/pyre-check/tree/master/pyre_extensions |
The pyre version in their __init__.py looks like they took your advice for I'm not in favour of type checking either. Just that the pre-existing code Not type checking when seeing ~P in __parameters__ would work, just that |
I started doing this in the original code (long ago when PEP-484 was brand |
This is now unblocked now that #67249 has landed. |
Huge thanks! I think the next step is to port the essence to typing_extensions, which has to work for anything from 3.5 up (or maybe 3.6), *including* 3.10 and above. https://github.com/python/typing/tree/master/typing_extensions Honestly maybe we could just make ParamSpec an alias for TypeVar there, and make Concatenate an alias for Tuple? Because "work" just means that the syntax needs to be valid, the type checkers are responsible for using it. (We're still working on getting this to work for mypy.) |
Thanks for the extremely helpful reviews and help in this Guido! Sure, I'll probably start work on that next week, slightly busy with life right now. After that I'll work on docs. |
Looks like we can close this now, right? You can open a separate issue in the python/typing repo to update typing_extensions. |
I have just one more PR - one that converts genericalias nested lists to |
Hi Guido, after a month of observing how people stumbled over the related collections.abc.Callable bugs, and experience from implementing this PEP, I learnt a few things which I think may interest you: Previously it was *recommended* that everything in typing be hashable. I would now say it is *required*. Union uses sets to de-duplicate arguments, and Optional uses Union internally. Both blow up if things aren't hashable. A surprising number of people caught the collections.abc.Callable bug because Optional[Callable[.....]] failed. Going forward, future PEPs to typing.py probably need to ensure their implementations are hashable, or risk not working with some of the types in the module itself. Alternatively, they can always change the implementations of Union and Optional, though I don't know if I recommend that ;). Thanks for your time. |
Guido, I hope I didn't choose a bad time to send this PR over (I suspect you may already be flooded by emails about PEP-563). The jist of the PR is that it's possible to implement PEP-612 in pure-Python. Specifically, PEP-612 says:
https://www.python.org/dev/peps/pep-0612/#valid-use-locations Currently, the implementation treats By implementing this in pure Python, we can:
What do you think? |
Yeah, like this idea. Let’s get this in before beta 1. |
The last of the patches have landed. Guido, thank you so much for helping me through this 5 month long process. Please enjoy your vacation! PS: I need to send in a bugfix for typing.py later to ignore |
Thanks for your major contribution, Ken! Agreed, that bugfix can come later. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: