8000 Write data parameter docs as regular parameter not as note · matplotlib/matplotlib@ab8d409 · GitHub
[go: up one dir, main page]

Skip to content

Commit ab8d409

Browse files
committed
Write data parameter docs as regular parameter not as note
1 parent 906cae4 commit ab8d409

File tree

2 files changed

+124
-35
lines changed

2 files changed

+124
-35
lines changed

lib/matplotlib/__init__.py

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,20 +1247,11 @@ def _label_from_arg(y, default_name):
12471247
return None
12481248

12491249

1250-
_DATA_DOC_TITLE = """
1250+
_DATA_KWARG = """\
1251+
data : indexable object, optional
1252+
{data_kwarg_message}
12511253
1252-
Notes
1253-
-----
1254-
"""
1255-
1256-
_DATA_DOC_APPENDIX = """
1257-
1258-
.. note::
1259-
In addition to the above described arguments, this function can take
1260-
a *data* keyword argument. If such a *data* argument is given,
1261-
{replaced}
1262-
1263-
Objects passed as **data** must support item access (``data[s]``) and
1254+
Objects passed as *data* must support item access (``data[s]``) and
12641255
membership test (``s in data``).
12651256
"""
12661257

@@ -1287,17 +1278,45 @@ def _add_data_doc(docstring, replace_names):
12871278
or replace_names is not None and len(replace_names) == 0):
12881279
return docstring
12891280
docstring = inspect.cleandoc(docstring)
1290-
repl = (
1291-
(" every other argument can also be string ``s``, which is\n"
1281+
1282+
def find_insert_index(docstring):
1283+
# Try inserting before **kwargs docs
1284+
insert_index = docstring.find('\n**kwargs') + 1
1285+
if insert_index > 0:
1286+
return insert_index
1287+
# If **kwargs docs does not exist, insert as the last parameter.
1288+
# To do so, find the end of the parameters section:
1289+
# - find start of parameters section
1290+
# - find next section (defined by a line starting with '----'). This
1291+
# seems the most reliable way as the parameters section may be quite
1292+
# complex.
1293+
# - Go back to the previous empty line (A section title must be
1294+
# preceededby an emtpy line.
1295+
param_string = '\nParame 10000 ters\n----------\n'
1296+
i_params = docstring.find(param_string) + len(param_string)
1297+
i_next_heading = docstring.find('\n----', i_params)
1298+
if i_next_heading < 0:
1299+
return -1 # no next heading: append to end
1300+
insert_index = docstring.rfind('\n\n', i_params, i_next_heading) + 1
1301+
assert insert_index > 0
1302+
return insert_index
1303+
1304+
insert_index = find_insert_index(docstring)
1305+
data_kwarg_message = (
1306+
(" If given, all parameters also accept a string ``s``, which is\n"
12921307
" interpreted as ``data[s]`` (unless this raises an exception).")
12931308
if replace_names is None else
1294-
(" the following arguments can also be string ``s``, which is\n"
1295-
" interpreted as ``data[s]`` (unless this raises an exception):\n"
1309+
(" If given, the following parameters also accept a string ``s``,\n"
1310+
" which is interpreted as ``data[s]`` (unless this raises an\n"
1311+
" exception):\n"
12961312
" " + ", ".join(map("*{}*".format, replace_names))) + ".")
1297-
addendum = _DATA_DOC_APPENDIX.format(replaced=repl)
1298-
if _DATA_DOC_TITLE not in docstring:
1299-
addendum = _DATA_DOC_TITLE + addendum
1300-
return docstring + addendum
1313+
if insert_index == -1:
1314+
return (docstring + '\n'
1315+
+ _DATA_KWARG.format(data_kwarg_message=data_kwarg_message))
1316+
else:
1317+
return (docstring[:insert_index]
1318+
+ _DATA_KWARG.format(data_kwarg_message=data_kwarg_message)
1319+
+ docstring[insert_index:])
13011320

13021321

13031322
def _preprocess_data(func=None, *, replace_names=None, label_namer=None):

lib/matplotlib/tests/test_preprocess_data.py

Lines changed: 84 additions & 14 deletions
F313
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import numpy as np
44
import pytest
55

6-
from matplotlib import _preprocess_data
6+
from matplotlib import _add_data_doc, _preprocess_data
77
from matplotlib.axes import Axes
88
from matplotlib.testing.decorators import check_figures_equal
99

@@ -194,35 +194,105 @@ def func(ax, x, y, z=1):
194194
func(None, "a", "b", "z", "z", data=data)
195195

196196

197+
def test_add_data_doc_kwargs():
198+
"""Test that the data docs is inserted before **kwargs."""
199+
assert ("Data param should follow.\ndata : indexable object, optional" in
200+
_add_data_doc("""\
201+
Some function.
202+
203+
Parameters
204+
----------
205+
x
206+
Data param should follow.
207+
**kwargs
208+
Additional parameters.
209+
""", replace_names=['x']))
210+
211+
212+
def test_add_data_doc_after_params():
213+
"""
214+
Test that the data docs is inserted at the end of Parameters section
215+
that is followed by another section.
216+
"""
217+
assert ("Data param should follow.\ndata : indexable object, optional" in
218+
_add_data_doc("""\
219+
Some function.
220+
221+
Parameters
222+
----------
223+
x
224+
Data param should follow.
225+
226+
Returns
227+
-------
228+
someting
229+
""", replace_names=['x']))
230+
231+
232+
def test_add_data_doc_after_params_last():
233+
"""
234+
Test that the data docs is inserted at the end of Parameters section
235+
that is not followed by further docs.
236+
"""
237+
assert ("Data param should follow.\ndata : indexable object, optional" in
238+
_add_data_doc("""\
239+
Some function.
240+
241+
Parameters
242+
----------
243+
x
244+
Data param should follow.
245+
""", replace_names=['x']))
246+
247+
197248
def test_docstring_addition():
198249
@_preprocess_data()
199250
def funcy(ax, *args, **kwargs):
200-
"""Funcy does nothing"""
251+
"""
252+
Funcy does nothing.
253+
254+
Parameters
255+
----------
256+
**kwargs
257+
Text.
258+
"""
201259

202-
assert re.search(r"every other argument", funcy.__doc__)
203-
assert not re.search(r"the following arguments", funcy.__doc__)
260+
assert re.search(r"all parameters also accept a string", funcy.__doc__)
261+
assert not re.search(r"the following parameters", funcy.__doc__)
204262

205263
@_preprocess_data(replace_names=[])
206264
def funcy(ax, x, y, z, bar=None):
207265
"""Funcy does nothing"""
208266

209-
assert not re.search(r"every other argument", funcy.__doc__)
210-
assert not re.search(r"the following arguments", funcy.__doc__)
267+
assert not re.search(r"all parameters also accept a string", funcy.__doc__)
268+
assert not re.search(r"the following parameters", funcy.__doc__)
211269

212270
@_preprocess_data(replace_names=["bar"])
213271
def funcy(ax, x, y, z, bar=None):
214-
"""Funcy does nothing"""
215-
216-
assert not re.search(r"every other argument", funcy.__doc__)
217-
assert not re.search(r"the following arguments .*: \*bar\*\.",
272+
"""
273+
Funcy does nothing.
274+
275+
Parameters
276+
----------
277+
**kwargs
278+
Text.
279+
"""
280+
assert not re.search(r"all parameters also accept a string", funcy.__doc__)
281+
assert not re.search(r"the following parameters .*: \*bar\*\.",
218282
funcy.__doc__)
219283

220284
@_preprocess_data(replace_names=["x", "t"])
221285
def funcy(ax, x, y, z, t=None):
222-
"""Funcy does nothing"""
223-
224-
assert not re.search(r"every other argument", funcy.__doc__)
225-
assert not re.search(r"the following arguments .*: \*x\*, \*t\*\.",
286+
"""
287+
Funcy does nothing.
288+
289+
Parameters
290+
----------
291+
x, y, z
292+
Text.
293+
"""
294+
assert not re.search(r"all parameters also accept a string", funcy.__doc__)
295+
assert not re.search(r"the following parameters .*: \*x\*, \*t\*\.",
226296
funcy.__doc__)
227297

228298

0 commit comments

Comments
 (0)
0