autoclass does not work for concrete aliases of a generic type
#7,450 opened on 2020年4月9日
Repository metrics
- Stars
- (5,625 stars)
- PR merge metrics
- (平均マージ 10d 11h) (30d で 11 merged PRs)
説明
Describe the bug
autoclass does not output class documentation for concrete aliases of a generic type; instead, it just outputs "module.Class".
To Reproduce
(Two possible workarounds included below.)
conf.py:
import sys, os
sys.path.insert(0, os.path.abspath('.'))
extensions = ['sphinx.ext.autodoc']
mymodule.py:
from typing import Generic, TypeVar
class SimpleThing:
"""A normal class."""
def __init__(self, attr: int):
#: help
self.attr: int = attr
T = TypeVar('T', int, float, complex)
class _GenericThing(Generic[T]):
"""A generic, preferably private."""
def __init__(self, attr: T):
#: help
self.attr: T = attr
ConcreteThing = _GenericThing[float]
"""A concrete thing."""
_PrivateThing = _GenericThing[complex]
"""A private concrete thing."""
DocHackThing = _GenericThing[float]
# __doc__ and #:/""" comments comments don't work with autoclass otherwise.
DocHackThing.__name__ = 'DocHackThing'
# Kills warnings; we still lose the signature in the output.
# If we use GenericThing.__mro__, we get the signature of typing._GenericAlias.
# Setting __signature__ = inspect.signature(GenericThing) doesn't work either.
DocHackThing.__mro__ = object.__mro__
# This works for Sphinx, but help(DocHackThing) remains broken.
DocHackThing.__doc__ = """
Another concrete thing.
.. attribute:: attr
:type: float
:value: None
help
"""
index.rst:
.. module:: mymodule
.. autoclass:: SimpleThing
:members:
.. autoclass:: _GenericThing
:members:
autoclass doesn't work for concrete types:
.. autoclass:: ConcreteThing
:members:
Using autodata gets the point across, but it forces us to expose
:class:`_GenericThing` for things to make sense to the user:
.. autodata:: ConcreteThing
It would be nice if autoclass for concrete types would look like this:
.. We still have to add the signature by hand.
.. autoclass:: DocHackThing(attr: float)
:members:
index.txt, as generated by sphinx-build -M text . _build:
class mymodule.SimpleThing(attr: int)
A normal class.
attr: int = None
help
class mymodule._GenericThing(attr: T)
A generic, preferably private.
attr: T = None
help
autoclass doesn't work for concrete types:
mymodule.ConcreteThing
A concrete thing.
alias of "mymodule.DocHackThing"
Using autodata gets the point across, but it forces us to expose
"_GenericThing" for things to make sense to the user:
mymodule.ConcreteThing = mymodule._GenericThing[float]
A concrete thing.
It would be nice if autoclass for concrete types would look like this:
class mymodule.DocHackThing(attr: float)
Another concrete thing.
attr: float = None
help
Expected behavior
The autoclass output for the alias of a concrete type should be similar to that of a type that isn't using generics at all (docs for ConcreteThing should look like those for SimpleThing).
It's arguable this should happen all the time:
If the generic class is part of the public API, autoclass for the generic type and autodata for the concrete alias is probably the correct thing to do.
However, if the generic type is just an implementation detail, it would be nice to be able to pretend the concrete alias is a normal class, and not force the user think about typing stuff.
Your project
Full minimal repro included above.
This is the problem in real life: https://github.com/lemon24/reader/blob/05926a6cb7b62d7186f68502ea905f6bdc067b0b/src/reader/core/types.py#L78-L238
Screenshots
N/A.
Environment info
- OS: macOS Catalina 10.15.2
- Python version: 3.7.6
- Sphinx version: 2.4.4
- Sphinx extensions: sphinx.ext.autodoc
- Extra tools: N/A
Additional context
N/A.