Skip to content
Snippets Groups Projects
Unverified Commit a8ae7a56 authored by Miss Islington (bot)'s avatar Miss Islington (bot) Committed by GitHub
Browse files

bpo-45762: Improve docs for ``@singledispatch``/``@singledispatchmethod`` (GH-29426) (GH-29430)


(cherry picked from commit 71e8a3e7)

Co-authored-by: default avatarAlex Waygood <Alex.Waygood@Gmail.com>
parent 276a3a6a
No related branches found
No related tags found
No related merge requests found
...@@ -392,8 +392,8 @@ The :mod:`functools` module defines the following functions: ...@@ -392,8 +392,8 @@ The :mod:`functools` module defines the following functions:
dispatch>` :term:`generic function`. dispatch>` :term:`generic function`.
To define a generic function, decorate it with the ``@singledispatch`` To define a generic function, decorate it with the ``@singledispatch``
decorator. Note that the dispatch happens on the type of the first argument, decorator. When defining a function using ``@singledispatch``, note that the
create your function accordingly:: dispatch happens on the type of the first argument::
>>> from functools import singledispatch >>> from functools import singledispatch
>>> @singledispatch >>> @singledispatch
...@@ -403,9 +403,9 @@ The :mod:`functools` module defines the following functions: ...@@ -403,9 +403,9 @@ The :mod:`functools` module defines the following functions:
... print(arg) ... print(arg)
To add overloaded implementations to the function, use the :func:`register` To add overloaded implementations to the function, use the :func:`register`
attribute of the generic function. It is a decorator. For functions attribute of the generic function, which can be used as a decorator. For
annotated with types, the decorator will infer the type of the first functions annotated with types, the decorator will infer the type of the
argument automatically:: first argument automatically::
>>> @fun.register >>> @fun.register
... def _(arg: int, verbose=False): ... def _(arg: int, verbose=False):
...@@ -431,17 +431,17 @@ The :mod:`functools` module defines the following functions: ...@@ -431,17 +431,17 @@ The :mod:`functools` module defines the following functions:
... ...
To enable registering lambdas and pre-existing functions, the To enable registering :term:`lambdas<lambda>` and pre-existing functions,
:func:`register` attribute can be used in a functional form:: the :func:`register` attribute can also be used in a functional form::
>>> def nothing(arg, verbose=False): >>> def nothing(arg, verbose=False):
... print("Nothing.") ... print("Nothing.")
... ...
>>> fun.register(type(None), nothing) >>> fun.register(type(None), nothing)
The :func:`register` attribute returns the undecorated function which The :func:`register` attribute returns the undecorated function. This
enables decorator stacking, pickling, as well as creating unit tests for enables decorator stacking, :mod:`pickling<pickle>`, and the creation
each variant independently:: of unit tests for each variant independently::
>>> @fun.register(float) >>> @fun.register(float)
... @fun.register(Decimal) ... @fun.register(Decimal)
...@@ -476,11 +476,12 @@ The :mod:`functools` module defines the following functions: ...@@ -476,11 +476,12 @@ The :mod:`functools` module defines the following functions:
Where there is no registered implementation for a specific type, its Where there is no registered implementation for a specific type, its
method resolution order is used to find a more generic implementation. method resolution order is used to find a more generic implementation.
The original function decorated with ``@singledispatch`` is registered 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. implementation is found.
If an implementation registered to :term:`abstract base class`, virtual If an implementation is registered to an :term:`abstract base class`,
subclasses will be dispatched to that implementation:: virtual subclasses of the base class will be dispatched to that
implementation::
>>> from collections.abc import Mapping >>> from collections.abc import Mapping
>>> @fun.register >>> @fun.register
...@@ -493,7 +494,7 @@ The :mod:`functools` module defines the following functions: ...@@ -493,7 +494,7 @@ The :mod:`functools` module defines the following functions:
>>> fun({"a": "b"}) >>> fun({"a": "b"})
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:: a given type, use the ``dispatch()`` attribute::
>>> fun.dispatch(float) >>> fun.dispatch(float)
...@@ -516,7 +517,7 @@ The :mod:`functools` module defines the following functions: ...@@ -516,7 +517,7 @@ The :mod:`functools` module defines the following functions:
.. versionadded:: 3.4 .. versionadded:: 3.4
.. versionchanged:: 3.7 .. versionchanged:: 3.7
The :func:`register` attribute supports using type annotations. The :func:`register` attribute now supports using type annotations.
.. class:: singledispatchmethod(func) .. class:: singledispatchmethod(func)
...@@ -525,8 +526,9 @@ The :mod:`functools` module defines the following functions: ...@@ -525,8 +526,9 @@ The :mod:`functools` module defines the following functions:
dispatch>` :term:`generic function`. dispatch>` :term:`generic function`.
To define a generic method, decorate it with the ``@singledispatchmethod`` To define a generic method, decorate it with the ``@singledispatchmethod``
decorator. Note that the dispatch happens on the type of the first non-self decorator. When defining a function using ``@singledispatchmethod``, note
or non-cls argument, create your function accordingly:: that the dispatch happens on the type of the first non-*self* or non-*cls*
argument::
class Negator: class Negator:
@singledispatchmethod @singledispatchmethod
...@@ -542,9 +544,10 @@ The :mod:`functools` module defines the following functions: ...@@ -542,9 +544,10 @@ The :mod:`functools` module defines the following functions:
return not arg return not arg
``@singledispatchmethod`` supports nesting with other decorators such as ``@singledispatchmethod`` supports nesting with other decorators such as
``@classmethod``. Note that to allow for ``dispatcher.register``, :func:`@classmethod<classmethod>`. Note that to allow for
``singledispatchmethod`` must be the *outer most* decorator. Here is the ``dispatcher.register``, ``singledispatchmethod`` must be the *outer most*
``Negator`` class with the ``neg`` methods being class bound:: decorator. Here is the ``Negator`` class with the ``neg`` methods bound to
the class, rather than an instance of the class::
class Negator: class Negator:
@singledispatchmethod @singledispatchmethod
...@@ -562,8 +565,9 @@ The :mod:`functools` module defines the following functions: ...@@ -562,8 +565,9 @@ The :mod:`functools` module defines the following functions:
def _(cls, arg: bool): def _(cls, arg: bool):
return not arg return not arg
The same pattern can be used for other similar decorators: ``staticmethod``, The same pattern can be used for other similar decorators:
``abstractmethod``, and others. :func:`@staticmethod<staticmethod>`,
:func:`@abstractmethod<abc.abstractmethod>`, and others.
.. versionadded:: 3.8 .. versionadded:: 3.8
......
Improve documentation for :func:`functools.singledispatch` and
:class:`functools.singledispatchmethod`.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment