diff --git a/Lib/functools.py b/Lib/functools.py index 4d5e2709007843..0d926817bac67f 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -933,6 +933,7 @@ def __init__(self, func): self.dispatcher = singledispatch(func) self.func = func + self.attrname = None def register(self, cls, method=None): """generic_method.register(cls, func) -> func @@ -941,6 +942,9 @@ def register(self, cls, method=None): """ return self.dispatcher.register(cls, func=method) + def __set_name__(self, _, name): + self.attrname = name + def __get__(self, obj, cls=None): def _method(*args, **kwargs): method = self.dispatcher.dispatch(args[0].__class__) @@ -949,6 +953,15 @@ def _method(*args, **kwargs): _method.__isabstractmethod__ = self.__isabstractmethod__ _method.register = self.register update_wrapper(_method, self.func) + + if self.attrname is not None: + attrname = self.attrname + + try: + obj.__dict__[attrname] = _method + except AttributeError: + pass # not all objects have __dict__ (e.g. class defines slots) + return _method @property diff --git a/Misc/NEWS.d/next/Library/2020-11-10-07-04-15.bpo-40988.5kBC-O.rst b/Misc/NEWS.d/next/Library/2020-11-10-07-04-15.bpo-40988.5kBC-O.rst new file mode 100644 index 00000000000000..013bb509e7aca0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-11-10-07-04-15.bpo-40988.5kBC-O.rst @@ -0,0 +1,2 @@ +Applied a cached_propery type optimization suggested by federico to +singledispatchmethod yielding approximately a 3.5 speedup in access times.