readthedocs / readthedocs/sphinx-autoapi

Duplicated annotations in class and __init__() with autodoc typehints

Open
#461 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
494
Forks
147
Avg merge
9m
Merged PRs (30d)
1

Description

Hi. I found that when using autodoc typehints, the "Parameters" field from __init__() is duplicated in the class but without the descriptions. The return type is omitted in the class, but not in __init__(). For example,

class TestClass():
    """Class docstring"""

    def __init__(self, array: list[int]) -> None:
        """Constructor docstring

        :param array: Description of 'array'
        """

gives

autoapi_class_bad

Is this expected behavior?

I want just one set of annotations, either in the class or __init__(), depending on autoapi_python_class_content, i.e.:

"class"
autoapi_class_good

"init":
autoapi_init_good

"both":
autoapi_both

I was able to achieve this by (crudely) patching _record_typehints() in _mapper.py:

def _record_typehints(self, obj):
    if (
        isinstance(obj, (PythonClass, PythonFunction, PythonMethod))
        and not obj.overloads
    ) or isinstance(obj, PythonProperty):
        obj_annotations = {}

+        # remove "Return type" field from __init__() doc
-        include_return_annotation = True
+        include_return_annotation = not (isinstance(obj, PythonMethod) and obj.short_name == "__init__") 
        obj_data = obj.obj
        if isinstance(obj, PythonClass):
            constructor = obj.constructor
            if constructor:
+                # remove "Parameters" field from class doc if autoapi_python_class_content=="class"
+                if obj._class_content == "class":
+                    return
                include_return_annotation = False
                obj_data = constructor.obj
            else:
                return

        for _, name, annotation, _ in obj_data["args"]:
            if name and annotation:
                obj_annotations[name] = annotation

        return_annotation = obj_data["return_annotation"]
        if include_return_annotation and return_annotation:
            obj_annotations["return"] = return_annotation

        self.app.env.autoapi_annotations[obj.id] = obj_annotations

Thanks.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in _mapper.py at _record_typehints() and reproduce the shown class with autodoc typehints and each autoapi_python_class_content setting. Trace how class and init() annotations are recorded, then verify that the selected setting produces one appropriate Parameters section and the expected return type without duplicated annotations.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
documentation
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.