Skip to content

feature: support deprecation on overloads #7

@dmanuel64

Description

@dmanuel64

Is your feature request related to a problem? Please describe.

griffe-warnings-deprecated does not surface @warnings.deprecated applied to @overload as specified in PEP 702.

Right now, only the implementation function shows up as deprecated in the docs. This means that deprecations tied to specific parameter combinations (overloads) are lost. In my case, deprecations are tied to specific parameters. I mark only those overloads as deprecated so that:

  • IDEs and type checkers will not strike through the entire function, and
  • users won’t get a runtime warning for every call - only when using the deprecated form.

However, mkdocstrings with the griffe-warnings-deprecated extension currently renders those overload signatures without any deprecation badge or note, even though the overloads are decorated with @warnings.deprecated.

Describe the solution you'd like

  • Recognize @warnings.deprecated(...) applied to @overload definitions.
  • Render a “Deprecated” badge/label per overload signature in the API docs, with the decorator’s message shown in a small note/admonition beneath that overload.

Describe alternatives you've considered

  • Decorating the implementation function instead of the overloads.
    Problem: IDEs (and some linters) then mark the whole function as deprecated and users get warnings for all calls, not just the deprecated forms.
  • Manually documenting parameter deprecations in the docstring.
    Problem: easy to drift from code, and doesn’t tie into type checkers/PEP 702.

Additional context

Example of issue:

from typing import Optional, Callable, overload
from warnings import deprecated

class Mod: ...
class Settings: ...

@overload
def build(mod: Mod, *, overwrite: bool = False) -> None: ...

@overload
@deprecated("`path` is deprecated; use `mod.mod_path` instead.")
def build(mod: Mod, *, path: Optional[str], overwrite: bool = False) -> None: ...

@overload
@deprecated("`settings_factory` is deprecated; configure `Settings` directly.")
def build(mod: Mod, *, overwrite: bool = False,
          settings_factory: Optional[Callable[[], Settings]]) -> None: ...

@overload
@deprecated("`path` and `settings_factory` are deprecated.")
def build(mod: Mod, *, path: Optional[str], overwrite: bool = False,
          settings_factory: Optional[Callable[[], Settings]]) -> None: ...

def build(mod: Mod, path: Optional[str] = None, overwrite: bool = False,
          settings_factory: Optional[Callable[[], Settings]] = None) -> None:
    """Implementation; not deprecated as a whole."""
    ...

mkdocstrings configuration in mkdocs.yaml:

...
- mkdocstrings:
    handlers:
      python:
        paths: [src]
        options:
            extensions:
              - griffe_warnings_deprecated
              - griffe_pydantic:
                  schema: true
...

Current behavior: overloads render but show no deprecation badge.

Image

As mentioned earlier in Alternative's Considered, decorating the implementation makes deprecation show, but marks the entire function as deprecated and IDEs warn on all calls.

Image Image

Expected behavior: only the overloads decorated with @deprecated should show a deprecation badge, leaving the implementation and non-deprecated overloads untouched, like as shown in the VSCode IDE:

Image

Metadata

Metadata

Assignees

Labels

featureNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions