-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Tweak dynamic dispatch and handle variadic and, or etc...
- Loading branch information
Showing
3 changed files
with
43 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,38 @@ | ||
import types | ||
|
||
|
||
class DispatchRegistry: | ||
"""Dispatch a function based on the class of the argument. | ||
This class allows to register a function to execute for a specific class | ||
and expose this as a method of an object which will be dispatched | ||
based on the argument. | ||
It is similar to functools.singledispatch but it allows more | ||
customization in case the dispatch rules grow in complexity | ||
and works for class methods as well | ||
(singledispatch supports methods only in more recent versions) | ||
""" | ||
|
||
def __init__(self): | ||
self._registry = {} | ||
|
||
def register(self, cls): | ||
def decorator(func): | ||
self._registry[cls] = func | ||
return func | ||
|
||
return decorator | ||
|
||
def __getitem__(self, cls): | ||
|
||
def bind(self, obj): | ||
return types.MethodType(self, obj) | ||
|
||
def __getitem__(self, argument): | ||
for dispatch_cls, func in self._registry.items(): | ||
if issubclass(cls, dispatch_cls): | ||
if isinstance(argument, dispatch_cls): | ||
return func | ||
else: | ||
raise ValueError(f"Unsupported SQL Node type: {cls}") | ||
raise ValueError(f"Unsupported SQL Node type: {cls}") | ||
|
||
def __call__(self, obj, dispatch_argument, *args, **kwargs): | ||
return self[dispatch_argument](obj, dispatch_argument, *args, **kwargs) |