Sphinx: [napoleon] Clarify whether there is actual support for type annotations

Created on 2 Jul 2016  Â·  8Comments  Â·  Source: sphinx-doc/sphinx

I may be a victim of circumstances here, but I was left a bit confused.

  1. I found http://sphinxcontrib-napoleon.readthedocs.io/ before realizing per the note at the top that Napoleon is now distributed with Sphinx.
  2. The documentation on Read the Docs has a section about PEP 484 type annotations. I saw that, and the example for Python 2/3 compatible comment annotations where types are left out of the Google-style docstring is exactly what I was hoping I could do.
  3. Using sphinx.ext.napoleon, there is no type information reflected in generated documentation if I use that style. I wasn't sure whether this just isn't actually supported, because the doc isn't really explicit about that, but I initially took it as implied.
  4. I realized the extension has documentation on sphinx-doc.org as well. It doesn't include the section on type annotations at all.
  5. I was left wondering whether new changes to Napoleon land on sphinx-contrib first (which I rooted around to find on Bitbucket) and whether there might be newer features that I'm missing when using built-in sphinx.ext.napoleon. This may be true (?), but checking in the changelog I didn't see anything regarding type annotation support anyway.

So, a couple of things I'm left feeling:

  • It would be nice if the Napoleon documentation explicitly states whether or not type annotations are actually considered/used when generating documentation. The example implies that they _might_ be.
  • Maybe more of general Sphinx project ecosystem matters than Napoleon-specific, but it would be nice if there was some obvious clarification of:

    • why some extension documentation exists on both Read the Docs and http://www.sphinx-doc.org/

    • why they differ

    • which of them users should consider canonical/authoritative/bleeding-edge

    • if there is some relation to installing a PyPI module to have versions that evolve ahead of the next Sphinx release

    • why sphinx-contrib lives only on Bitbucket

Maybe this exists somewhere but it wasn't along my circumstantial path above.

extensions

Most helpful comment

@RobRuana Thanks for your explanation regarding output of docs with and without type annotations.

I was wondering if there is a way to get the param1 (int): The first parameter types of annotations even if you are using Python 3.5+ typehints? The nice thing about this output is that int can actually be a link to the package where int is defined, using intersphinx (this is nice for more complicated types like numpy arrays, etc). However, this does not seem to work with typehints?

All 8 comments

  • The documentation on http://sphinxcontrib-napoleon.readthedocs.io/ applies to sphinxcontrib-napoleon
  • The documentation on http://www.sphinx-doc.org/ applies to sphinx.ext.napoleon
  • As the documentation implies, sphinxcontrib-napoleon exists mainly to support users who are still using an older version of Sphinx (< 1.3)
  • In addition sphinxcontrib-napoleon does not depend on sphinx – I know of at least one project using it as an independent library
  • sphinxcontrib-napoleon and sphinx.ext.napoleon are kept in sync, but sphinxcontrib-napoleon has a faster release cycle (I roll a point release after pretty much every bug fix)
  • Where they differ it's because sphinxcontrib-napoleon was released sooner. For example, the napoleon PEP 484 docs haven't landed in http://www.sphinx-doc.org/ because Sphinx 1.5 hasn't been released yet.
  • The sphinx-contrib repo exists mostly for historical reasons – the extensions in sphinx-contrib are not officially maintained by the sphinx team
  • sphinx-contrib lives on Bitbucket mostly because there hasn't been a strong enough reason to migrate somewhere else

Regarding PEP 484

The Napoleon examples of functions with and without PEP 484 annotations:

def function_with_pep484_type_annotations(param1: int, param2: str) -> bool:
    """Example function with PEP 484 type annotations.

    Args:
        param1: The first parameter.
        param2: The second parameter.

    Returns:
        The return value. True for success, False otherwise.

    """

def function_with_types_in_docstring(param1, param2):
    """Example function with types documented in the docstring.

    `PEP 484`_ type annotations are supported. If attribute, parameter, and
    return types are annotated according to `PEP 484`_, they do not need to be
    included in the docstring:

    Args:
        param1 (int): The first parameter.
        param2 (str): The second parameter.

    Returns:
        bool: The return value. True for success, False otherwise.

    .. _PEP 484:
        https://www.python.org/dev/peps/pep-0484/

    """

Will render like this:
screenshot

So you can see there are some slight differences. Using PEP 484 annotations, the types will be rendered inline with the function declaration. I have a feeling this will become the de facto standard as more people become comfortable writing type annotations.

Thanks so much for the detailed answer! It'd be great if some of this can make its way to… somewhere more visible. 😃 (Also it's interesting to know about the possibility of use without Sphinx).

The one case you didn't cover regarding PEP 484 is the comment syntax for Python 2-compatible code, this example from the docs:

def func(arg1, arg2):
    # type: (int, str) -> bool
    """Summary line.

    Extended description of function.

    Args:
        arg1: Description of arg1
        arg2: Description of arg2

    Returns:
        Description of return value

    """
    return True

That's my current interest so that's why I wasn't seeing anything.

I suppose it'd be a matter of Sphinx itself (or autodoc) having support for this form of type information so that Napoleon could use it too—I'm not sure if there is any support for this, I'll search around for info or related tickets.

I'll add a line explaining that the Python 2-compatible annotations aren't supported. For some reason, I thought those worked :(

@RobRuana Thanks for your explanation regarding output of docs with and without type annotations.

I was wondering if there is a way to get the param1 (int): The first parameter types of annotations even if you are using Python 3.5+ typehints? The nice thing about this output is that int can actually be a link to the package where int is defined, using intersphinx (this is nice for more complicated types like numpy arrays, etc). However, this does not seem to work with typehints?

The above described functionality would be really great!

Agreed. In particular the combination with intersphinx does not work with this behavior.
Furthermore, I think a consistent rendering of both examples is desirable.

For introspection purposes, function type annotations should be the preferred approach

Agree with @ostrokach 's suggestion to note types in the parameter definitions. This presents the relevant information in a more contextually appropriate location - easier for readers to digest.

It would further be good to have an option to remove the parameter types from the function signatures (in the documents). The typing information clutters the signatures, quickly becoming a readability issue for complex functions or parameters consisting of multiple or nested types.

This extension is worth trying:
https://github.com/agronholm/sphinx-autodoc-typehints

It moves type hints from function signatures to the parameter description. I'm using it with sphinx.ext.napoleon and sphinx.ext.intersphinx and so far it works.

Was this page helpful?
0 / 5 - 0 ratings