Skip to content

[3.9] bpo-45726: Improve docs for @singledispatch/@singledispatchmethod (GH-29426) #29430

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 26 additions & 22 deletions Doc/library/functools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,8 @@ The :mod:`functools` module defines the following functions:
dispatch>` :term:`generic function`.

To define a generic function, decorate it with the ``@singledispatch``
decorator. Note that the dispatch happens on the type of the first argument,
create your function accordingly::
decorator. When defining a function using ``@singledispatch``, note that the
dispatch happens on the type of the first argument::

>>> from functools import singledispatch
>>> @singledispatch
Expand All @@ -403,9 +403,9 @@ The :mod:`functools` module defines the following functions:
... print(arg)

To add overloaded implementations to the function, use the :func:`register`
attribute of the generic function. It is a decorator. For functions
annotated with types, the decorator will infer the type of the first
argument automatically::
attribute of the generic function, which can be used as a decorator. For
functions annotated with types, the decorator will infer the type of the
first argument automatically::

>>> @fun.register
... def _(arg: int, verbose=False):
Expand All @@ -431,17 +431,17 @@ The :mod:`functools` module defines the following functions:
...


To enable registering lambdas and pre-existing functions, the
:func:`register` attribute can be used in a functional form::
To enable registering :term:`lambdas<lambda>` and pre-existing functions,
the :func:`register` attribute can also be used in a functional form::

>>> def nothing(arg, verbose=False):
... print("Nothing.")
...
>>> fun.register(type(None), nothing)

The :func:`register` attribute returns the undecorated function which
enables decorator stacking, pickling, as well as creating unit tests for
each variant independently::
The :func:`register` attribute returns the undecorated function. This
enables decorator stacking, :mod:`pickling<pickle>`, and the creation
of unit tests for each variant independently::

>>> @fun.register(float)
... @fun.register(Decimal)
Expand Down Expand Up @@ -476,11 +476,12 @@ The :mod:`functools` module defines the following functions:
Where there is no registered implementation for a specific type, its
method resolution order is used to find a more generic implementation.
The original function decorated with ``@singledispatch`` is registered
for the base ``object`` type, which means it is used if no better
for the base :class:`object` type, which means it is used if no better
implementation is found.

If an implementation registered to :term:`abstract base class`, virtual
subclasses will be dispatched to that implementation::
If an implementation is registered to an :term:`abstract base class`,
virtual subclasses of the base class will be dispatched to that
implementation::

>>> from collections.abc import Mapping
>>> @fun.register
Expand All @@ -493,7 +494,7 @@ The :mod:`functools` module defines the following functions:
>>> fun({"a": "b"})
a => b

To check which implementation will the generic function choose for
To check which implementation the generic function will choose for
a given type, use the ``dispatch()`` attribute::

>>> fun.dispatch(float)
Expand All @@ -516,7 +517,7 @@ The :mod:`functools` module defines the following functions:
.. versionadded:: 3.4

.. versionchanged:: 3.7
The :func:`register` attribute supports using type annotations.
The :func:`register` attribute now supports using type annotations.


.. class:: singledispatchmethod(func)
Expand All @@ -525,8 +526,9 @@ The :mod:`functools` module defines the following functions:
dispatch>` :term:`generic function`.

To define a generic method, decorate it with the ``@singledispatchmethod``
decorator. Note that the dispatch happens on the type of the first non-self
or non-cls argument, create your function accordingly::
decorator. When defining a function using ``@singledispatchmethod``, note
that the dispatch happens on the type of the first non-*self* or non-*cls*
argument::

class Negator:
@singledispatchmethod
Expand All @@ -542,9 +544,10 @@ The :mod:`functools` module defines the following functions:
return not arg

``@singledispatchmethod`` supports nesting with other decorators such as
``@classmethod``. Note that to allow for ``dispatcher.register``,
``singledispatchmethod`` must be the *outer most* decorator. Here is the
``Negator`` class with the ``neg`` methods being class bound::
:func:`@classmethod<classmethod>`. Note that to allow for
``dispatcher.register``, ``singledispatchmethod`` must be the *outer most*
decorator. Here is the ``Negator`` class with the ``neg`` methods bound to
the class, rather than an instance of the class::

class Negator:
@singledispatchmethod
Expand All @@ -562,8 +565,9 @@ The :mod:`functools` module defines the following functions:
def _(cls, arg: bool):
return not arg

The same pattern can be used for other similar decorators: ``staticmethod``,
``abstractmethod``, and others.
The same pattern can be used for other similar decorators:
:func:`@staticmethod<staticmethod>`,
:func:`@abstractmethod<abc.abstractmethod>`, and others.

.. versionadded:: 3.8

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Improve documentation for :func:`functools.singledispatch` and
:class:`functools.singledispatchmethod`.