Skip to content

Conversation

@dangotbanned
Copy link
Member

@dangotbanned dangotbanned commented Jan 22, 2026

Description

Adds a slimmed-down version of @functools.singledispatch, with the initial use replacing _supertyping._same_supertype in #3396.

I can see a few other places (particularly DType-related) that could later benefit.
So, I went ahead and added more tests + docs than I would normally do for an internal tool.

Why not @functools.singledispatch?

Most of the stdlib code is dedicated to two features I don't want to use.

mro-based dispatch

That allows you to register ABCs (like Mapping, Iterable, etc) or any regular class and have it's subclasses match.

Definitely pretty clever stuff, but I'd prefer to have a simpler version that needs every class to be added explicitly

Registration via annotation

Forward references are resolved eagerly1 and only classes and unions of classes are supported.

IMO, that's just a complicated way of accepting *types: type[Any] in the decorator - so I did that instead 😅

Related issues

Footnotes

  1. ibis has @lazy_singledispatch that appears to solve this issue

Comment on lines +27 to +29
# Default implementation serves as a fallback for subclasses of `upper_bound`
@just_dispatch(upper_bound=DType)
def dtype_repr_code(dtype: DType) -> str:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of these comments are an attempt at a literate style 🙂

Initially I wanted to have some examples in the docstrings (in _dispatch.py), but:

  • Anything non-trivial requires a very large docstring
  • I couldn't think of anything simple that captures the strengths of the concept

@dangotbanned dangotbanned marked this pull request as ready for review January 22, 2026 12:40
Comment on lines +57 to +63
def register( # noqa: D417
self, tp: type[Any], *tps: type[Any]
) -> Callable[[Passthrough], Passthrough]:
"""Register types to dispatch via the decorated function.

Arguments:
*tps: One or more **concrete** types.
Copy link
Member Author

@dangotbanned dangotbanned Jan 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've left out validating the types for now.

  • 3.9: @functools.singledispatch supports type[Any]
  • 3.10: Same support, but that's the version which introduces types.UnionType
  • 3.11: @functools.singledispatch supports typing.Union | types.UnionType | type[Any]

Since #3204 is not resolved, I'd rather leave this runtime check until then

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants