|
| 1 | +MEP10: Docstring consistency |
| 2 | +============================ |
| 3 | +.. contents:: |
| 4 | + :local: |
| 5 | + |
| 6 | +Status |
| 7 | +------ |
| 8 | + |
| 9 | +**Progress** |
| 10 | + |
| 11 | +Targeted for 1.3 |
| 12 | + |
| 13 | +Branches and Pull requests |
| 14 | +-------------------------- |
| 15 | + |
| 16 | +#1665 |
| 17 | +#1757 |
| 18 | +#1795 |
| 19 | + |
| 20 | +Abstract |
| 21 | +-------- |
| 22 | + |
| 23 | +matplotlib has a great deal of inconsistency between docstrings. This |
| 24 | +not only makes the docs harder to read, but it is harder on |
| 25 | +contributors, because they don't know which specifications to follow. |
| 26 | +There should be a clear docstring convention that is followed |
| 27 | +consistently. |
| 28 | + |
| 29 | +The organization of the API documentation is difficult to follow. |
| 30 | +Some pages, such as pyplot and axes, are enormous and hard to browse. |
| 31 | +There should instead be short summary tables that link to detailed |
| 32 | +documentation. In addition, some of the docstrings themselves are |
| 33 | +quite long and contain redundant information. |
| 34 | + |
| 35 | +Building the documentation takes a long time and uses a `make.py` |
| 36 | +script rather than a Makefile. |
| 37 | + |
| 38 | +Detailed description |
| 39 | +-------------------- |
| 40 | + |
| 41 | +There are number of new tools and conventions available since |
| 42 | +matplotlib started using Sphinx that make life easier. The following |
| 43 | +is a list of proposed changes to docstrings, most of which involve |
| 44 | +these new features. |
| 45 | + |
| 46 | +Numpy docstring format |
| 47 | +'''''''''''''''''''''' |
| 48 | + |
| 49 | +`Numpy docstring format |
| 50 | +<https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt>`_: |
| 51 | +This format divides the docstring into clear sections, each having |
| 52 | +different parsing rules that make the docstring easy to read both as |
| 53 | +raw text and as HTML. We could consider alternatives, or invent our |
| 54 | +own, but this is a strong choice, as it's well used and understood in |
| 55 | +the Numpy/Scipy community. |
| 56 | + |
| 57 | +Cross references |
| 58 | +'''''''''''''''' |
| 59 | + |
| 60 | +Most of the docstrings in matplotlib use explicit "roles" when linking |
| 61 | +to other items, for example: ``:func:`myfunction```. As of Sphinx |
| 62 | +0.4, there is a "default_role" that can be set to "obj", which will |
| 63 | +polymorphically link to a Python object of any type. This allows one |
| 64 | +to write ```myfunction``` instead. This makes docstrings much easier |
| 65 | +to read and edit as raw text. Additionally, Sphinx allows for setting |
| 66 | +a current module, so links like ```~matplotlib.axes.Axes.set_xlim``` |
| 67 | +could be written as ```~axes.Axes.set_xlim```. |
| 68 | + |
| 69 | +Overriding signatures |
| 70 | +''''''''''''''''''''' |
| 71 | + |
| 72 | +Many methods in matplotlib use the ``*args`` and ``**kwargs`` syntax |
| 73 | +to dynamically handle the keyword arguments that are accepted by the |
| 74 | +function, or to delegate on to another function. This, however, is |
| 75 | +often not useful as a signature in the documentation. For this |
| 76 | +reason, many matplotlib methods include something like:: |
| 77 | + |
| 78 | + def annotate(self, *args, **kwargs): |
| 79 | + """ |
| 80 | + Create an annotation: a piece of text referring to a data |
| 81 | + point. |
| 82 | + |
| 83 | + Call signature:: |
| 84 | + |
| 85 | + annotate(s, xy, xytext=None, xycoords='data', |
| 86 | + textcoords='data', arrowprops=None, **kwargs) |
| 87 | + """ |
| 88 | + |
| 89 | +This can't be parsed by Sphinx, and is rather verbose in raw text. As |
| 90 | +of Sphinx 1.1, if the `autodoc_docstring_signature` config value is |
| 91 | +set to True, Sphinx will extract a replacement signature from the |
| 92 | +first line of the docstring, allowing this:: |
| 93 | + |
| 94 | + def annotate(self, *args, **kwargs): |
| 95 | + """ |
| 96 | + annotate(s, xy, xytext=None, xycoords='data', |
| 97 | + textcoords='data', arrowprops=None, **kwargs) |
| 98 | + |
| 99 | + Create an annotation: a piece of text referring to a data |
| 100 | + point. |
| 101 | + """ |
| 102 | + |
| 103 | +The explicit signature will replace the actual Python one in the |
| 104 | +generated documentation. |
| 105 | + |
| 106 | +Linking rather than duplicating |
| 107 | +''''''''''''''''''''''''''''''' |
| 108 | + |
| 109 | +Many of the docstrings include long lists of accepted keywords by |
| 110 | +interpolating things into the docstring at load time. This makes the |
| 111 | +docstrings very long. Also, since these tables are the same across |
| 112 | +many docstrings, it inserts a lot of redundant information in the docs |
| 113 | +-- particularly a problem in the printed version. |
| 114 | + |
| 115 | +These tables should be moved to docstrings on functions whose only |
| 116 | +purpose is for help. The docstrings that refer to these tables should |
| 117 | +link to them, rather than including them verbatim. |
| 118 | + |
| 119 | +autosummary extension |
| 120 | +''''''''''''''''''''' |
| 121 | + |
| 122 | +The Sphinx autosummary extension should be used to generate summary |
| 123 | +tables, that link to separate pages of documentation. Some classes |
| 124 | +that have many methods (e.g. `Axes.axes`) should be documented with |
| 125 | +one method per page, whereas smaller classes should have all of their |
| 126 | +methods together. |
| 127 | + |
| 128 | +Examples linking to relevant documentation |
| 129 | +'''''''''''''''''''''''''''''''''''''''''' |
| 130 | + |
| 131 | +The examples, while helpful at illustrating how to use a feature, do |
| 132 | +not link back to the relevant docstrings. This could be addressed by |
| 133 | +adding module-level docstrings to the examples, and then including |
| 134 | +that docstring in the parsed content on the example page. These |
| 135 | +docstrings could easily include references to any other part of the |
| 136 | +documentation. |
| 137 | + |
| 138 | +Documentation using help() vs a browser |
| 139 | +'''''''''''''''''''''' |
| 140 | + |
| 141 | +Using Sphinx markup in the source allows for good-looking docs in your |
| 142 | +browser, but the markup also makes the raw text returned using help() |
| 143 | +look terrible. One of the aims of improving the docstrings should be |
| 144 | +to make both methods of accessing the docs look good. |
| 145 | + |
| 146 | +Implementation |
| 147 | +-------------- |
| 148 | + |
| 149 | +1. The numpydoc extensions should be turned on for matplotlib. There |
| 150 | + is an important question as to whether these should be included in |
| 151 | + the matplotlib source tree, or used as a dependency. Installing |
| 152 | + Numpy is not sufficient to get the numpydoc extensions -- it's a |
| 153 | + separate install procedure. In any case, to the extent that they |
| 154 | + require customization for our needs, we should endeavor to submit |
| 155 | + those changes upstream and not fork them. |
| 156 | + |
| 157 | +2. Manually go through all of the docstrings and update them to the |
| 158 | + new format and conventions. Updating the cross references (from |
| 159 | + ```:func:`myfunc``` to ```func```) may be able to be |
| 160 | + semi-automated. This is a lot of busy work, and perhaps this labor |
| 161 | + should be divided on a per-module basis so no single developer is |
| 162 | + over-burdened by it. |
| 163 | + |
| 164 | +3. Reorganize the API docs using autosummary and `sphinx-autogen`. |
| 165 | + This should hopefully have minimal impact on the narrative |
| 166 | + documentation. |
| 167 | + |
| 168 | +4. Modify the example page generator (`gen_rst.py`) so that it |
| 169 | + extracts the module docstring from the example and includes it in a |
| 170 | + non-literal part of the example page. |
| 171 | + |
| 172 | +5. Use `sphinx-quickstart` to generate a new-style Sphinx Makefile. |
| 173 | + The following features in the current `make.py` will have to be |
| 174 | + addressed in some other way: |
| 175 | + |
| 176 | + - Copying of some static content |
| 177 | + |
| 178 | + - Specifying a "small" build (only low-resolution PNG files for examples) |
| 179 | + |
| 180 | +Steps 1, 2, and 3 are interdependent. 4 and 5 may be done |
| 181 | +independently, though 5 has some dependency on 3. |
| 182 | + |
| 183 | +Backward compatibility |
| 184 | +---------------------- |
| 185 | + |
| 186 | +As this mainly involves docstrings, there should be minimal impact on |
| 187 | +backward compatibility. |
| 188 | + |
| 189 | +Alternatives |
| 190 | +------------ |
| 191 | + |
| 192 | +None yet discussed. |
0 commit comments