https://github.com/python/cpython/commit/6fd942a17dc8354dfc998edf1e1f60b049c3c0b1 commit: 6fd942a17dc8354dfc998edf1e1f60b049c3c0b1 branch: 3.13 author: Miss Islington (bot) <[email protected]> committer: tomasr8 <[email protected]> date: 2026-07-19T09:56:21+02:00 summary:
[3.13] gh-153896: Deduplicate unhashable arguments in `typing.Literal` (GH-153914) (#153957) gh-153896: Deduplicate unhashable arguments in `typing.Literal` (GH-153914) (cherry picked from commit a53b5b126749133e50692fe0c3729f5580ee8500) Co-authored-by: Massimiliano Bruni <[email protected]> files: A Misc/NEWS.d/next/Library/2026-07-18-10-52-10.gh-issue-153896.87oevp.rst M Lib/test/test_typing.py M Lib/typing.py diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 5e7f40c42b52e9..92b90fac3575df 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -2728,8 +2728,14 @@ def test_args(self): self.assertEqual(Literal[1, 2, 3].__args__, (1, 2, 3)) self.assertEqual(Literal[1, 2, 3, 3].__args__, (1, 2, 3)) self.assertEqual(Literal[1, Literal[2], Literal[3, 4]].__args__, (1, 2, 3, 4)) - # Mutable arguments will not be deduplicated - self.assertEqual(Literal[[], []].__args__, ([], [])) + # Unhashable arguments will be deduplicated too + self.assertEqual(Literal[[], []].__args__, ([],)) + self.assertEqual(Literal[{"a": 1}, {"a": 1}].__args__, ({"a": 1},)) + self.assertEqual( + Literal[1, {'a': 'b'}, 2, {'a': 'b'}, 3].__args__, + (1, {'a': 'b'}, 2, 3), + ) + self.assertEqual(Literal[{1}, {1}, {2}, {2}].__args__, ({1}, {2})) def test_flatten(self): l1 = Literal[Literal[1], Literal[2], Literal[3]] diff --git a/Lib/typing.py b/Lib/typing.py index 381aaf3c7d080e..3be82699b54fb6 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -835,13 +835,16 @@ def open_helper(file: str, mode: MODE) -> str: # There is no '_type_check' call because arguments to Literal[...] are # values, not types. parameters = _flatten_literal_params(parameters) + value_and_type_parameters = list(_value_and_type_iter(parameters)) + deduplicated_parameters = tuple( + p + for p, _ in _deduplicate( + value_and_type_parameters, + unhashable_fallback=True, + ) + ) - try: - parameters = tuple(p for p, _ in _deduplicate(list(_value_and_type_iter(parameters)))) - except TypeError: # unhashable parameters - pass - - return _LiteralGenericAlias(self, parameters) + return _LiteralGenericAlias(self, deduplicated_parameters) @_SpecialForm diff --git a/Misc/NEWS.d/next/Library/2026-07-18-10-52-10.gh-issue-153896.87oevp.rst b/Misc/NEWS.d/next/Library/2026-07-18-10-52-10.gh-issue-153896.87oevp.rst new file mode 100644 index 00000000000000..217a3d3d272ed0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-18-10-52-10.gh-issue-153896.87oevp.rst @@ -0,0 +1 @@ +Deduplicate unhashable args in :data:`typing.Literal`. _______________________________________________ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3//lists/python-checkins.python.org Member address: [email protected]
