In this usage of singledispatchmethod:
from functools import singledispatchmethod class C: @singledispatchmethod def d(self, x): return "base!" @d.register(int) def _(self, x): return "int!" print(C.d(C(), 1))
This is what I expected in the output:
int!
But instead this was printed out:
base!
singledispatch and singledispatchmethod don't analyze and adapt argument semantics to the registered callable type, which makes them very nice and simple.
_singledispatchmethod_get always dispatches on args[0] regardless of whether it's bound or unbound, and if it didn't, that would break descriptor support; this facet is crucial for staticmethod (and classmethod) dispatches to work:
from functools import singledispatchmethod class C: @singledispatchmethod @staticmethod def d(x): return "base!" @d.register(int) @staticmethod def s(x): return "int!" print(C.d(1)) # int!
Our tests rely on this and possibly millions of projects rely on this.
I think we could document this explicitly (and backport to 3.13 and 3.14).
Found this while working on GH-143465.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux