Multiple dispatch implementation for Python that enables function dispatching based on types of all non-keyword arguments
npx @tessl/cli install tessl/pypi-multipledispatch@1.0.0Multiple dispatch implementation for Python that enables function dispatching based on the types of all non-keyword arguments. Unlike Python's built-in single dispatch, this library dispatches on all arguments, supporting inheritance, instance methods, union types, variadic signatures, and comprehensive conflict resolution.
pip install multipledispatchfrom multipledispatch import dispatch, DispatcherFor advanced usage:
from multipledispatch import (
dispatch, Dispatcher,
MDNotImplementedError,
halt_ordering, restart_ordering
)For conflict analysis and utilities:
from multipledispatch.conflict import (
supercedes, ambiguous, ambiguities,
AmbiguityWarning
)
from multipledispatch.utils import typename, str_signature
from multipledispatch.variadic import Variadic, isvariadicfrom multipledispatch import dispatch
# Basic function dispatch
@dispatch(int, int)
def add(x, y):
return x + y
@dispatch(float, float)
def add(x, y):
return x + y
@dispatch(str, str)
def add(x, y):
return x + y
# Usage
print(add(1, 2)) # Uses int, int implementation -> 3
print(add(1.0, 2.0)) # Uses float, float implementation -> 3.0
print(add("a", "b")) # Uses str, str implementation -> "ab"
# Class method dispatch
class Vector:
def __init__(self, data):
self.data = data
@dispatch('Vector', 'Vector')
def __add__(self, other):
return Vector([a + b for a, b in zip(self.data, other.data)])
@dispatch('Vector', (int, float))
def __add__(self, scalar):
return Vector([x + scalar for x in self.data])
v1 = Vector([1, 2, 3])
v2 = Vector([4, 5, 6])
result = v1 + v2 # Vector addition
scaled = v1 + 2 # Scalar additionThe dispatch system is built on three core components:
The library performs static analysis to detect conflicts at registration time rather than runtime, ensuring predictable behavior and optimal performance through caching.
Essential dispatching features including the main dispatch decorator, Dispatcher class for programmatic dispatch management, and comprehensive type system support with inheritance, unions, and method dispatch.
def dispatch(*types, **kwargs):
"""
Decorator for creating dispatched functions.
Parameters:
- *types: Type signatures for dispatch
- namespace: dict (optional) - Custom namespace for dispatch isolation
Returns:
Decorator function that registers implementations
"""
class Dispatcher:
"""
Dispatcher for managing multiple implementations of a function.
"""
def __init__(self, name, doc=None):
"""
Initialize dispatcher.
Parameters:
- name: str - Name of the dispatched function
- doc: str (optional) - Documentation string
"""
def register(self, *types, **kwargs):
"""
Register new implementation for given types.
Parameters:
- *types: Type signature
- **kwargs: Additional options
Returns:
Decorator function
"""Advanced dispatching capabilities including conflict resolution, variadic dispatch, custom namespaces, error handling, and signature analysis tools for complex dispatch scenarios.
class Variadic:
"""
Type for variadic argument signatures.
Usage: Variadic[int] for variable number of int arguments
"""
def isvariadic(obj):
"""
Check if type represents variadic signature.
Parameters:
- obj: Type to check
Returns:
bool: True if type is variadic
"""
class MDNotImplementedError(NotImplementedError):
"""
Exception raised when no suitable dispatch implementation is found.
"""# Type aliases for dispatch signatures
TypeSignature = tuple # Tuple of types for dispatch
NamespaceDict = dict # Namespace dictionary for dispatch isolation
# Union type specification (tuple of types)
UnionType = tuple # e.g., (int, float) for int OR float
# Variadic type specification
VariadicType = type # Created via Variadic[type] or Variadic[(type1, type2)]