Skip to content

Commit

Permalink
Fix ParamSpec ellipsis default for <3.10 (#279)
Browse files Browse the repository at this point in the history
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
  • Loading branch information
Gobot1234 and AlexWaygood authored Sep 6, 2023
1 parent 4705e74 commit 13c9484
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
called on a concrete subclass of a generic class. Patch by Alex Waygood
(backporting https://github.com/python/cpython/pull/107584, by James
Hilton-Balfe).
- Fix bug where `ParamSpec(default=...)` would raise a `TypeError` on Python
versions <3.11. Patch by James Hilton-Balfe

# Release 4.7.1 (July 2, 2023)

Expand Down
5 changes: 5 additions & 0 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,11 @@ Special typing primitives

The implementation was changed for compatibility with Python 3.12.

.. versionchanged:: 4.8.0

Passing an ellipsis literal (``...``) to *default* now works on Python
3.10 and lower.

.. class:: ParamSpecArgs

.. class:: ParamSpecKwargs
Expand Down
3 changes: 3 additions & 0 deletions src/test_typing_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5593,6 +5593,9 @@ def test_paramspec(self):
class A(Generic[P]): ...
Alias = typing.Callable[P, None]

P_default = ParamSpec('P_default', default=...)
self.assertIs(P_default.__default__, ...)

def test_typevartuple(self):
Ts = TypeVarTuple('Ts', default=Unpack[Tuple[str, int]])
self.assertEqual(Ts.__default__, Unpack[Tuple[str, int]])
Expand Down
5 changes: 4 additions & 1 deletion src/typing_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1277,7 +1277,10 @@ def _set_default(type_param, default):
type_param.__default__ = tuple((typing._type_check(d, "Default must be a type")
for d in default))
elif default != _marker:
type_param.__default__ = typing._type_check(default, "Default must be a type")
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")
else:
type_param.__default__ = None

Expand Down

0 comments on commit 13c9484

Please sign in to comment.