singledispatchmethod

Backport of @functools.singledispatchmethod to Python 2.7-3.7.


Keywords
backport, python, singledispatch
License
MIT
Install
pip install singledispatchmethod==1.0

Documentation

singledispatchmethod

Backport of @functools.singledispatchmethod decorator [1] from Python 3.8 to Python 2.7-3.7. These are merely ~30 lines of code, but why bother yourself with copypasta?

$ pip install singledispatchmethod

The decorator transforms a method into a single-dispatch [2] generic function [3]. Note that since the dispatch happens on the type of the first non-self or non-cls argument, you have to create your function accordingly:

from singledispatchmethod import singledispatchmethod

class Negator:

    @singledispatchmethod
    def neg(self, arg):
        raise NotImplementedError("Cannot negate a")

    @neg.register
    def _(self, arg: int):
        return -arg

    @neg.register
    def _(self, arg: bool):
        return not arg

@singledispatchmethod supports nesting with other decorators such as @classmethod. However, in order to expose dispatcher.register, @singledispatchmethod must be the outer most decorator. Here is the Negator class with the neg methods being class bound:

from singledispatchmethod import singledispatchmethod

class Negator:

    @singledispatchmethod
    @classmethod
    def neg(cls, arg):
        raise NotImplementedError("Cannot negate a")

    @neg.register
    @classmethod
    def _(cls, arg: int):
        return -arg

    @neg.register
    @classmethod
    def _(cls, arg: bool):
        return not arg

The same pattern can be used for other similar decorators, such as @staticmethod or @abstractmethod. Please note, since @singledispatchmethod decorator is based on @functools.singledispatch, type annotations are supported by dispatcher.register only since Python 3.7.

[1] https://docs.python.org/3.8/library/functools.html#functools.singledispatchmethod
[2] https://docs.python.org/3.8/glossary.html#term-single-dispatch
[3] https://docs.python.org/3.8/glossary.html#term-generic-function