readthedocs / sphinx-autoapi

A new approach to API documentation in Sphinx.
https://sphinx-autoapi.readthedocs.io/
MIT License
415 stars 126 forks source link

Add support for type aliases introduced in Python 3.12 via PEP 695 #414

Open Stausssi opened 7 months ago

Stausssi commented 7 months ago

Hi,

I've started updating my codebases to Python 3.12, including adding type aliases via type CustomType = dict[str, int] | list[int] and sharing them across files via from src.module import CustomType. The code itself works fine, but building the documentation does not: Cannot resolve import of src.module.CustomType in src.other_module Since I use warnings-as-errors by default, this currently breaks all my documentation builds. Setting suppress_warnings = ["autoapi"] does get rid of the warning. There might be a correlated issue in sphinx-doc/sphinx#11561.

I'm also not quite sure how these type aliases are supposed to be documented and opened a discussion on python.org, but this does not resolve the import issues.

etienneschalk commented 4 months ago

Hello,

I do not have exactly the same issue, as luckily my code base only use types declared with the type keyword inside of the module where they were declared.

Screenshot from 2024-02-11 14-32-58

However, such declared types are rendered as plain text: no "unwrapping" of the nested types like done before, nor a link to a potential type definition

I am not sure if this is a problem on sphinx-autoapi itself, or upstream on autodoc and other tools.

A suggestion: add a "Types" section that summarizes the type definitions. In function signatures, add links to the type definition. We can even push further and imagine having a tooltip like in IDEs displaying information about the type

Example of code using type keyword:

type PuzzleInput = list[tuple[list[str], int]]
type HandAndBid = tuple[list[int], int]
type PuzzleMappedInput = list[HandAndBid]
type SortedByHandType = dict[Any, list[HandAndBid]]

@dataclass(kw_only=True)
class AdventOfCodeProblem202307(AdventOfCodeProblem[PuzzleInput]):
    year: int = 2023
    day: int = 7

    def solve_part_1(self, puzzle_input: PuzzleInput): ...

When hovering PuzzleInput the mouse over the solve_part_1 method in VSCode, the full unwrapped type is shown in a tooltip:

(type alias) PuzzleInput: type[list[tuple[list[str], int]]]

When hovering SortedByHandType, the unwrapped definition also shows up in a tooltip

(type alias) SortedByHandType: type[dict[Any, list[tuple[list[int], int]]]]
AWhetter commented 4 months ago

Just noting that this is currently blocked due to the lack of a way to document type aliases in Sphinx (https://github.com/sphinx-doc/sphinx/issues/7896). astroid already has support for parsing type aliases.

AWhetter commented 3 months ago

It seems that implementing type aliases in Sphinx is going to take some time. In the meantime, I've pushed a commit that will workaround the limitation by rendering PEP-695 type usage as an assignment to a variable that's annotated with typing.TypeAlias. Once we have proper PEP-695 support on Sphinx we can change AutoAPI to render these properly.