From 2cf2fc14672430c82763b3eb934c10909cae6ecf Mon Sep 17 00:00:00 2001 From: TheMuffinMan1320 <76186189+TheMuffinMan1320@users.noreply.github.com> Date: Thu, 13 Aug 2026 14:48:08 -0500 Subject: [PATCH] Fix crash when singledispatch is shadowed by a user function (#20339) The functools.singledispatch plugin hook is matched purely by fully qualified name. If a user's own module happens to produce a function whose fullname is exactly "functools.singledispatch" (e.g. a top-level module literally named functools.py defining its own singledispatch function), the hook fires even though the return type is not an Instance of functools._SingleDispatchCallable, tripping an assert and crashing mypy. Bail out gracefully instead. --- mypy/plugins/singledispatch.py | 3 ++- test-data/unit/check-singledispatch.test | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/mypy/plugins/singledispatch.py b/mypy/plugins/singledispatch.py index 9a5576c17e82c..7fb01985f8e4a 100644 --- a/mypy/plugins/singledispatch.py +++ b/mypy/plugins/singledispatch.py @@ -106,7 +106,8 @@ def create_singledispatch_function_callback(ctx: FunctionContext) -> Type: # singledispatch returns an instance of functools._SingleDispatchCallable according to # typeshed singledispatch_obj = get_proper_type(ctx.default_return_type) - assert isinstance(singledispatch_obj, Instance) + if not isinstance(singledispatch_obj, Instance): + return ctx.default_return_type singledispatch_obj.args += (func_type,) return ctx.default_return_type diff --git a/test-data/unit/check-singledispatch.test b/test-data/unit/check-singledispatch.test index 36c99b288bbe8..eb172acba3673 100644 --- a/test-data/unit/check-singledispatch.test +++ b/test-data/unit/check-singledispatch.test @@ -307,3 +307,15 @@ def default(val) -> int: return 3 [builtins fixtures/args.pyi] + +[case testDontCrashWhenSingledispatchIsShadowedByUserFunction] +# cmd: mypy -m functools +[file functools.py] +def singledispatch(func): + pass + +@singledispatch +def f(fn): + pass +[out] +[builtins fixtures/args.pyi]