Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
217 views
in Technique[技术] by (71.8m points)

python - Attribute docstring from parent class isn't shown in inner class using Sphinx

I have a class structured as follow:

class BaseObject(IBaseObject):
    """
    DESCRIPTION 1
    """

    class Setup(TypedDict, total=False):
        """
        DESCRIPTION 1.1
        """
        log_id:IntKEY
        """DESCRIPTION 1.1.1"""
        name:str
        """DESCRIPTION 1.1.2"""

and another class like this:

class VersionInfo(BaseObject):
    """
    DESCRIPTION 2

    """
    class Setup(BaseObject.Setup):
        items_dict:Dict[str,int]
        """DESCRIPTION 2.1.1"""
        hash:int
        """DESCRIPTION 2.1.2"""

When I create the documentation, I would like to see in VersionInfo.Setup the DESCRIPTION 1.1.1 and 1.1.2 used in the BaseObject.Setup's attributes (inherited), but I can only see the list of attributes without the description.

I tried to use :inherited-members: but only the TypedDict functions are added.

EDIT: The class

class IBaseObject():
    @abstractmethod
    def setup(self, params:Optional[TypedDict]) -> None:
        raise NotImplementedError("Should implement setup method")

    @abstractmethod
    def InFields(self, filer:QSFiler) -> bool:
        raise NotImplementedError("Should implement setup method")

is just a simple class with a couple of abstract methods not related to the nested class Setup.

IntKEY is just an int value

IntKEY = int
question from:https://stackoverflow.com/questions/66064479/attribute-docstring-from-parent-class-isnt-shown-in-inner-class-using-sphinx

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

In this solution inheritance from dict and IBaseObject is not shown by using the :exclude-members: option, as to not clutter the result visually. It's easy to fine-tune the working solution to your needs.

image of resulting documentation

Below are the classes grouped into a single code fence (to ease copy-pasting). QSFiler wasn't defined in the question so it's changed to int, but that's the only difference from the code in the question. Let's assume it's a module called inner_class_problem.py, because a module/package name will be necessary for referencing by name.

from abc import abstractmethod
from typing import TypedDict, Optional, Dict

IntKEY = int

class IBaseObject:

    @abstractmethod
    def setup(self, params: Optional[TypedDict]) -> None:
        raise NotImplementedError("Should implement setup method")

    @abstractmethod
    def InFields(self, filer: int) -> bool:
        raise NotImplementedError("Should implement setup method")

class BaseObject(IBaseObject):
    """
    DESCRIPTION 1
    """
    class Setup(TypedDict, total=False):
        """
        DESCRIPTION 1.1
        """
        log_id: IntKEY
        """DESCRIPTION 1.1.1"""
        name: str
        """DESCRIPTION 1.1.2"""

class VersionInfo(BaseObject):
    """
    DESCRIPTION 2

    """
    class Setup(BaseObject.Setup):
        items_dict: Dict[str, int]
        """DESCRIPTION 2.1.1"""
        hash: int
        """DESCRIPTION 2.1.2"""

The corresponding reStructuredText file inner_class_problem.rst

inheritance with inner class
----------------------------

.. automodule:: inner_class_problem
    :members:
    :exclude-members: IBaseObject, BaseObject, VersionInfo

    .. autoclass:: IBaseObject
        :members:

    .. autoclass:: BaseObject
        :members:

    .. autoclass:: VersionInfo
        :members:
        :exclude-members: Setup

        .. autoclass:: inner_class_problem.VersionInfo::Setup
            :members:
            :inherited-members: dict
            :exclude-members: log_id, name

            .. autoattribute:: inner_class_problem.BaseObject::Setup.log_id
                :noindex:

            .. autoattribute:: inner_class_problem.BaseObject::Setup.name
                :noindex:

The problem statement was: the inner class VersionInfo.Setup didn't render the comments that document the inhereted variables BaseObject.Setup.log_id and BaseObjectSetup.name.

In order to circumvent this, you can sucessivly use the :exclude-members: option to isolate VersionInfo.Setup afterwards using the .. autoattribute:: directive to include the inherited variables BaseObject.Setup.name and BaseObject.Setup.log_id straight from the parent class into the child class (:noindex: option was used - see Options and avanced usage- to avoid a duplicate warning being issued by Sphinx).

This is inconvenient but it's probably your best choice. There are some alternatives, like writing the documentation of log_id and name directly in the .rst files with domain declarations.

Generally documentation of members from parent classes isn't repeated in child classes, because it's just a repetition. A class signature that inherits implicitly tells you the inherited members will be documented in the parent class.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...