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

Change the line length limit of docstrings to 88 characters #962

Closed
seisman opened this issue Feb 24, 2021 · 22 comments · Fixed by #2925
Closed

Change the line length limit of docstrings to 88 characters #962

seisman opened this issue Feb 24, 2021 · 22 comments · Fixed by #2925
Labels
maintenance Boring but important stuff for the core devs
Milestone

Comments

@seisman
Copy link
Member

seisman commented Feb 24, 2021

We use the Black tool to format the code, and the default line length of Black is 88 characters. The 88-char line length limit is only applied to code, not docstrings. For docstrings, the line length limit is 79 characters, and we use several tools, blackdoc, docformatter and flake8 to check and format the docstrings.

Then, the question is, why do we use different line length limits for code and docstrings?

We started to adopt the 79-char line length limit for docstrings in PR #384. The PR description also explains why we choose 79-char length (also see some external discussions in fatiando/verde#177)

Jupyter, IPython, and other IDEs don't usually render the rst in the
docstrings and just show them literally. The problem is that many of
these break lines at 79 characters. So docstrings with more characters
look terrible in these settings and sometimes almost unreadable. Wrap
all docstrings to 79 characters instead of Black's 88.


Is the reason still valid?

I just changed one line of the docstrings of Figure.basemap() to ~120 chars, and checked what the docstrings look like in Jupyter, IPython, PyCharm, and VS Code. Here are the results:

In Jupyter Notebook, the long docstrings look good with the help() function:

image

Also look good in the Notebook Contextual Help page:

image

In a Python or IPython console:

image

In VS Code:

image

In PyCharm:

image


From the above screenshots, it's clear that these consoles, editors, and IDEs don't wrap docstrings at 80 characters and work well with long docstrings.

Now the questions are:

  1. Are they any other common editors or IDEs that force wrapping docstrings at 80 characters?
  2. Should we change the line length limit of docstrings to 88 characters?
@seisman seisman added the question Further information is requested label Feb 24, 2021
@maxrjones
Copy link
Member

To me, the example docstring looks good in VSCode and PyCharm but the return between 'separate'/'tick-intervals' and 'or'/'compass' in the Notebook and the Python console decreases readability and does not look good. Do you know why there are returns in those two locations?

@seisman
Copy link
Member Author

seisman commented Feb 24, 2021

Oh, sorry for the confusion. To test what long docstrings look like, I changed (locally) the docstrings of Figure.basemap() to:

@kwargs_to_strings(R="sequence", c="sequence_comma", p="sequence")
def basemap(self, **kwargs):
    r"""
    Plot base maps and frames for the figure.

    Creates a basic or fancy basemap with axes, fill, and titles. Several map projections are available, and the user
    may specify separate
    tick-mark intervals for boundary annotation, ticking, and [optionally]
    gridlines. A simple map scale or directional rose may also be plotted.

    At least one of the parameters ``frame``, ``map_scale``, ``rose`` or
    ``compass`` must be specified.

So it seems VSCode and PyCharm remove all "returns" in the docstrings, while Python and notebook keep them.

@seisman
Copy link
Member Author

seisman commented Feb 25, 2021

Ping @GenericMappingTools/python @GenericMappingTools/python-maintainers for thoughts.

@maxrjones
Copy link
Member

I have no problems with changing it. Is your preference 88 or ~120 characters @seisman?

@seisman
Copy link
Member Author

seisman commented Feb 25, 2021

Is your preference 88 or ~120 characters

We will stick with 88 characters (the default value of Black) if others agree.

@michaelgrund
Copy link
Member

Is your preference 88 or ~120 characters

We will stick with 88 characters (the default value of Black) if others agree.

Would be fine for me.

@weiji14
Copy link
Member

weiji14 commented Feb 26, 2021

I would keep it at 79 characters. The point made at #384 and fatiando/verde#177 is for the Parameters section. E.g. in jupyterlab 3.0.9, try reading this (wrapping at 120 chars):

image

Wrapping to 88 char is fine on jupyterlab but not the classic jupyter notebook:

image

@seisman
Copy link
Member Author

seisman commented Feb 26, 2021

Hmmm, I didn't know the "Shift+Tab" shortcut for the docstring tooltip until today.

It seems JupyterLab wraps at 90 characters, but Jupyter Notebook wraps at 80 characters.

So, the only reason to keep 79 characters is to make it look better in the classic Jupyter Notebook? But, is jupyter notebook still heavily used by people? Even the jupyter notebook project encourages people to use JupyterLab instead.

Please note that this repository is currently maintained by a skeleton crew of maintainers from the Jupyter community. We encourage users to transition to JupyterLab, where more immediate support can occur.

@weiji14
Copy link
Member

weiji14 commented Feb 26, 2021

Hmmm, I didn't know the "Shift+Tab" shortcut for the docstring tooltip until today.

Wow, you've missed out on so much then!!

So, the only reason to keep 79 characters is to make it look better in the classic Jupyter Notebook? But, is jupyter notebook still heavily used by people? Even the jupyter notebook project encourages people to use JupyterLab instead.

Please note that this repository is currently maintained by a skeleton crew of maintainers from the Jupyter community. We encourage users to transition to JupyterLab, where more immediate support can occur.

You will be surprised at how many people still use the classic notebook, even as jupyerlab has been around for a few years. I haven't had time to look, but Google Collaboratory, Kaggle and others probably use a similar classic notebook interface. This is one of those things where it's better to keep things as it is - if it ain't broken, don't fix it.

@seisman
Copy link
Member Author

seisman commented Feb 26, 2021

You will be surprised at how many people still use the classic notebook, even as jupyerlab has been around for a few years. I haven't had time to look, but Google Collaboratory, Kaggle and others probably use a similar classic notebook interface. This is one of those things where it's better to keep things as it is - if it ain't broken, don't fix it.

Fair enough. Let's keep the docstring to 79 characters.

@seisman seisman closed this as completed Feb 27, 2021
@seisman
Copy link
Member Author

seisman commented Oct 19, 2023

I'm reopening the issue so that we can revisit it again.

$ jupyter --version                                                                                                                                                                         Selected Jupyter core packages...
IPython          : 8.7.0
ipykernel        : 6.25.2
ipywidgets       : 8.1.1
jupyter_client   : 7.4.9
jupyter_core     : 5.3.2
jupyter_server   : 2.7.3
jupyterlab       : 3.5.3
nbclient         : 0.7.4
nbconvert        : 7.8.0
nbformat         : 5.9.2
notebook         : 6.0.0
qtconsole        : 5.4.4
traitlets        : 5.11.2

It seems at least recent Jupyter notebooks no longer wrap at 79 characters:
image

@seisman seisman reopened this Oct 19, 2023
@seisman
Copy link
Member Author

seisman commented Oct 19, 2023

The main reasons that I prefer to set the line-length limit of docstrings to 88 characters:

  1. Make line-lengths of source codes and docstrings consistent.
  2. Increase line length and reduce number of lines.
  3. The 79-character line-length limit makes no sense for comments in gallery example files.

@leouieda
Copy link
Member

@seisman does the update handle indentation in Parameters blocks? That's still the worst part.

And my experience is also that loads of people still use the classic notebook and have no intention of going to Jupyter Lab.

@seisman
Copy link
Member Author

seisman commented Oct 20, 2023

does the update handle indentation in Parameters blocks? That's still the worst part.

I tried to merge two lines into a single long line. As you can see below, the word with is wrapped into two lines and t is the 86-th character. So it seems the classic notebook wraps at 86-characters, not 88.

image

Jupyter Lab wraps at 96-characters:

image

@seisman
Copy link
Member Author

seisman commented Oct 20, 2023

Quickly checked the line-length in numpy, xarray and pandas. It seems numpy strictly follows the 80-char rule, while in xarray and pandas, most lines are shorter than 80-char, but there are also many lines longer than 80-char.

@seisman
Copy link
Member Author

seisman commented Dec 22, 2023

Not sure why I had notebook v6.0.0 installed in #962 (comment). I just tried again with notebook versions >=6.1. It turns out they all wrap at 88 characters.

Here is the docstrings that I have changed for testing:

    lakes : str or list                                                         
        *fill*\ [**+l**\|\ **+r**].                                             
        Set the shade, color, or pattern for lakes and river-lakes. The default is the fill chosen for wet areas set by the ``water``
        parameter. Optionally, specify separate fills by appending              
        **+l** for lakes or **+r** for river-lakes, and passing multiple        
        strings in a list. 

Here is how the long line is wrapped in Jupyter Notebook v6.1.6:
Screenshot from 2023-12-22 20-32-31
The word fill starts at exactly column 89, so it's clear that Notebook wraps at 88 for notebook>=6.1.

Since Notebook v6.1.6 was released three years ago on Dec, 24, 2020, I think it's OK to assume that users are using notebook>=6.1, and then it's safe to set the length limit to 88-characters.

@seisman seisman added discussions Need more discussion before taking further actions and removed question Further information is requested labels Dec 22, 2023
@weiji14
Copy link
Member

weiji14 commented Dec 25, 2023

I'm ok with moving to 88-characters, if only to simplify the linter configuration (e.g. with #2909). But I'm not keen on re-wrapping all the docstrings from 79 to 88 characters and making lots of big diffs. We can enforce a line-length of 88, but only apply it for newly written documentation perhaps?

@seisman
Copy link
Member Author

seisman commented Dec 25, 2023

We can enforce a line-length of 88, but only apply it for newly written documentation perhaps?

I don't think we can. The line length of docstrings are controlled by

pygmt/pyproject.toml

Lines 86 to 87 in 013014b

wrap-summaries = 79
wrap-descriptions = 79

If we change them to 88, all docstrings will be reformatted.

@weiji14
Copy link
Member

weiji14 commented Dec 25, 2023

Well, as long as it's automated by ruff, that should be ok? Could configure the setting in pyproject.toml, and then call /format in a PR to see how big the diff is 🙂.

@seisman
Copy link
Member Author

seisman commented Dec 25, 2023

Well, as long as it's automated by ruff, that should be ok?

There must be some misunderstandings here. Currently, the docstrings are formatted by docformatter and the code snippets in docstrings (i.e., doctests) are formatted by blackdoc.

As in #2909, blackdoc will be replaced by ruff, but docstrings are still formatted by docformatter, unless we enable ruff's pydocstyle (D) rules, which is close to docformatter (astral-sh/ruff#1335).

@weiji14
Copy link
Member

weiji14 commented Dec 25, 2023

Well, as long as it's automated by ruff, that should be ok?

There must be some misunderstandings here. Currently, the docstrings are formatted by docformatter and the code snippets in docstrings (i.e., doctests) are formatted by blackdoc.

As in #2909, blackdoc will be replaced by ruff, but docstrings are still formatted by docformatter, unless we enable ruff's pydocstyle (D) rules, which is close to docformatter (astral-sh/ruff#1335).

Ah yes, we're talking about the docstrings here, so docformatter. I just tried changing the settings to wrap-summaries = 88 and wrap-descriptions = 88, and also need to set tool.ruff.lint.pycodestyle - max-doc-length = 88. There were 77 files that were modified. But it seems like only the summaries were re-wrapped to 88 line-lengths, while the descriptions below stayed the same at 79 characters? I was expecting the Parameters and other sections to be wrapped too, but it looks like the diff will be smaller than expected (which is good).

@seisman
Copy link
Member Author

seisman commented Dec 25, 2023

But it seems like only the summaries were re-wrapped to 88 line-lengths, while the descriptions below stayed the same at 79 characters? I was expecting the Parameters and other sections to be wrapped too

It's a known issue https://docformatter.readthedocs.io/en/latest/faq.html.

@seisman seisman added this to the 0.11.0 milestone Dec 27, 2023
@seisman seisman added maintenance Boring but important stuff for the core devs and removed discussions Need more discussion before taking further actions labels Dec 27, 2023
@seisman seisman changed the title Rethink the line length limit of docstrings Change the line length limit of docstrings to 88 characters Dec 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
maintenance Boring but important stuff for the core devs
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants