mirror of
https://github.com/python/cpython.git
synced 2025-10-09 16:34:44 +00:00
bpo-32380: Create functools.singledispatchmethod (#6306)
This commit is contained in:
parent
09c4a7dee2
commit
c651275afe
5 changed files with 205 additions and 1 deletions
|
@ -11,7 +11,7 @@
|
|||
|
||||
__all__ = ['update_wrapper', 'wraps', 'WRAPPER_ASSIGNMENTS', 'WRAPPER_UPDATES',
|
||||
'total_ordering', 'cmp_to_key', 'lru_cache', 'reduce', 'partial',
|
||||
'partialmethod', 'singledispatch']
|
||||
'partialmethod', 'singledispatch', 'singledispatchmethod']
|
||||
|
||||
try:
|
||||
from _functools import reduce
|
||||
|
@ -826,3 +826,40 @@ def singledispatch(func):
|
|||
wrapper._clear_cache = dispatch_cache.clear
|
||||
update_wrapper(wrapper, func)
|
||||
return wrapper
|
||||
|
||||
|
||||
# Descriptor version
|
||||
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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue