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

Question: Docstring formatting information/examples #95

Open
zachcran opened this issue Aug 31, 2024 · 2 comments
Open

Question: Docstring formatting information/examples #95

zachcran opened this issue Aug 31, 2024 · 2 comments

Comments

@zachcran
Copy link
Contributor

Can you provide information about how docstrings are formatted when a Python file is given to docstrfmt?

Things I have noticed that surprised me so far:

  • The first line of a multi-line docstring (the summary line) does not get split to multiple lines if it goes over the line length limit, but other lines will be reformatted. This kind of makes sense because PEP 257 says that the summary line should fit on one line, but looks like a bug to anyone not familiar with it. (I'm still not sure if it is a bug or not, honestly)

  • Function parameter documentation like:

    :param var1: This is the description of an optional parameter, defaults to 5
    :type var1: int, optional
    

    is compacted to

    :param int, optional var1: This is the description of an optional parameter, defaults to 5
    

    which I didn't even realize was possible! It was hard to find where this compact format was defined (here, I think) in the Sphinx documentation, so I was initially suspicious of whether it was actually part of the Sphinx format. Links to the formatting guide and/or formatted samples would be incredibly useful in clearing up things like this.

@LilSpazJoekp
Copy link
Owner

I certainly can!

  1. Your deduction is spot on. It is intentional to not format the first line. Doing so would cause other linters to complain about the violation.
  2. Typing can be provided in the parameter itself. This is interpreted against the standard library and your code base assuming you utilize sphinx's autodoc module. Your typing annotation in the example code is technically incorrect. It should be Something like this:
    :param Optional[int] var1: This is the description of an optional parameter, defaults to 5.
    
    Or
    :param int | None var1: This is the description of an optional parameter, defaults to 5.
    

Re: linking relevant documentation: This would be quite a tedious undertaking to do so. It would also likely require a dedicated readthedocs page (which is likely coming soon for configuration alone) for the project. I would welcome if someone wants to take it on but I don't have the bandwidth to do so right now. To be completely honest, I don't see the benefit out weighing the time investment in documenting/cross referencing every aspect of ReStructuredText+Sphinx that this project formats. Now, I'm not ruling it out completely as this project has seen more activity in the last month than nearly its entire history. However, I'd rather cite/explain things ad-hoc as they come up (this could later be compiled into a doc if there's demand for it) than to document everything outright all at once.

@zachcran
Copy link
Contributor Author

zachcran commented Sep 1, 2024

Makes sense, I totally get the lack of bandwidth! I also get the tediousness of linking a bunch of different references for the formatting choices. Alternatively, a few sample docstrings would really go a long way in communicating what to expect. I can make a PR with a few samples if you want, since I am toying around with it in a personal project right now and can easily convert some formatted docstrings into samples.

Your typing annotation in the example code is technically incorrect.

I don't think it is incorrect in this instance, although I didn't even know Optional[] existed before now so I had to do some reading and still might not understand!

From PEP 484, Optional[T1] is a shortcut for Union[T1, None] for the type. My understanding is that this helps type checkers not complain about instances where None is a valid value, but your desired type is actually some class or typedef, T1. I think some other languages call this "Nullable", and I've seen a lot of mentions in forums that Optional[] was an unfortunate and misleading name. In my case, the default value is an int and I want to tell the user that int is the only acceptable type for var1. Using Optional[int] or int | None would imply that None is also a valid value/type, which it is not. After some testing, I found that type checkers like mypy will actually complain if you use var: Optional[int] = 5 and then try to do var + 3 later on, since None is not a valid type to use for the + operator.

As far as using , optional at the end of :type var1: int, optional, that is what the autoDocstring extension of VSCode generates for the signature def foo(var1: int = 5):. It has >10.4 million installs, so I'm content to go with that default if it is what everyone else is doing. The docstrfmt formatted version still compiles and displays nicely, too!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants