pdoc3 / pdoc

:snake: :arrow_right: :scroll: Auto-generate API documentation for Python projects
https://pdoc3.github.io/pdoc/
GNU Affero General Public License v3.0
1.11k stars 143 forks source link

Request: Add option to generate `.pyi` stub files #405

Open USSX-Hares opened 2 years ago

USSX-Hares commented 2 years ago

Hi

I was searching for some typing inspection tools and found none that can both generate a python stub file (.pyi) and use the data from the runtime. This is required in order to generate typing for dynamic method signatures, such as dataclasses' methods or manually changed function __signature__ property (i.e., via decoration).

Use Case

Let's assume we have a function func_1 that accepts three keyword-only parameters: k1, k2, and k3, with k1 being mandatory and k2 and k3 having their default values. Then, introduce function func_2 which, in addition to its own arguments, accepts **kwargs which then translates to the arguments of func_1:

def func_1(*, k1: str, k2: int = 2, k3: int = 3) -> None: ...
def func_2(p1, *, k0: bool = False, **kwargs) -> None: ...
    return func_1(**kwargs)

We want to state that func_2 not only accepts the variable keyword arguments but expects exactly arguments of func_1. There are several ways to do so, one requires manually listing all parameters in the @typing.overload or module stub, and the other requires runtime signature analysis.

Expected:

def func_1(*, k1: str, k2: int = 2, k3: int = 3) -> None: ...
def func_2(p1, *, k0: bool = False, k1: str, k2: int = 2, k3: int = 3) -> None: ...

Options:

@overload
def func_2(p1, *, k0: bool = False, k1: str, k2: int = 2, k3: int = 3) -> None: ...
    pass
def func_2(p1, *, k0: bool = False, **kwargs) -> None: ...
    return func_1(**kwargs)
@some_magic_deco(func_1)
def func_2(p1, *, k0: bool = False, **kwargs) -> None: ...
    return func_1(**kwargs)

However, both methods have their own problems: the first works fine when used in the same file with a small number of arguments but truly gets monstrous as either the number of arguments or the chain of calls rises, while the second one does not work with the static analyzers such as MyPy or PyCharm's inspector.

Thus, if pdoc would be able to process the source code files and result in the identical .pyi files which can be included in the wheel distribution, that would be perfect.

P.S.

Lately introduced PEP-612 solves this problem only partially, so I searched for a runtime code analyser and concluded that pdoc3 is the best solution for the problem (only a new exporter is required).

Inspired by the discussion of https://github.com/python/typing/issues/270