[Python-checkins] bpo-42345: Fix hash implementation of typing.Literal (GH-23383)

miss-islington webhook-mailer at python.org
Thu Nov 19 11:51:10 EST 2020


https://github.com/python/cpython/commit/2acd9d0c6ccf0b4360e3b63beddb97996bcb9bb1
commit: 2acd9d0c6ccf0b4360e3b63beddb97996bcb9bb1
branch: 3.9
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: miss-islington <31488909+miss-islington at users.noreply.github.com>
date: 2020-11-19T08:51:01-08:00
summary:

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 at gmail.com>

files:
M Doc/library/typing.rst
M Lib/test/test_typing.py
M Lib/typing.py

diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst
index 324abdeb5eb5b..42a89ce8fb4c6 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 9d82eec3f5376..13cf20eee09ab 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -573,6 +573,11 @@ def test_equal(self):
         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 14952ec6cc695..f5316ab8a5f53 100644
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -932,7 +932,7 @@ def __eq__(self, other):
         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:



More information about the Python-checkins mailing list