Skip to content

Literal[...] deduplication silently skips when values are unhashable #153896

Description

@Maxinho96

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    sprintstdlibStandard Library Python modules in the Lib/ directorytopic-typingtype-bugAn unexpected behavior, bug, or error

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions