-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
autodoc
-documented type aliases can't be referenced from type annotations
#10785
Comments
I was looking for a Python 3.9 workaround (not using
autodoc is wrong here to begin with, a module level type alias (at least up until Python 3.9 without A type alias (not using .. data:: pathlike
:type: str | pathlib.Path So to get the hyperlink to resolve I changed the declaration to: .. class:: pathlike The important part is giving Sphinx the autodoc_type_aliases = {
'pathlike ': 'module.pathlike ', # works
} However, the workaround leaves you with a problem: in the documentation the type alias now appears as a class. So to have it display with the proper type (as a stop gap measure) you would have to:
.. class:: pathlike
.. data:: pathlike
:type: str | pathlib.Path
:noindex: This does get the documentation with hyperlinks and cross-references working as intended. But it requires manually writing reST for each type alias declaration. From the end user's perspective the API shows correctly (the only telltale sign would the type in the index, but that could also be manually overridden.) |
In my case, I have a type annotation to an alias called class Region:
"""
Parsers should yield instances of this class for each example they
discover in a documentation source file.
:param start:
The character position at which the example starts in the
:class:`~sybil.document.Document`.
:param end:
The character position at which the example ends in the
:class:`~sybil.document.Document`.
:param parsed:
The parsed version of the example.
:param evaluator:
The callable to use to evaluate this example and check if it is
as it should be.
"""
def __init__(self, start: int, end: int, parsed: Any, evaluator: Evaluator):
#: The start of this region within the document's :attr:`~sybil.Document.text`.
self.start: int = start
#: The end of this region within the document's :attr:`~sybil.Document.text`.
self.end: int = end
#: The parsed version of this region. This only needs to have meaning to
#: the :attr:`evaluator`.
self.parsed: Any = parsed
#: The :any:`Evaluator` for this region.
self.evaluator: Evaluator = evaluator This is defined in #: The signature for an evaluator. See :ref:`developing-parsers`.
Evaluator = Callable[['sybil.Example'], Optional[str]] This is documented in a .. autoclass:: sybil.typing.Evaluator Now, for the class sybil.Region(start: int, end: int, parsed: Any, evaluator: Callable[[sybil.Example], Optional[str]]) However, for the attribute, I get: evaluator: Evaluator Note the lack of linking in Evaluator. I get the following warning:
I can find no way to fix this, I tried:
Since I have nitpicky on and treating warnings as thing to cause a doc build to fail, the only workaround I can find is to put this in my
So, three problems:
If I've missed any information that would be useful in making progress on this, please let me know! |
Sphinx normally makes type names in annotations links to the documentation for that type, but this doesn't work for type aliases (like drgn.Path). See sphinx-doc/sphinx#10785. Add a workaround inspired by adafruit/circuitpython#8236. Signed-off-by: Omar Sandoval <[email protected]>
To add on top of #10785 (comment), here's how to properly document and hide the dummy class reference using Python 3.12:
An example python file may look like this: """
.. class:: BytesOrStr
.. data:: BytesOrStr
:noindex:
:type: typing.TypeAliasType
:value: str | bytes
Type alias for bytes or string.
Bound:
:class:`str` | :class:`bytes`
.. class:: FilePath
.. data:: FilePath
:noindex:
:type: typing.TypeAliasType
:value: BytesOrStr | os.PathLike
Type alias for a file path.
Bound:
:class:`str` | :class:`bytes` | :class:`os.PathLike`
"""
import os
type BytesOrStr = str | bytes
type FilePath = BytesOrStr | os.PathLike
# More type aliases ...
Here is an example of what could be appended to from pathlib import Path
from bs4 import BeautifulSoup, Tag
# Define alias paths
TYPE_ALIASES = {
"BytesOrStr": "my_package.utils.",
"FilePath": "my_package.utils.",
}
def keep_only_data(soup: BeautifulSoup):
def has_children(tag: Tag, txt1: str, txt2: str):
if tag.name != "dt":
return False
# Get the prename and name elements of the signature
ch1 = tag.select_one("span.sig-prename.descclassname span.pre")
ch2 = tag.select_one("span.sig-name.descname span.pre")
return ch1 and ch2 and ch1.string == txt1 and ch2.string == txt2
for alias, module in TYPE_ALIASES.items():
if dt := soup.find("dt", id=f"{module}{alias}"):
# Copy class directive's a
a = dt.find("a").__copy__()
dt.parent.decompose()
else:
continue
if dt := soup.find(lambda tag: has_children(tag, module, alias)):
# ID and a for data directive
dt["id"] = f"{module}{alias}"
dt.append(a)
def edit_html(app, exception):
if app.builder.format != "html":
return
for pagename in app.env.found_docs:
if not isinstance(pagename, str):
continue
with (Path(app.outdir) / f"{pagename}.html").open("r") as f:
# Parse HTML using BeautifulSoup html parser
soup = BeautifulSoup(f.read(), "html.parser")
keep_only_data(soup)
with (Path(app.outdir) / f"{pagename}.html").open("w") as f:
# Write back HTML
f.write(str(soup))
def setup(app):
app.connect("build-finished", edit_html) |
In my case, I only encounter this issue if I have |
Describe the bug
When using
autodoc
to document type aliases in a module, references to those aliases in the signature of a function cannot be resolved, even when usingfrom __future__ import annotations
andautodoc_type_aliases
.How to Reproduce
Create
module.py
with these contents:and
index.rst
with these contents:and then run Sphinx, enabling autodoc and using
autodoc_type_aliases
:Expected behavior
On the
module.read_file(path: pathlike) → bytes
line,pathlike
should be a link to themodule.pathlike
type alias, but it is not a link at all.Running with nitpicky mode shows:
This is because
autodoc
is generating apy:attr
entry forpathlike
, and Sphinx is trying to resolve apy:class
entry instead.Your project
See "how to reproduce"
Screenshots
No response
OS
Linux
Python version
3.10.6
Sphinx version
5.1.1
Sphinx extensions
sphinx.ext.autodoc
Extra tools
No response
Additional context
I'm working around this with a hack in my
docs/conf.py
:The text was updated successfully, but these errors were encountered: