Skip to content

singledispatch.register fails for lru_cache decorated functions #132064

Closed
@lczyk

Description

@lczyk

Bug report

Function decorated with both @singledispatch.register and @lru_chache fails with a cryptic error message.

EDIT: In python 3.14a6. It works in python 3.9~3.13.

Bug description:

import sys
from functools import lru_cache, singledispatch, wraps
from typing import Any, Callable

def wrapped_lru_cache[T: Callable](maxsize: int = 1024) -> Callable[[T], T]:
    def decorator(func: T) -> T:
        @wraps(func)
        def wrapper(*args: Any, **kwargs: Any) -> Any:
            return lru_cache(maxsize=maxsize)(func)(*args, **kwargs)
        return wrapper  # type: ignore
    return decorator

if len(sys.argv) > 1 and sys.argv[1] == "--broken-in-py314":
    # does not work in python 3.14+
    lru = lru_cache
else:
    # workaround
    lru = wrapped_lru_cache

@singledispatch
def fun(x: str | tuple) -> int:
    raise TypeError(f"Input must be str or tuple not a {type(x)}")

@fun.register
@lru(maxsize=1024)  # <- this
def _(x: str) -> int:
    return len(x)

@fun.register
def _(x: tuple) -> int:
    sum = 0
    for e in x:
        sum += fun(e)
    return sum

if __name__ == "__main__":
    print(f"{fun("hello")=}")
    print(f"{fun(("hello", "sailor"))=}")

python ./singledispatch_mwe.py, but python ./singledispatch_mwe.py --broken-in-py314 produces the following error:

Traceback (most recent call last):
  File ".../singledispatch_mwe.py", line 25, in <module>
    @fun.register
     ^^^^^^^^^^^^
  File "~/.local/share/uv/python/cpython-3.14.0a6-macos-aarch64-none/lib/python3.14/functools.py", line 963, in register
    argname, cls = next(iter(get_type_hints(func, format=Format.FORWARDREF).items()))

In python 3.9~3.13 both of the above work.

CPython versions tested on:

3.9~3.14

Operating systems tested on:

macOS

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.14bugs and security fixesstdlibPython modules in the Lib dirtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions