Fix ParamSpec ellipsis default for <3.10#279
Conversation
AlexWaygood
left a comment
There was a problem hiding this comment.
CHANGELOG entry/docs? :-)
If this fixes an issue you hit, other people might have hit it too, so they probably deserve to know about the fix!
|
The change itself looks good, but please add a changelog/docs entry as Alex requested. For reference, PEP 696 explicitly allows this: https://peps.python.org/pep-0696/#paramspec-defaults |
|
Oh weird, it doesn't seem to have pushed the changes |
JelleZijlstra
left a comment
There was a problem hiding this comment.
Looks good but @AlexWaygood please take a look too.
I'll likely cut a new release once the PEP 727 (Doc()) changes are in.
| if isinstance(type_param, ParamSpec) and default is ...: # ... not valid <3.11 | ||
| type_param.__default__ = default | ||
| else: | ||
| type_param.__default__ = typing._type_check(default, "Default must be a type") |
There was a problem hiding this comment.
Aha, so the issue is that typing._type_check changed in Python 3.11 so that it would accept an ellipsis, but the function didn't allow it on previous versions of CPython
AlexWaygood
left a comment
There was a problem hiding this comment.
Looks reasonable to me, other than my point about the docs.
Another possible fix could be to vendor the current version of _type_check from the CPython main branch, since we use that function quite a lot in typing_extensions, and there might have been other changes to _type_check in recent versions of CPython that are causing bugs we don't know about yet in typing_extensions. It would be a more invasive change, though; I think this fix is fine for now
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
I think its this change FWIW python/cpython@870b22b |
Riiight... so we probably can't use |
lol, confirmed: Python 3.9.12 (main, Apr 4 2022, 05:22:27) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from typing_extensions import *
>>> P = ParamSpec("P")
>>> Annotated[P.args, 'foo']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\alexw\.conda\envs\py39\lib\typing.py", line 277, in inner
return func(*args, **kwds)
File "C:\Users\alexw\.conda\envs\py39\lib\typing.py", line 1340, in __class_getitem__
origin = _type_check(params[0], msg, allow_special_forms=True)
File "C:\Users\alexw\.conda\envs\py39\lib\typing.py", line 166, in _type_check
raise TypeError(f"{msg} Got {arg!r:.100}.")
TypeError: Annotated[t, ...]: t must be a type. Got P.args.Works fine with Python 3.11.2 (tags/v3.11.2:878ead1, Feb 7 2023, 16:38:35) [MSC v.1934 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from typing import *
>>> P = ParamSpec("P")
>>> Annotated[P.args, 'foo']
typing.Annotated[P.args, 'foo'] |
|
We probably should vendor |
|
Sure |
hmm... seems tricky to just copy over the py311+ implementation of |
|
Thanks for investigating! That feels like it might be more trouble than a purely hypothetical use case is worth. Adding our own ForwardRef would potentially break users who do |
No description provided.