8000 MNT: Replace _docstring.Substitution by _docstring.format · matplotlib/matplotlib@e3dc213 · GitHub
[go: up one dir, main page]

Skip to content

Commit e3dc213

Browse files
committed
MNT: Replace _docstring.Substitution by _docstring.format
Making the decorator a function is simpler than a class. Behavior is unchanged.
1 parent 62f6bcd commit e3dc213

File tree

8 files changed

+45
-45
lines changed

8 files changed

+45
-45
lines changed

lib/matplotlib/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,7 @@ def gen_candidates():
647647
_deprecated_remain_as_none = {}
648648

649649

650-
@_docstring.Substitution(
650+
@_docstring.format(
651651
"\n".join(map("- {}".format, sorted(rcsetup._validators, key=str.lower)))
652652
)
653653
class RcParams(MutableMapping, dict):

lib/matplotlib/_docstring.py

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,43 +31,47 @@ def decorator(func):
3131
return decorator
3232

3333

34-
class Substitution:
34+
def format(*args, **kwargs):
3535
"""
3636
A decorator that performs %-substitution on an object's docstring.
3737
3838
This decorator should be robust even if ``obj.__doc__`` is None (for
3939
example, if -OO was passed to the interpreter).
4040
41-
Usage: construct a docstring.Substitution with a sequence or dictionary
42-
suitable for performing substitution; then decorate a suitable function
43-
with the constructed object, e.g.::
41+
You can pass either positional parameters, which will replace ``%s``
42+
in the docstring. Or alternatively pass keywords, which will replace
43+
named placeholders like ``%(name)s`` in the docstring.
4444
45-
sub_author_name = Substitution(author='Jason')
46-
47-
@sub_author_name
48-
def some_function(x):
49-
"%(author)s wrote this function"
50-
51-
# note that some_function.__doc__ is now "Jason wrote this function"
45+
Examples
46+
--------
47+
Inject dynamic information into the docstring. Here we replace
48+
`%s` with a formatted list.
5249
53-
One can also use positional arguments::
50+
@_docstring.format(
51+
"\n".join(map("- {}".format, sorted(STYLE_BLACKLIST, key=str.lower)))
52+
)
53+
def use(style):
54+
'''
55+
Use Matplotlib style settings from a style specification.
5456
55-
sub_first_last_names = Substitution('Edgar Allen', 'Poe')
57+
The following `.rcParams` are not related to style and will be ignored if
58+
found in a style specification:
5659
57-
@sub_first_last_names
58-
def some_function(x):
59-
"%s %s wrote the Raven"
60+
%s
61+
'''
6062
"""
61-
def __init__(self, *args, **kwargs):
62-
if args and kwargs:
63-
raise TypeError("Only positional or keyword args are allowed")
64-
self.params = args or kwargs
65-
66-
def __call__(self, func):
63+
if args and kwargs:
64+
raise ValueError(
65+
"_docstring.format() can only take positional or keyword arguments, "
66+
"not both")
67+
def decorator(func):
6768
if func.__doc__:
68-
func.__doc__ = inspect.cleandoc(func.__doc__) % self.params
69+
params = args or kwargs
70+
func.__doc__ = inspect.cleandoc(func.__doc__) % params
6971
return func
7072

73+
return decorator
74+
7175

7276
class _ArtistKwdocLoader(dict):
7377
def __missing__(self, key):

lib/matplotlib/_docstring.pyi

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,7 @@ _T = TypeVar('_T')
88
def kwarg_doc(text: str) -> Callable[[_T], _T]: ...
99

1010

11-
class Substitution:
12-
@overload
13-
def __init__(self, *args: str): ...
14-
@overload
15-
def __init__(self, **kwargs: str): ...
16-
def __call__(self, func: _T) -> _T: ...
17-
def update(self, *args, **kwargs): ... # type: ignore[no-untyped-def]
11+
def format(**kwargs: str) -> Callable[[_T], _T]: ...
1812

1913

2014
class _ArtistKwdocLoader(dict[str, str]):

lib/matplotlib/figure.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -379,8 +379,8 @@ def _suplabels(self, t, info, **kwargs):
379379
self.stale = True
380380
return suplab
381381

382-
@_docstring.Substitution(x0=0.5, y0=0.98, name='suptitle', ha='center',
383-
va='top', rc='title')
382+
@_docstring.format(x0=0.5, y0=0.98, name='suptitle', ha='center',
383+
va='top', rc='title')
384384
@_docstring.copy(_suplabels)
385385
def suptitle(self, t, **kwargs):
386386
# docstring from _suplabels...
@@ -394,8 +394,8 @@ def get_suptitle(self):
394394
text_obj = self._suptitle
395395
return "" if text_obj is None else text_obj.get_text()
396396

397-
@_docstring.Substitution(x0=0.5, y0=0.01, name='supxlabel', ha='center',
398-
va='bottom', rc='label')
397+
@_docstring.format(x0=0.5, y0=0.01, name='supxlabel', ha='center',
398+
va='bottom', rc='label')
399399
@_docstring.copy(_suplabels)
400400
def supxlabel(self, t, **kwargs):
401401
# docstring from _suplabels...
@@ -409,8 +409,8 @@ def get_supxlabel(self):
409409
text_obj = self._supxlabel
410410
return "" if text_obj is None else text_obj.get_text()
411411

412-
@_docstring.Substitution(x0=0.02, y0=0.5, name='supylabel', ha='left',
413-
va='center', rc='label')
412+
@_docstring.format(x0=0.02, y0=0.5, name='supylabel', ha='left',
413+
va='center', rc='label')
414414
@_docstring.copy(_suplabels)
415415
def supylabel(self, t, **kwargs):
416416
# docstring from _suplabels...

lib/matplotlib/quiver.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ class Quiver(mcollections.PolyCollection):
462462

463463
_PIVOT_VALS = ('tail', 'middle', 'tip')
464464

465-
@_docstring.Substitution(_quiver_doc)
465+
@_docstring.format(_quiver_doc)
466466
def __init__(self, ax, *args,
467467
scale=None, headwidth=3, headlength=5, headaxislength=4.5,
468468
minshaft=1, minlength=1, units='width', scale_units=None,

lib/matplotlib/style/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
'docstring.hardcopy', 'date.epoch'}
4040

4141

42-
@_docstring.Substitution(
42+
@_docstring.format(
4343
"\n".join(map("- {}".format, sorted(STYLE_BLACKLIST, key=str.lower)))
4444
)
4545
def use(style):

lib/matplotlib/tri/_tricontour.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ def _contour_args(self, args, kwargs):
217217
it is taken from :rc:`lines.antialiased`.""" % _docstring.interpd.params)
218218

219219

220-
@_docstring.Substitution(func='tricontour', type='lines')
220+
@_docstring.format(func='tricontour', type='lines')
221221
@_docstring.dedent_interpd
222222
def tricontour(ax, *args, **kwargs):
223223
"""
@@ -246,7 +246,7 @@ def tricontour(ax, *args, **kwargs):
246246
return TriContourSet(ax, *args, **kwargs)
247247

248248

249-
@_docstring.Substitution(func='tricontourf', type='regions')
249+
@_docstring.format(func='tricontourf', type='regions')
250250
@_docstring.dedent_interpd
251251
def tricontourf(ax, *args, **kwargs):
252252
"""

lib/matplotlib/widgets.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3122,8 +3122,9 @@ def onselect(eclick: MouseEvent, erelease: MouseEvent)
31223122
"""
31233123

31243124

3125-
@_docstring.Substitution(_RECTANGLESELECTOR_PARAMETERS_DOCSTRING.replace(
3126-
'__ARTIST_NAME__', 'rectangle'))
3125+
@_docstring.format(
3126+
_RECTANGLESELECTOR_PARAMETERS_DOCSTRING.replace('__ARTIST_NAME__', 'rectangle')
3127+
)
31273128
class RectangleSelector(_SelectorWidget):
31283129
"""
31293130
Select a rectangular region of an Axes.
@@ -3608,8 +3609,9 @@ def geometry(self):
36083609
return np.array(self._selection_artist.get_data())
36093610

36103611

3611-
@_docstring.Substitution(_RECTANGLESELECTOR_PARAMETERS_DOCSTRING.replace(
3612-
'__ARTIST_NAME__', 'ellipse'))
3612+
@_docstring.format(
3613+
_RECTANGLESELECTOR_PARAMETERS_DOCSTRING.replace('__ARTIST_NAME__', 'ellipse')
3614+
)
36133615
class EllipseSelector(RectangleSelector):
36143616
"""
36153617
Select an elliptical region of an Axes.

0 commit comments

Comments
 (0)
0