3

I have a decorator that has a nested definition of the wrapping class. Wrapper maintains as the attribute the original class that it wraps. Toy example looks like this:

def decorator(cls):
    class Wrapper(object):
        original = cls

        def __init__(self):
            self.__doc__ = self.original.__doc__
            self.__name__ = self.original.__name__

        def do_something_with_cls(cls):
            pass

    return Wrapper

Now I want to decorate the Foo class with this decorator in the other module and generate sphinx documentation for the Foo class before it has been decorated. It looks like this:

from .bar import decorator


@decorator
class Foo(object):
    """The docstring I want to preserve."""
    def __init__(self):
        pass

I was trying to achieve this with use of the autoclass functionality but it didn't work out. What i wanted to do was to create a class instance and take its docstring:

.. autoclass:: package.baz.Foo()
   :members:

but it returned this in the html documentation of the package.baz.Foo class: alias of package.bar.decorator.<locals>.Wrapper

I want to achieve that when I am documenting the baz module I am able to generate a documentation of the Foo class before its decoration. Is it possible?

EDIT:

This looks like a similar problem but here what I would like to achieve is to pass to the Wrapper instance the docstring that Sphinx will see and generate a documentation basing on the original Foo docstring or I will be able to call a Wrapper.original and make a documentation of this, but the following didn't work out:

.. autoclass package.baz.Foo.original
   :members:
emerte
  • 58
  • 5
  • Use [**`wraps`**](https://docs.python.org/3/library/functools.html#functools.wraps) – Peter Wood Apr 11 '19 at 18:29
  • Possible duplicate of [Python functools.wraps equivalent for classes](https://stackoverflow.com/questions/6394511/python-functools-wraps-equivalent-for-classes) – Peter Wood Apr 11 '19 at 18:33
  • Both solutions will not work out because: 1. wraps are not compatible for the class passed as the parameter 2. I am here decorating the whole class with the function that defines the Wrapper class inside. In the attached problem there is the class that decorates the function. Or maybe I am missing something? – emerte Apr 11 '19 at 18:37

1 Answers1

3

If @wraps is not working you can update __doc__ manually.

Do something like:

def decorator(cls):
    class Wrapper(object):
        original = cls

        def __init__(self):
            self.__doc__ = self.original.__doc__
            self.__name__ = self.original.__name__

        def do_something_with_cls(cls):
            pass

    Wrapper.__doc__ = cls.__doc__
    return Wrapper


@decorator
class Foo(object):
    """The docstring I want to preserve."""
    def __init__(self):
        pass


print(Foo.__doc__)

'The docstring I want to preserve.'

Rajan
  • 1,463
  • 12
  • 26
  • You are my hero! I don't know why I didn't figure out that I need to specify this outside of the class definition and did the same but in the __init__ phase... Thank you very much, works perfectly! – emerte Apr 11 '19 at 18:58