You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/dispatch.rst
+33-35Lines changed: 33 additions & 35 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -62,34 +62,25 @@ Ideally, every project will instanciate Dispatch only once, in a module such as
62
62
Basic Use
63
63
---------
64
64
65
-
First, users must instanciate the `Dispatch` class, to create a dispatch group:
65
+
Multidispatch groups functions by their name. Functions of different names will never collide with each other.
66
66
67
-
::
68
-
69
-
from runtype import Dispatch
70
-
dp = Dispatch()
71
-
72
-
Then, the group can be used as a decorator for any number of functions.
73
-
74
-
Dispatch maintains the original name of every function. So, functions of different names will never collide with each other.
75
-
76
-
The order in which you define functions doesn't matter.
67
+
The order in which you define functions doesn't matter to runtype, but it's recommended to order functions from most specific to least specific.
77
68
78
69
Example:
79
70
::
80
71
81
-
dp = Dispatch()
72
+
from runtype import multidispatch as md
82
73
83
74
@dataclass(frozen=False)
84
75
class Point:
85
76
x: int = 0
86
77
y: int = 0
87
78
88
-
@dp
79
+
@md
89
80
def __init__(self, points: list | tuple):
90
81
self.x, self.y = points
91
82
92
-
@dp
83
+
@md
93
84
def __init__(self, points: dict):
94
85
self.x = points['x']
95
86
self.y = points['y']
@@ -102,6 +93,19 @@ Example:
102
93
assert p0 == Point({"x": 0, "y": 0}) # User constructor
103
94
104
95
96
+
A different dispatch object is created for each module, so collisions between different modules are impossible.
97
+
98
+
Users who want to define a dispatch across several modules, or to have more granular control, can use the Dispatch class:
99
+
100
+
::
101
+
102
+
from runtype import Dispatch
103
+
dp = Dispatch()
104
+
105
+
Then, the group can be used as a decorator for any number of functions, in any module.
106
+
107
+
Functions will still be grouped by name.
108
+
105
109
106
110
Specificity
107
111
-----------
@@ -117,11 +121,11 @@ Example:
117
121
118
122
from typing import Union
119
123
120
-
@dp
124
+
@md
121
125
def f(a: int, b: int):
122
126
return a + b
123
127
124
-
@dp
128
+
@md
125
129
def f(a: Union[int, str], b: int):
126
130
return (a, b)
127
131
@@ -147,9 +151,9 @@ Ambiguity can result from two situations:
147
151
Example:
148
152
::
149
153
150
-
>>> @dp
154
+
>>> @md
151
155
... def f(a, b: int): pass
152
-
>>> @dp
156
+
>>> @md
153
157
... def f(a: int, b): pass
154
158
>>> f(1, 1)
155
159
Traceback (most recent call last):
@@ -161,14 +165,11 @@ Dispatch is designed to always throw an error when the right choice isn't obviou
161
165
Another example:
162
166
::
163
167
164
-
from runtype import Dispatch
165
-
dp = Dispatch()
166
-
167
-
@dp
168
+
@md
168
169
def join(seq, sep: str = ''):
169
170
return sep.join(str(s) for s in seq)
170
171
171
-
@dp
172
+
@md
172
173
def join(seq, sep: list):
173
174
return join(join(sep, str(s)) for s in seq)
174
175
...
@@ -191,39 +192,36 @@ Another example:
191
192
192
193
Dispatch chooses the right function based on the idea specificity, which means that `class MyStr(str)` is more specific than `str`, and so on: `MyStr(str) < str < Union[int, str] < object`.
193
194
194
-
MyPy support (@overload)
195
+
MyPy support
195
196
------------------------
196
197
197
-
Dispatch can be made to work with the overload decorator, aiding in granular type resolution.
198
+
multidispatch works with mypy by employing the typing.overload decorator, aiding in granular type resolution.
198
199
199
200
However, due to the limited design of the overload decorator, there are several rules that need to be followed, and limitations that should be considered.
200
201
201
-
1. The overload decorator must be placed above the dispatch decorator.
202
+
1. For MyPy's benefit, more specific functions should be placed above less specific functions.
202
203
203
-
1. The last dispatched function of each function group, must be written without type declarations, and without the overload decorator. It is recommended to use this function for error handling.
204
+
2. The last dispatched function of each function group, must be written without type declarations (making it the least specific), and use the multidispatch_final decorator. It is recommended to use this function for error handling and default functionality.
204
205
205
-
3. Mypy doesn't support all of the functionality of Runtype's dispatch, such as full specificity resolution. Therefore, some valid dispatch constructs will produce an error in mypy.
206
+
Note: Mypy doesn't support all of the functionality of Runtype's dispatch, such as full specificity resolution. Therefore, some valid dispatch constructs will produce an error in mypy.
206
207
207
208
208
209
Example usage:
209
210
210
211
::
211
212
212
-
from runtype import Dispatch
213
+
from runtype import multidispatch as md, multidispatch_final as md_final
0 commit comments