ty icon indicating copy to clipboard operation
ty copied to clipboard

Docstrings for reexported functions do not fall back to implementation definition

Open Jammf opened this issue 4 weeks ago • 2 comments

Summary

When hovering a reexported function from a module with a .pyi stub file, the docstring from the stub file definition is (correctly) shown instead of the implementation docstring. However, if the stub definition does not have a docstring, then the docstring is missing on hover instead of falling back to the implementation docstring.

## a/b.py
def foo() -> None:
    """Implementation docstring"""
    pass

def bar() -> None:
    """Implementation docstring"""
    pass


## a/__init__.pyi
def foo() -> None: 
    """Stub docstring"""
    ...

def bar() -> None: 
    ...


## a/__init__.py
from .b import foo as foo
from .b import bar as bar


## main.py
from a import foo  # Stub docstring
from a import bar  # <missing docstring>

This is in contrast to the following example that works as expected, when the stub file a/__init__.pyi is renamed to a/b.pyi:

## a/b.py
def foo() -> None:
    """Implementation docstring"""
    pass

def bar() -> None:
    """Implementation docstring"""
    pass


## a/b.pyi          <-- Renamed
def foo() -> None: 
    """Stub docstring"""
    ...

def bar() -> None: 
    ...


## a/__init__.py
from .b import foo as foo
from .b import bar as bar


## main.py
from a import foo  # Stub docstring
from a import bar  # Implementation docstring

Playground link: https://play.ty.dev/74d4d6ee-8ced-41da-b0c6-bf8167f510ae

Possibly related: https://github.com/astral-sh/ty/issues/788#issuecomment-3175228024

Version

ty 0.0.5 (d37b7dbd9 2025-12-20)

Jammf avatar Dec 21 '25 20:12 Jammf

Module-level attributes seem to have a similar issue, except in their case even a .pyi for the implementation file doesn't fall back correctly when stub docstring is omitted:

## a/b.py
FOO = 3
"""Implementation docstring"""

BAR = 4
"""Implementation docstring"""


## a/b.pyi 
FOO: int
"""Stub docstring"""

BAR: int


## main.py
from a.b import FOO  # Stub docstring
from a.b import BAR  # MISSING docstring!

https://play.ty.dev/dae79e23-d61b-4d23-8962-f9b9e67a60da

Jammf avatar Dec 21 '25 21:12 Jammf

Thanks. There's a related issue where we want to show the docstring of the overriden function if the override doesn't have a docstring.

MichaReiser avatar Dec 22 '25 12:12 MichaReiser