0
# Core Dispatch Functionality
1
2
Essential dispatching features that form the foundation of multiple dispatch in Python. This includes the main dispatch decorator, programmatic dispatch management through the Dispatcher class, and comprehensive type system support.
3
4
## Capabilities
5
6
### Function Dispatch Decorator
7
8
The primary interface for creating dispatched functions using the `@dispatch` decorator with automatic type resolution and inheritance support.
9
10
```python { .api }
11
def dispatch(*types, **kwargs):
12
"""
13
Decorator for creating dispatched functions based on argument types.
14
15
Parameters:
16
- *types: Type signatures for dispatch (e.g., int, str, (int, float))
17
- namespace: dict (optional) - Custom namespace for dispatch isolation
18
19
Returns:
20
Decorator function that registers implementations
21
22
Raises:
23
TypeError: If types are invalid
24
"""
25
```
26
27
**Usage Examples:**
28
29
```python
30
# Basic type dispatch
31
@dispatch(int, int)
32
def add(x, y):
33
return x + y
34
35
@dispatch(str, str)
36
def add(x, y):
37
return x + y
38
39
# Union types (multiple acceptable types)
40
@dispatch((int, float), (int, float))
41
def multiply(x, y):
42
return x * y
43
44
# Custom namespace
45
my_namespace = {}
46
47
@dispatch(int, namespace=my_namespace)
48
def process(x):
49
return x * 2
50
```
51
52
### Dispatcher Class
53
54
Programmatic dispatch management for advanced use cases where decorators are insufficient or dynamic dispatch registration is needed.
55
56
```python { .api }
57
class Dispatcher:
58
"""
59
Manages multiple implementations of a function with type-based dispatch.
60
"""
61
62
def __init__(self, name, doc=None):
63
"""
64
Initialize a new dispatcher.
65
66
Parameters:
67
- name: str - Name of the dispatched function
68
- doc: str (optional) - Documentation string for the dispatcher
69
"""
70
71
def register(self, *types, **kwargs):
72
"""
73
Register a new implementation for the given type signature.
74
75
Parameters:
76
- *types: Type signature (e.g., int, str, (int, float))
77
- **kwargs: Additional registration options
78
79
Returns:
80
Decorator function for the implementation
81
"""
82
83
def add(self, signature, func):
84
"""
85
Add new types/method pair to dispatcher.
86
87
Parameters:
88
- signature: tuple - Type signature
89
- func: callable - Implementation function
90
"""
91
92
def dispatch(self, *types):
93
"""
94
Determine appropriate implementation for this type signature.
95
96
This method is internal. Users should call this object as a function.
97
Implementation resolution occurs within the __call__ method.
98
99
Parameters:
100
- *types: Types to dispatch on
101
102
Returns:
103
callable: Best matching implementation
104
105
Raises:
106
MDNotImplementedError: If no suitable implementation found
107
"""
108
109
def resolve(self, types):
110
"""
111
Determine appropriate implementation for this type signature (DEPRECATED).
112
113
.. deprecated:: 0.4.4
114
Use dispatch(*types) instead
115
116
Parameters:
117
- types: tuple - Type signature
118
119
Returns:
120
callable: Best matching implementation
121
"""
122
123
def __call__(self, *args, **kwargs):
124
"""
125
Execute dispatch based on argument types.
126
127
Parameters:
128
- *args: Arguments to dispatch on
129
- **kwargs: Keyword arguments passed to implementation
130
131
Returns:
132
Result of dispatched function
133
"""
134
```
135
136
**Usage Examples:**
137
138
```python
139
# Create dispatcher programmatically
140
math_ops = Dispatcher('math_ops')
141
142
@math_ops.register(int, int)
143
def math_ops_impl(x, y):
144
return x + y
145
146
@math_ops.register(str, str)
147
def math_ops_impl(x, y):
148
return x + y
149
150
result = math_ops(1, 2) # -> 3
151
result = math_ops("a", "b") # -> "ab"
152
153
# Direct registration
154
def float_add(x, y):
155
return float(x + y)
156
157
math_ops.add((float, float), float_add)
158
```
159
160
### Method Dispatch
161
162
Specialized dispatcher for instance methods that automatically handles `self` parameter and integrates with Python's descriptor protocol.
163
164
```python { .api }
165
class MethodDispatcher(Dispatcher):
166
"""
167
Dispatcher specialized for instance methods.
168
Inherits from Dispatcher with method-specific behavior.
169
"""
170
171
def __get__(self, instance, owner):
172
"""
173
Descriptor protocol implementation for method binding.
174
175
Parameters:
176
- instance: Object instance (or None for class access)
177
- owner: Owner class
178
179
Returns:
180
Bound method dispatcher
181
"""
182
```
183
184
**Usage Examples:**
185
186
```python
187
class Calculator:
188
add = MethodDispatcher('add')
189
190
@add.register(object, int, int)
191
def add_impl(self, x, y):
192
return x + y
193
194
@add.register(object, str, str)
195
def add_impl(self, x, y):
196
return x + y
197
198
calc = Calculator()
199
result = calc.add(1, 2) # -> 3
200
result = calc.add("a", "b") # -> "ab"
201
```
202
203
### Type System Support
204
205
Comprehensive support for Python's type system including inheritance, abstract base classes, and custom type checking.
206
207
```python { .api }
208
def ismethod(func):
209
"""
210
Determine if function is a method during class definition.
211
212
Parameters:
213
- func: callable - Function to check
214
215
Returns:
216
bool: True if func is a method
217
"""
218
```
219
220
**Supported Type Features:**
221
222
- **Basic Types**: `int`, `float`, `str`, `list`, `dict`, etc.
223
- **User Classes**: Full inheritance support with method resolution order
224
- **Union Types**: `(int, float)` for accepting multiple types
225
- **Abstract Classes**: `collections.abc.Iterator`, `numbers.Number`, etc.
226
- **Type Strings**: `'MyClass'` for forward references during class definition
227
228
**Examples:**
229
230
```python
231
from collections.abc import Iterator
232
from numbers import Number
233
234
@dispatch(Iterator)
235
def process_iterable(items):
236
return list(items)
237
238
@dispatch(Number, Number)
239
def calculate(x, y):
240
return x * y
241
242
# Works with inheritance
243
class Animal:
244
pass
245
246
class Dog(Animal):
247
pass
248
249
@dispatch(Animal)
250
def speak(animal):
251
return "Generic animal sound"
252
253
@dispatch(Dog) # More specific, takes precedence
254
def speak(dog):
255
return "Woof!"
256
257
dog = Dog()
258
speak(dog) # -> "Woof!" (uses more specific implementation)
259
```
260
261
### Error Handling
262
263
Structured error handling for dispatch failures and type resolution issues.
264
265
```python { .api }
266
class MDNotImplementedError(NotImplementedError):
267
"""
268
Exception raised when no suitable implementation is found for given types.
269
Subclass of NotImplementedError with dispatch-specific context.
270
"""
271
```
272
273
**Example:**
274
275
```python
276
@dispatch(int)
277
def process(x):
278
return x * 2
279
280
try:
281
result = process("string") # No str implementation
282
except MDNotImplementedError as e:
283
print(f"No implementation found: {e}")
284
```