Created
April 25, 2018 03:35
-
-
Save ethanhs/3306e8767eda080efefdeb0f3a7a91dc to your computer and use it in GitHub Desktop.
`functools.singledispatchmethod` for use before 3.8
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
from functools import singledispatch, update_wrapper | |
class singledispatchmethod: | |
"""Single-dispatch generic method descriptor. | |
Supports wrapping existing descriptors and handles non-descriptor | |
callables as instance methods. | |
""" | |
def __init__(self, func): | |
if not callable(func) and not hasattr(func, "__get__"): | |
raise TypeError(f"{func!r} is not callable or a descriptor") | |
self.dispatcher = singledispatch(func) | |
self.func = func | |
def register(self, cls, method=None): | |
"""generic_method.register(cls, func) -> func | |
Registers a new implementation for the given *cls* on a *generic_method*. | |
""" | |
return self.dispatcher.register(cls, func=method) | |
def __get__(self, obj, cls): | |
def _method(*args, **kwargs): | |
method = self.dispatcher.dispatch(args[0].__class__) | |
return method.__get__(obj, cls)(*args, **kwargs) | |
_method.__isabstractmethod__ = self.__isabstractmethod__ | |
_method.register = self.register | |
update_wrapper(_method, self.func) | |
return _method | |
@property | |
def __isabstractmethod__(self): | |
return getattr(self.func, '__isabstractmethod__', False) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment