I have an abstract base class Base
that provides an abstract method _run()
that needs to be implemented by derived classes, as well as a method run()
that will call _run()
and do some extra work that is common to all derived classes.
In all derived classes, I am setting the function docstring for the _run()
method. As this function is not part of the public API, I want the same docstring (and function signature) to instead show up for the run()
method.
Consider the following example:
import inspect
from abc import ABC, abstractmethod
class Base(ABC):
@abstractmethod
def _run(self):
return
def run(self, *args, **kwargs):
"""old_doc"""
return self._run(*args, **kwargs)
class Derived(Base):
def _run(self):
"""new_doc"""
return
My initial idea was to manipulate the docstring in Base.__init__
or Base.__new__
. This works to some extent, but presents a number of problems:
- I want to be able to override these two methods (at the very least
__init__
) in derived classes. - This requires the class to be instantiated before the docstring is available.
- By setting the docstring for
Base.run
when instantiating the derived class, it would in fact set the docstring for all derived classes.
class Base(ABC):
def __init__(self):
type(self).run.__doc__ = type(self)._run.__doc__
type(self).run.__signature__ = inspect.signature(type(self)._run)
...
What I am hoping for:
>>> Derived.run.__doc__
'new_doc'
What I get so far:
>>> Derived.run.__doc__
'old_doc'
>>> Derived().run.__doc__
'new_doc'
Are there any solutions to this?