Skip to content

functools.singledispatch registration prioritizes the types of normal arguments before positional-only ones #143886

Open

Description

@pR0Ps

Bug report

Bug description:

Decorator-based functools.singledispatch registration prioritizes the types of normal arguments before positional-only ones when getting "the type of the first argument".

This means that a function of def f(pos: str, /, other: int) will be registered to be dispatched for other's type (int) instead of pos (str).

To reproduce:

import functools

@functools.singledispatch
def f(arg, /, extra):
    return f"{arg}: undispatched type"

@f.register
def f_int(arg: int, /, extra: str):
    return f"{arg} is a {type(arg)} (dispatched by int)"

@f.register
def f_str(arg: str, /, extra: int):
    return f"{arg} is a {type(arg)} (dispatched by str)"

print(f(None, "extra"))
print(f(1, "extra"))
print(f("s", "extra"))

Result:

None: undispatched type
1 is a <class 'int'> (dispatched by str)
s is a <class 'str'> (dispatched by int)

Expected:

None: undispatched type
1 is a <class 'int'> (dispatched by int)
s is a <class 'str'> (dispatched by str)

CPython versions tested on:

3.9, 3.10, 3.11, 3.12, 3.13, 3.14, CPython main branch

Operating systems tested on:

macOS

Linked PRs

Activity

  1. added
    type-bugAn unexpected behavior, bug, or error
    on Jan 15, 2026
  2. JelleZijlstra commented on Jan 15, 2026

    @JelleZijlstra
    Member

    That's a good catch! I think #84644 should fix this too.

    Your fix is good but the trouble is that it changed compiled code, so compiled pycs won't see the fix, unless we bump the magic number. And we don't generally want to bump the magic number in bugfix releases.

  3. pR0Ps commented on Jan 15, 2026

    @pR0Ps
    ContributorAuthor

    You're right, #84644 looks like it should fix function registrations with positional-only args. Since it changes it to no longer rely on the order of hints returned from typing.get_type_hints, them being out of order wouldn't matter anymore.

    I still think that the order that get_type_hints returns should be fixed so that it matches how the arguments are defined, but like you said, maybe that can wait until the next non-bugfix release.

  4. added
    stdlibStandard Library Python modules in the Lib/ directory
    on Jan 16, 2026
  5. added
    3.13only security fixes
    3.14bugs and security fixes
    3.15bugs and security fixes
    on Jan 16, 2026
  6. pR0Ps commented on Apr 14, 2026

    @pR0Ps
    ContributorAuthor

    compiled pycs won't see the fix, unless we bump the magic number. And we don't generally want to bump the magic number in bugfix releases.

    What's the process for fixing something like this? Can it be merged at any point and only after the next magic number bump take effect? Or would merging it and bumping the number need to be done in the same PR?

  7. JelleZijlstra commented on Apr 15, 2026

    @JelleZijlstra
    Member

    We don't bump the magic number in bugfix branches. I think your fix is good for the long term and if you get CI green I will merge it, but we can't apply that change in 3.14 and 3.13; for that we need some version of #143465.

  8. added a commit that references this issue on Apr 15, 2026
  9. added a commit that references this issue on Apr 25, 2026
  10. pR0Ps commented on Oct 16, 2026

    @pR0Ps
    ContributorAuthor

    @JelleZijlstra Should this be closed now that #143888 has been released in 3.15? Or should it stay open until #143465 can be merged and backported to 3.14?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.13only security fixes3.14bugs and security fixes3.15bugs and security fixesstdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions