Bug report
Bug description:
https://gist.github.com/devdanzin/3198710e3c0128fda5e0a7b4e0768e5f#5-literal-deduplication-silently-skips-when-values-are-unhashable
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
Bug report
Bug description:
https://gist.github.com/devdanzin/3198710e3c0128fda5e0a7b4e0768e5f#5-literal-deduplication-silently-skips-when-values-are-unhashable
Findings
The issue text is wrong: the
unhashable_fallbackparam is not used inAnnotatedor 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_deduplicatewithunhashable_fallback=Trueto handle unhashable metadata.Why it is not used now:
In commit dc6d66f (gh-105499 / PR #105511, Mar 2025),
typing.Unionwas merged withtypes.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=Truedisappeared.Today,
_deduplicatestill 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:
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_fallbackparam anyway, and change the failing test, since the intended behavior doesn't seem right to me as of today: I thinkLiteralshould always deduplicate, even when the params are unhashable.CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Linked PRs
Literaltype #153913typing.Literal(GH-153914) #153955typing.Literal(GH-153914) #153956typing.Literal(GH-153914) #153957