From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Thu, 19 Nov 2020 16:51:01 +0000 (-0800) Subject: bpo-42345: Fix hash implementation of typing.Literal (GH-23383) X-Git-Tag: v3.9.1rc1~26 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2acd9d0c6ccf0b4360e3b63beddb97996bcb9bb1;p=thirdparty%2FPython%2Fcpython.git bpo-42345: Fix hash implementation of typing.Literal (GH-23383) Fix hash implementation of `typing.Literal`. Update docs regarding `typing.Litaral` caching. Base implementation was done in PR GH-23294. (cherry picked from commit 1b54077ff6f5c1379e097e9f8e8648da9826d6ec) Co-authored-by: Yurii Karabas <1998uriyyo@gmail.com> --- diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 324abdeb5eb5..42a89ce8fb4c 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1687,9 +1687,9 @@ Introspection helpers For a typing object of the form ``X[Y, Z, ...]`` these functions return ``X`` and ``(Y, Z, ...)``. If ``X`` is a generic alias for a builtin or :mod:`collections` class, it gets normalized to the original class. - If ``X`` is a :class:`Union` contained in another generic type, - the order of ``(Y, Z, ...)`` may be different from the order of - the original arguments ``[Y, Z, ...]`` due to type caching. + If ``X`` is a :class:`Union` or :class:`Literal` contained in another + generic type, the order of ``(Y, Z, ...)`` may be different from the order + of the original arguments ``[Y, Z, ...]`` due to type caching. For unsupported objects return ``None`` and ``()`` correspondingly. Examples:: diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 9d82eec3f537..13cf20eee09a 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -573,6 +573,11 @@ class LiteralTests(BaseTestCase): self.assertEqual(Literal[1, 2], Literal[2, 1]) self.assertEqual(Literal[1, 2, 3], Literal[1, 2, 3, 3]) + def test_hash(self): + self.assertEqual(hash(Literal[1]), hash(Literal[1])) + self.assertEqual(hash(Literal[1, 2]), hash(Literal[2, 1])) + self.assertEqual(hash(Literal[1, 2, 3]), hash(Literal[1, 2, 3, 3])) + 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)) diff --git a/Lib/typing.py b/Lib/typing.py index 14952ec6cc69..f5316ab8a5f5 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -932,7 +932,7 @@ class _LiteralGenericAlias(_GenericAlias, _root=True): return set(_value_and_type_iter(self.__args__)) == set(_value_and_type_iter(other.__args__)) def __hash__(self): - return hash(tuple(_value_and_type_iter(self.__args__))) + return hash(frozenset(_value_and_type_iter(self.__args__))) class Generic: