Skip to content

Commit aad8cc2

Browse files
authored
Merge pull request #11 from seequent/new-release
New release
2 parents f3bc7ab + f71dbbb commit aad8cc2

File tree

3 files changed

+63
-25
lines changed

3 files changed

+63
-25
lines changed

README.md renamed to README.rst

Lines changed: 61 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
1-
# methoddispatch
1+
methoddispatch
2+
==============
23

3-
[![Build Status](https://travis-ci.com/seequent/methoddispatch.svg?branch=master)](https://travis-ci.com/seequent/methoddispatch)
4+
|Build Status|
45

5-
Python 3.4 added the ``singledispatch`` decorator to the ``functools`` standard library module.
6-
This library extends this functionality to instance methods (and works for functions too).
76

8-
To define a generic method , decorate it with the ``@singledispatch`` decorator. Note that the dispatch happens on the type of the first argument, create your function accordingly.
7+
Python 3.4 added the ``singledispatch`` decorator to the ``functools``
8+
standard library module. This library extends this functionality to
9+
instance methods (and works for functions too).
10+
11+
To define a generic method , decorate it with the ``@singledispatch``
12+
decorator. Note that the dispatch happens on the type of the first
13+
argument, create your function accordingly.
14+
15+
::
916

1017
>>> from methoddispatch import singledispatch, register, SingleDispatch
1118

@@ -15,7 +22,10 @@ To define a generic method , decorate it with the ``@singledispatch`` decorator.
1522
... print("Let me just say,", end=" ")
1623
... print(arg)
1724

18-
To add overloaded implementations to the function, use the ``register()`` attribute of the generic function. It is a decorator, taking a type parameter and decorating a function implementing the operation for that type
25+
To add overloaded implementations to the function, use the
26+
``register()`` attribute of the generic function. It is a decorator,
27+
taking a type parameter and decorating a function implementing the
28+
operation for that type::
1929

2030
>>> @fun.register(int)
2131
... def _(arg, verbose=False):
@@ -30,15 +40,18 @@ To add overloaded implementations to the function, use the ``register()`` attrib
3040
... for i, elem in enumerate(arg):
3141
... print(i, elem)
3242

33-
To enable registering lambdas and pre-existing functions, the ``register()`` attribute can be used in a functional form::
43+
To enable registering lambdas and pre-existing functions, the
44+
``register()`` attribute can be used in a functional form::
3445

3546
>>> def nothing(arg, verbose=False):
3647
... print("Nothing.")
3748
...
3849
>>> fun.register(type(None), nothing)
3950
<function nothing at 0x03D3FDB0>
4051

41-
The ``register()`` attribute returns the undecorated function which enables decorator stacking, pickling, as well as creating unit tests for each variant independently
52+
The ``register()`` attribute returns the undecorated function which
53+
enables decorator stacking, pickling, as well as creating unit tests for
54+
each variant independently::
4255

4356
>>> from decimal import Decimal
4457
>>> @fun.register(float)
@@ -51,7 +64,8 @@ The ``register()`` attribute returns the undecorated function which enables deco
5164
>>> fun_num is fun
5265
False
5366

54-
When called, the generic function dispatches on the type of the first argument::
67+
When called, the generic function dispatches on the type of the first
68+
argument::
5569

5670
>>> fun("Hello, world.")
5771
Hello, world.
@@ -70,16 +84,22 @@ When called, the generic function dispatches on the type of the first argument::
7084
>>> fun(1.23)
7185
0.615
7286

73-
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 implementation is found.
87+
Where there is no registered implementation for a specific type, its
88+
method resolution order is used to find a more generic implementation.
89+
The original function decorated with ``@singledispatch`` is registered
90+
for the base ``object`` type, which means it is used if no better
91+
implementation is found.
7492

75-
To check which implementation will the generic function choose for a given type, use the ``dispatch()`` attribute::
93+
To check which implementation will the generic function choose for a
94+
given type, use the ``dispatch()`` attribute::
7695

7796
>>> fun.dispatch(float)
7897
<function fun_num at 0x1035a2840>
7998
>>> fun.dispatch(dict) # note: default implementation
8099
<function fun at 0x103fe0000>
81100

82-
To access all registered implementations, use the read-only ``registry`` attribute::
101+
To access all registered implementations, use the read-only ``registry``
102+
attribute::
83103

84104
>>> fun.registry.keys()
85105
dict_keys([<class 'NoneType'>, <class 'int'>, <class 'object'>,
@@ -90,7 +110,8 @@ To access all registered implementations, use the read-only ``registry`` attribu
90110
>>> fun.registry[object]
91111
<function fun at 0x103fe0000>
92112

93-
Decorating class methods requires the class to inherit from ``SingleDispatch``
113+
Decorating class methods requires the class to inherit from
114+
``SingleDispatch``::
94115

95116
>>> class BaseClass(SingleDispatch):
96117
... @singledispatch
@@ -107,8 +128,12 @@ Decorating class methods requires the class to inherit from ``SingleDispatch``
107128
>>> b.foo(1)
108129
'int'
109130

110-
Subclasses can extend the type registry of the function on the base class with their own overrides.
111-
Because we do not want to modify the base class ``foo`` registry the ``methoddispatch.register`` decorator must be used instead of ``foo.register``. The module level ``register`` function takes either the method name or the method itself as the first parameter and the dispatch type as the second.
131+
Subclasses can extend the type registry of the function on the base
132+
class with their own overrides. Because we do not want to modify the
133+
base class ``foo`` registry the ``methoddispatch.register`` decorator
134+
must be used instead of ``foo.register``. The module level ``register``
135+
function takes either the method name or the method itself as the first
136+
parameter and the dispatch type as the second.::
112137

113138
>>> class SubClass(BaseClass):
114139
... @register('foo', float)
@@ -125,13 +150,15 @@ Because we do not want to modify the base class ``foo`` registry the ``methoddis
125150
>>> s.foo(1.0)
126151
'float'
127152

128-
The ``SingleDispatch`` mixin class ensures that each subclass has it's own independant copy of the dispatch registry
153+
The ``SingleDispatch`` mixin class ensures that each subclass has it’s
154+
own independant copy of the dispatch registry::
129155

130156
>>> b = BaseClass()
131157
>>> b.foo(1.0)
132158
'default'
133159

134-
Method overrides do not need to provide the ``register`` decorator again to be used in the dispatch of ``foo``
160+
Method overrides do not need to provide the ``register`` decorator again
161+
to be used in the dispatch of ``foo``::
135162

136163
>>> class SubClass2(BaseClass):
137164
... def foo_int(self, bar):
@@ -141,10 +168,14 @@ Method overrides do not need to provide the ``register`` decorator again to be u
141168
>>> s.foo(1)
142169
'my int'
143170

144-
However, providing the register decorator with the same type will also work.
145-
Decorating a method override with a different type (not a good idea) will register the different type and leave the base-class handler in place for the orginal type.
171+
However, providing the register decorator with the same type will also
172+
work. Decorating a method override with a different type (not a good
173+
idea) will register the different type and leave the base-class handler
174+
in place for the orginal type.
146175

147-
In Python 3.6 and later, for functions annotated with types, the decorator will infer the type of the first argument automatically as shown below
176+
In Python 3.6 and later, for functions annotated with types, the
177+
decorator will infer the type of the first argument automatically as
178+
shown below::
148179

149180
>>> class BaseClassAnno(SingleDispatch):
150181
... @singledispatch
@@ -160,12 +191,19 @@ In Python 3.6 and later, for functions annotated with types, the decorator will
160191
... def foo_float(self, bar: float):
161192
... return 'float'
162193

163-
In Python 3.6 and earlier, the ``SingleDispatch`` class uses a meta-class ``SingleDispatchMeta`` to manage the dispatch registries. However in Python 3.6 and later the ``__init_subclass__`` method is used instead.
164-
If your class also inherits from an ABC interface you can use the ``SingleDispatchABCMeta`` metaclass in Python 3.6 and earlier.
194+
In Python 3.6 and earlier, the ``SingleDispatch`` class uses a
195+
meta-class ``SingleDispatchMeta`` to manage the dispatch registries.
196+
However in Python 3.6 and later the ``__init_subclass__`` method is used
197+
instead. If your class also inherits from an ABC interface you can use
198+
the ``SingleDispatchABCMeta`` metaclass in Python 3.6 and earlier.
165199

166-
Finally, accessing the method ``foo`` via a class will use the dispatch registry for that class
200+
Finally, accessing the method ``foo`` via a class will use the dispatch
201+
registry for that class::
167202

168203
>>> SubClass2.foo(s, 1)
169204
'my int'
170205
>>> BaseClass.foo(s, 1)
171206
'int'
207+
208+
.. |Build Status| image:: https://travis-ci.com/seequent/methoddispatch.svg?branch=master
209+
:target: https://travis-ci.com/seequent/methoddispatch

methoddispatch/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@
185185
from .methoddispatch3 import *
186186
del methoddispatch3
187187

188-
__version__ = '2.0.0'
188+
__version__ = '2.0.1'
189189
__author__ = 'Seequent'
190190
__license__ = 'BSD'
191191
__copyright__ = 'Copyright 2018 Seequent'

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
keywords="single dispatch decorator method",
1515
url="https://github.com/seequent/methoddispatch",
1616
packages=setuptools.find_packages(),
17-
long_description=methoddispatch.__doc__,
17+
long_description=open('README.rst').read(),
1818
classifiers=[
1919
"Programming Language :: Python :: 2.7",
2020
"Programming Language :: Python :: 3.4",

0 commit comments

Comments
 (0)