jsh9 / pydoclint

A Python docstring linter that checks arguments, returns, yields, and raises sections
https://pypi.org/project/pydoclint/
MIT License
146 stars 15 forks source link

pydoclint generates DOC602 and DOC603 on google style guide example for classes #163

Open jabbera opened 2 months ago

jabbera commented 2 months ago

The google style guide for instance class attributes is here: https://google.github.io/styleguide/pyguide.html#384-classes

The example they provide is:

class SampleClass:
    """Summary of class here.

    Longer class information...
    Longer class information...

    Attributes:
        likes_spam: A boolean indicating if we like SPAM or not.
        eggs: An integer count of the eggs we have laid.
    """

    def __init__(self, likes_spam: bool = False):
        """Initializes the instance based on spam preference.

        Args:
          likes_spam: Defines if instance exhibits this preference.
        """
        self.likes_spam = likes_spam
        self.eggs = 0

    @property
    def butter_sticks(self) -> int:
        """The number of butter sticks we have."""

Running this though 0.5.6 pydoclint with the following settings:

[tool.pydoclint] style = 'google' allow-init-docstring = true

generates the following errors:

    1: DOC602: Class `SampleClass`: Class docstring contains more class attributes than in actual class attributes.  (Please read https://jsh9.github.io/pydoclint/checking_class_attributes.html on how to correctly document class attributes.)
    1: DOC603: Class `SampleClass`: Class docstring attributes are different from actual class attributes. (Or could be other formatting issues: https://jsh9.github.io/pydoclint/violation_codes.html#notes-on-doc103 ). Arguments in the docstring but not in the actual class attributes: [eggs: , likes_spam: ]. (Please read https://jsh9.github.io/pydoclint/checking_class_attributes.html on how to correctly document class attributes.)

Can you please tell me how I should be documenting class instance variables?

jsh9 commented 1 month ago

Hi @jabbera ,

Sorry for the delayed reply.

In pydoclint, "class attributes" specifically refer to the attributes above the __init__() function.

In your example, both eggs and likes_spam are instance attributes rather than class attributes. Because both of them can only be initiated when you actually instantiate an instance of this class.

jabbera commented 1 month ago

@jsh9 no worries on the delay getting back to me. I think you misunderstood my issue. Google doc style says instance attributes should be defined as in the example above. When I do they Pydoclint complains about class attributes (static fields). My question is how to I document the instance fields?

jsh9 commented 1 month ago

This would work, I think.

class SampleClass:
    """Summary of class here.

    Longer class information...
    Longer class information...
    """

    def __init__(self, likes_spam: bool = False):
        """Initializes the instance based on spam preference.

        Args:
          likes_spam: Defines if instance exhibits this preference.
        """
        self.likes_spam = likes_spam
        self.eggs = 0

    @property
    def butter_sticks(self) -> int:
        """The number of butter sticks we have."""

The trick is to use "Attributes" section in the docstring for class attributes, and use the "Arg" section in the docstring for instance attributes or arguments to the init function.

jabbera commented 1 week ago

@jsh9 I appreciate your take on it, but pydoclint isn't following the example google sets forth and since I can't exclude the rule from pydoclint it's really causing a headache.