mkdocstrings icon indicating copy to clipboard operation
mkdocstrings copied to clipboard

bug: False positive "Parameter does not appear in function signature" with typing.dataclass_transform

Open bessman opened this issue 1 year ago • 1 comments

Description of the bug

PEP681 introduced dataclass_transform, a decorator for marking objects with dataclass-like behavior, available in python3.11+.

Griffe incorrectly warns about missing parameters of such objects' docstrings.

To Reproduce

# helloclass.py
from dataclasses import dataclass
from typing import dataclass_transform


@dataclass_transform()
class HelloDataClass:
    """A dataclass which says 'Hello' on creation."""

    def __init_subclass__(cls) -> None:
        """Say hello."""
        print("Hello")
        dataclass(cls)


class HelloPerson(HelloDataClass):
    """A person with name and age.

    Parameters
    ----------
    name : str
    age : int
    """

    name: str
    age: int
# mkdocs.yaml
site_name: hello
nav:
  - Home: index.md
plugins:
  - mkdocstrings:
      default_handler: python
      handlers:
        python:
          options:
            docstring_style: numpy
<!-- docs/index.md -->
::: helloclass

Full traceback

$ mkdocs build
INFO    -  Cleaning site directory
INFO    -  Building documentation to directory: /tmp/site
WARNING -  griffe: helloclass.py:21: Parameter 'name' does not appear in the
           function signature
WARNING -  griffe: helloclass.py:21: Parameter 'age' does not appear in the
           function signature
INFO    -  Documentation built in 0.21 seconds

Expected behavior

A class which inherits from a base decorated with dataclass_transform, or itself decorated by a decorator decorated by dataclass_transform, should not warn about missing parameters in function signature.

bessman avatar Dec 22 '24 14:12 bessman

Hi @bessman, thanks for the report!

Aahhh... more dynamic stuff to handle statically :sweat_smile:

In this case, things get hairy. This will probably require a new built-in extension. The extension will have to:

  • find classes decorated with @dataclass_transform
  • then find classes that inherit from such classes (directly or indirectly)
  • and run the built-in dataclasses extension onto them somehow

Well, it would be nice if we could reuse code, but that might prove difficult.

Also, I see you call dataclasses.dataclass(cls): what if you called pydantic.dataclasses.dataclass(cls) instead, or any other dataclass-like transform? This will be impossible to detect statically unfortunately. So, what should we do? Always default to considering the inheriting classes to be standard dataclasses.dataclass? What else can we do without forcing devs to add additional metadata just for Griffe?

The alternative is always to fallback onto dynamic analysis for these objects: https://mkdocstrings.github.io/griffe/guide/users/how-to/selectively-inspect/.

I'll mark this as a feature rather than a bug. Griffe does not claim to support the whole standard library or all PEPs: that's only a goal :slightly_smiling_face:

pawamoy avatar Dec 22 '24 14:12 pawamoy