Stubgen can read multiple escaped signatures at the start of a docstring by AWhetter · Pull Request #10019 · python/mypy

Description

The autodoc extension for Sphinx supports using multiple function signatures defined at the start of the docstring on multiple lines separated by a backslash (https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#confval-autodoc_docstring_signature).
For example:

"""example(arg0: int) -> int \
example(arg0: str) -> str
This is the summary line.

This is the rest of the docstring.
"""

Currently stubgen fails to parse these lines, which results in it outputting the following signature for the above example: def example(*args, **kwargs) -> Any.

This change allows stubgen to parse these leading signatures in a docstring. I've done so in a backwards compatible way, but I have made what I think is a compromise to make it backwards compatible. I think that ideally any leading signatures in a docstring should be the only signatures that stubgen reads from a docstring.
I've made the change such that even if there are leading signatures in the docstring, the remaining signatures are still read. This is compatible with the current format that pybind11 outputs docstrings with. However I am currently looking to make pybind support this same docstring format that Sphinx expects (pybind/pybind11#2621).

So the current situation, before my changes, is:

# pybind11 output
"""example(*args, **kwargs) -> Any
Overloaded function.

1. example(arg0: int) -> int

2. example(arg0: str) -> str
"""

# stubgen outputs from the above docstring
"""
from typing import overload
@overload
def example(arg0: int) -> int: ...

@overload
def example(arg0: str) -> str: ...

@overload
def example(*args, **kwargs) -> Any: ...
"""

If only the pybind11 change goes ahead (no stubgen changes required because it cannot parse the leading signatures but can parse the section headings):

# pybind11 output
"""example(arg0: int) -> int \
example(arg0: str) -> str
Overloaded function.

1. example(arg0: int) -> int

2. example(arg0: str) -> str
"""

# stubgen outputs from the above docstring
"""
from typing import overload
@overload
def example(arg0: int) -> int: ...

@overload
def example(arg0: str) -> str: ...
"""

The change that I've made in this pull request allows for the extra flexibility of not needing the sections in the docstring:

# pybind11 output
"""example(arg0: int) -> int \
example(arg0: str) -> str
Overloaded function.

This bit of the docstring does not need to include signatures.
"""

# stubgen outputs from the above docstring
"""
from typing import overload
@overload
def example(arg0: int) -> int: ...

@overload
def example(arg0: str) -> str: ...
"""

What I think the ideal situation is:

# pybind11 output
"""example(arg0: int) -> int \
example(arg0: str) -> str
Overloaded function.

example(arg0: float) -> float
Although this is an unusual case, this extra signature should not get parsed.
"""

# stubgen outputs from the above docstring
"""
from typing import overload
@overload
def example(arg0: int) -> int: ...

@overload
def example(arg0: str) -> str: ...
"""

Test Plan

A test has been included. It failed before making changes to mypy.