diff --git a/typing_extensions/CHANGELOG b/typing_extensions/CHANGELOG index 975a0032d..c96bd34de 100644 --- a/typing_extensions/CHANGELOG +++ b/typing_extensions/CHANGELOG @@ -1,5 +1,7 @@ # Release 4.x.x +- `ParamSpec` args and kwargs are now equal to themselves. Backport from + bpo-46676. Patch by Gregory Beauregard (@GBeauregard). - Add `reveal_type`. Backport from bpo-46414. - Runtime support for PEP 681 and `typing_extensions.dataclass_transform`. - `Annotated` can now wrap `ClassVar` and `Final`. Backport from diff --git a/typing_extensions/src/test_typing_extensions.py b/typing_extensions/src/test_typing_extensions.py index 03a75e4c4..4e1d95ff6 100644 --- a/typing_extensions/src/test_typing_extensions.py +++ b/typing_extensions/src/test_typing_extensions.py @@ -2057,8 +2057,10 @@ def test_valid_uses(self): self.assertTrue(hasattr(P, 'args')) self.assertTrue(hasattr(P, 'kwargs')) + @skipIf((3, 10, 0) <= sys.version_info[:3] <= (3, 10, 2), "Needs bpo-46676.") def test_args_kwargs(self): P = ParamSpec('P') + P_2 = ParamSpec('P_2') # Note: not in dir(P) because of __class__ hacks self.assertTrue(hasattr(P, 'args')) self.assertTrue(hasattr(P, 'kwargs')) @@ -2066,6 +2068,13 @@ def test_args_kwargs(self): self.assertIsInstance(P.kwargs, ParamSpecKwargs) self.assertIs(P.args.__origin__, P) self.assertIs(P.kwargs.__origin__, P) + self.assertEqual(P.args, P.args) + self.assertEqual(P.kwargs, P.kwargs) + self.assertNotEqual(P.args, P_2.args) + self.assertNotEqual(P.kwargs, P_2.kwargs) + self.assertNotEqual(P.args, P.kwargs) + self.assertNotEqual(P.kwargs, P.args) + self.assertNotEqual(P.args, P_2.kwargs) self.assertEqual(repr(P.args), "P.args") self.assertEqual(repr(P.kwargs), "P.kwargs") diff --git a/typing_extensions/src/typing_extensions.py b/typing_extensions/src/typing_extensions.py index b594e33f7..27eaff0f8 100644 --- a/typing_extensions/src/typing_extensions.py +++ b/typing_extensions/src/typing_extensions.py @@ -1635,6 +1635,11 @@ def __init__(self, origin): def __repr__(self): return f"{self.__origin__.__name__}.args" + def __eq__(self, other): + if not isinstance(other, ParamSpecArgs): + return NotImplemented + return self.__origin__ == other.__origin__ + class ParamSpecKwargs(_Immutable): """The kwargs for a ParamSpec object. @@ -1653,6 +1658,11 @@ def __init__(self, origin): def __repr__(self): return f"{self.__origin__.__name__}.kwargs" + def __eq__(self, other): + if not isinstance(other, ParamSpecKwargs): + return NotImplemented + return self.__origin__ == other.__origin__ + # 3.10+ if hasattr(typing, 'ParamSpec'): ParamSpec = typing.ParamSpec