Types with nested "|" (Union) are not formatted well
For this program:
from __future__ import annotations
from typing import Iterable
def function1(value: int | str = 1) -> None:
pass
def function2(value: int | str | Iterable[int | str] = 1) -> None:
pass
pdoc produces the documentation:
def function1(value: int | str = 1) -> None:
def function2(value: Union[int, str, Iterable[int | str]] = 1) -> None:
If feasible, it might be best to always use the more modern ... | ... syntax and never the Union[...] syntax.
This seems to be an upstream bug in Python itself:
>>> from typing import Iterable
>>> int | str | Iterable[int | str]
typing.Union[int, str, typing.Iterable[int | str]]
as well as
>>> import inspect
>>> inspect.formatannotation(int | str | Iterable[int | str])
'Union[int, str, Iterable[int | str]]'
Interesting; I can reproduce your results above, but then also:
>>> def f(a: int | str | Iterable[int | str] = 1):
>>> return a
>>> inspect.formatannotation(f.__annotations__)
"{'a': 'int | str | Iterable[int | str]'}"
The difference might be related to the postponed evaluation of the annotation context?
Actually, f.__annotations__ already contains the nice strings:
{'a': 'int | str | Iterable[int | str]'}
I'm curious: what would be the drawbacks of directly using the strings from f.__annotations__ for the pdoc documentation (assuming that the code has enabled from __future__ import annotations)?
It gives the user the choice to refer to local type aliases or to fully qualified module.types, etc.
The main drawback is that linking becomes much harder (how do we know that Doc is actually pdoc.doc.Doc, but maybe we can do some tricks here similar (but simpler) to 1a in the other issue. I'll take a look! :)
For the record, the problem here is that typing does not perfectly interoperate with the new types.UnionType (on which the | syntax is based). The following works as expected:
from collections.abc import Iterable # not from typing!
def function2(value: int | str | Iterable[int | str] = 1) -> None:
pass
Amazing that you found this!
I just confirmed on my code that this issue goes away when migrating to using collections.abc.
It does make that pdoc documentation longer, e.g. collections.abc.Iterable[...] so some control over verbosity of type expansion (#420) would still be handy.