Bug report
Bug description:
Findings
The issue text is wrong: the unhashable_fallback param is not used in Annotated or anywhere else.
The parameter was added and actively used in commit a7549b0 (gh-112281 / PR #112283, Mar 2024).
In that revision, Union dedup went through _remove_dups_flatten, which called _deduplicate with unhashable_fallback=True to handle unhashable metadata.
Why it is not used now:
In commit dc6d66f (gh-105499 / PR #105511, Mar 2025), typing.Union was merged with types.UnionType.
That rewrite removed the old Python-side Union construction path in typing.py (including _remove_dups_flatten and the old Union special-form machinery), so the only known caller of unhashable_fallback=True disappeared.
Today, _deduplicate still has the keyword parameter, but the remaining in-file call path (Literal handling) does not pass it.
I tried to just pass the argument, but then this existing test fails, which has this comment:
# Mutable arguments will not be deduplicated
The test was added with commit f03d318 , when deduplication of Literals was first introduced. From the commit, it looks like excluding unhashable params from deduplication was the intended behavior.
Proposal
I propose to use the unhashable_fallback param anyway, and change the failing test, since the intended behavior doesn't seem right to me as of today: I think Literal should always deduplicate, even when the params are unhashable.
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Linked PRs
- gh-153896: Deduplicate mutable args in
Literaltype #153913 - gh-153896: Deduplicate unhashable Literal params #153914
- [3.15] gh-153896: Deduplicate unhashable arguments in
typing.Literal(GH-153914) #153955 - [3.14] gh-153896: Deduplicate unhashable arguments in
typing.Literal(GH-153914) #153956 - [3.13] gh-153896: Deduplicate unhashable arguments in
typing.Literal(GH-153914) #153957