pybind11 icon indicating copy to clipboard operation
pybind11 copied to clipboard

Proper pep695 generic function docstrings

Open InvincibleRMC opened this issue 6 months ago • 4 comments

Description

Add typevar_record to hold information about function type variables. Use these type variables to update the generated docstrings as according to pep695.

To be used in conjuction with the typevar types introduced in #5167.

Suggested changelog entry:

  • Introduce typevar_record to add pep695 generics to function docstrings.

InvincibleRMC avatar Jun 24 '25 22:06 InvincibleRMC

@timohl if you have any comments/suggestions please let me know.

InvincibleRMC avatar Jun 24 '25 23:06 InvincibleRMC

I should find time to review the code in more detail during the weekend, but I already skimmed through the tests and the new syntax looks nice. :)

One thing that came to my mind though is backwards compatibility. PEP695 is added in Python 3.12. Have you tested how stubgen and type checkers react in older versions, or any plans on how to make this compatible?

Also, what is the impact of the check for PYBIND11_HAS_OPTIONAL? The test is guarded by PYBIND11_TYPING_H_HAS_STRING_LITERAL. In the end, it would be nice to add tests for setups where the requirements of this feature are not met.

timohl avatar Jun 25 '25 08:06 timohl

I should find time to review the code in more detail during the weekend, but I already skimmed through the tests and the new syntax looks nice. :)

One thing that came to my mind though is backwards compatibility. PEP695 is added in Python 3.12. Have you tested how stubgen and type checkers react in older versions, or any plans on how to make this compatible?

From what I can tell mypy's stubgen or pybind11-stubgen currently ignore the inside of pep695. Mypy has a todo.

Mypy will fail if running in version less than 3.12

def foo[T](a: T) -> T: ...  # invalid syntax

However, mypy could when implementing support generate pre-pep695 syntax in stubs when ran on older python versions.

import typing

T = typing.TypeVar("T")
def foo(a: T) -> T: ... # valid

InvincibleRMC avatar Jun 25 '25 16:06 InvincibleRMC

I don't know how much this would get used but it would be a nice addition to pybind11. I have one function that could use this which is currently documented with a custom docstring.

I added very basic support for this syntax to my fork of pybind11-stubgen. It only supports the un-type-hinted variant. https://github.com/sizmailov/pybind11-stubgen/commit/283cc7ede5448dcf415e22867b0aa638ba31e31e

Looks like the tests are failing due to our changes to type hints.

gentlegiantJGC avatar Nov 15 '25 08:11 gentlegiantJGC