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 1b54077ff6)

Co-authored-by: Yurii Karabas <1998uriyyo@gmail.com>
This commit is contained in:
Miss Islington (bot) 2020-11-19 08:51:01 -08:00 committed by GitHub
parent 87c87b5bd6
commit 2acd9d0c6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 9 additions and 4 deletions

View File

@ -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::

View File

@ -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))

View File

@ -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: