Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Class attribute documentation? #1576

Closed
brettcannon opened this issue Jul 20, 2021 · 14 comments
Closed

Class attribute documentation? #1576

brettcannon opened this issue Jul 20, 2021 · 14 comments
Labels
enhancement New feature or request fixed in next version (main) A fix has been implemented and will appear in an upcoming version

Comments

@brettcannon
Copy link
Member

Discussed in microsoft/vscode-python#16736

Originally posted by Holt59 July 19, 2021
I'd like to know how I can get class attribute documentation on hover/completion, similar to what I would get with the docstring of a property:

class A:

    def __init__(self):
        self._foo = 33
        self.bar = 45
    
    @property
    def foo(self) -> int:
        """
        Returns:
            Foo documentation.
        """
        return self._foo

How can I get proper documentation (on hover/completion) for bar without using a property?

Note: I'm asking here since I don't know if it is something specific to this extension or to the server (I'm using Pylance).

@brettcannon brettcannon transferred this issue from microsoft/vscode-python Jul 20, 2021
@jakebailey
Copy link
Member

We emulate inspect.getdoc, which I don't think has support for variables, as it's an algorithm that traverses looking for __doc__. I'm not really aware of any standard method to annotate variables, only objects that can have a __doc__ (including properties).

@erictraut
Copy link
Contributor

@brettcannon, out of curiosity, how would you typically provide documentation for a class or instance variable? A string literal on the line before the variable's first usage? On the line after (consistent with docstrings in class and function declarations)? On the same line, as an end-of-line comment?

Do you think there's sufficient consistency in how this is done in Python code for pyright to assume there's a standard?

@Holt59
Copy link

Holt59 commented Jul 21, 2021

@erictraut As explained in the original discussion, it's indicated in PEP 257

String literals occurring immediately after a simple assignment at the top level of a module, class, or init method are called "attribute docstrings".

So basically:

def __init__(self):
    self.foo = 33
    """Description of foo."""

I'm not sure it's used a lot but it's specified somewhere. Another way would be to parse the class docstring but I guess it would be a much bigger change.

@judej judej added the enhancement New feature or request label Jul 21, 2021
@github-actions github-actions bot removed the triage label Jul 21, 2021
@brettcannon
Copy link
Member Author

To be honest, I am not aware of any specific standard around attribute documentation. I actually didn't even know about the line from PEP 257 until @Holt59 pointed it out to me.

@erictraut
Copy link
Contributor

Yeah, I wasn't aware of that either. I don't recall ever seeing an "attribute docstring" used in Python code.

@eric-tramel
Copy link

As a bump to this issue, I actually just ran into this, myself. One of the specific use-cases for this kind of functionality is in the definition of constants modules. Let's say you have a lot of constants you need to make use of in your program or library, and you would like other developers (or yourself...) to be able to quickly look up detailed information about the nature of these constants (think scientific computing).

One could opt for a verbose strategy of classing...

class _BestNumbers:
    """A very well documented class."""

    @property
    def the_best_number(self) -> int:
        """The best number known. 

        This extensive documentation explains why this particular
        value is the best. It all started when....
        """
        return 42

BestNumbers = _BestNumbers()

image

However, a less cumbersome method might be to just define such sets of constants within their own module. But in this case, while PEP 257 illustrates how one could document such variables for those visiting the source definition, unless the language server supports PEP 257, those docstrings aren't carried forward to where the developer actually needs it.

# Defined within some constants/best_numbers.py

THE_BEST_NUMBER: int = 42
"""The best number known. 

This extensive documentation explains why this particular
value is the best. It all started when....
"""

image

@erictraut
Copy link
Contributor

@eric-tramel, thanks for the input. Yes, what you say makes sense in theory. In practice, I've never seen attribute docstrings (as defined in PEP 257) used in any Python libraries. Are you aware of any examples of their use? This might be a chicken-vs-egg situation where library authors will start to include attribute docstrings in more cases if pylance and other tools start to support them.

@eric-tramel
Copy link

Not public ones, sorry @erictraut :)

I would think it is more chicken-and-egg. I know that I would write simpler code if it meant that others using it could get information more easily. But if I have to contort with classes to do it, then I use the @property methodology. However, it is down to the IDE/LanguageServer selection, as I believe PyCharm supports this convention of attribute documentation, and it is also supported in Epydoc, if my information is correct.

@erictraut
Copy link
Contributor

Support for attribute docstrings in the completion provider will be included in the next release of pyright and pylance.

@erictraut erictraut added the fixed in next version (main) A fix has been implemented and will appear in an upcoming version label Jul 25, 2021
@bschnurr
Copy link
Member

bschnurr commented Jul 28, 2021

This issue has been fixed in version 2021.7.6, which we've just released. You can find the changelog here: https://github.com/microsoft/pylance-release/blob/main/CHANGELOG.md#202176-28-july-2021

@phitoduck
Copy link

Sorry, I know this has been closed for a while, but... THIS THREAD BLEW MY MIND. I had no idea this was a thing. Now I do. To whoever worked on this: you're amazing.

@kaste
Copy link

kaste commented Sep 27, 2022

Necro-posting, but anyway. This style

    self.foo = "bar"
	""" This is what foo does """

was explicitly rejected by Guido https://peps.python.org/pep-0224/. Maybe that's why nobody uses it.

Wide usage (and support from sphinx) has

        #: Hint to draw to the right-hand side of the row.
        self.annotation: str = annotation

        self.kind: Kind = kind  #: The kind of the item. See `Kind`.

as for example seen https://github.com/pytest-dev/pytest/blob/main/src/_pytest/reports.py#L272 https://github.com/pallets/flask/blob/main/src/flask/app.py#L207 🤷

The #: makes it clear that this is a special comment. Both are not available at runtime. For that __doc_foo__ must be used (not within __init__ of course). (That was rejected as well silly me.)

@starball5
Copy link

Is there an existing feature-request issue to add support for the style that @kaste mentioned above? It was just asked about on Stack Overflow: Show Python docstring for instance attribute in VS Code.

@rchiodo
Copy link
Contributor

rchiodo commented Aug 8, 2023

Is there an existing feature-request issue to add support for the style that @kaste mentioned above? It was just asked about on Stack Overflow: Show Python docstring for instance attribute in VS Code.

I don't believe so. But if it's not part of standard doc strings, it would probably take a lot of up votes for us to add it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request fixed in next version (main) A fix has been implemented and will appear in an upcoming version
Projects
None yet
Development

No branches or pull requests