8000 Merge pull request #22148 from oscargus/deprecatedocstring · matplotlib/matplotlib@223b2b1 · GitHub
[go: up one dir, main page]

Skip to content

Commit 223b2b1

Browse files
authored
Merge pull request #22148 from oscargus/deprecatedocstring
MNT: Deprecate `docstring`
2 parents f35a330 + 52df591 commit 223b2b1

37 files changed

+305
-300
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Module ``docstring`` deprecated
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
The module ``matplotlib.docstring`` is considered internal and public access
5+
is deprecated.

doc/api/prev_api_changes/api_changes_3.5.0/removals.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ The following class methods have been removed:
214214
- ``Colorbar.on_mappable_changed`` and ``Colorbar.update_bruteforce``; use
215215
``Colorbar.update_normal()`` instead
216216
- ``docstring.Substitution.from_params`` has been removed; directly assign to
217-
``params`` of `.Substitution` instead
217+
``params 57AE `` of ``docstring.Substitution`` instead
218218
- ``DraggableBase.artist_picker``; set the artist's picker instead
219219
- ``DraggableBase.on_motion_blit``; use `.DraggableBase.on_motion` instead
220220
- ``FigureCanvasGTK3._renderer_init``

doc/devel/documenting_mpl.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -684,14 +684,14 @@ are:
684684
2. as automated as possible so that as properties change, the docs
685685
are updated automatically.
686686

687-
The ``@docstring.interpd`` decorator implements this. Any function accepting
687+
The ``@_docstring.interpd`` decorator implements this. Any function accepting
688688
`.Line2D` pass-through ``kwargs``, e.g., `matplotlib.axes.Axes.plot`, can list
689689
a summary of the `.Line2D` properties, as follows:
690690

691691
.. code-block:: python
692692
693693
# in axes.py
694-
@docstring.interpd
694+
@_docstring.interpd
695695
def plot(self, *args, **kwargs):
696696
"""
697697
Some stuff omitted
@@ -726,7 +726,7 @@ gets interpolated into the docstring.
726726

727727
Note that this scheme does not work for decorating an Artist's ``__init__``, as
728728
the subclass and its properties are not defined yet at that point. Instead,
729-
``@docstring.interpd`` can be used to decorate the class itself -- at that
729+
``@_docstring.interpd`` can be used to decorate the class itself -- at that
730730
point, `.kwdoc` can list the properties and interpolate them into
731731
``__init__.__doc__``.
732732

lib/matplotlib/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@
106106

107107
# cbook must import matplotlib only within function
108108
# definitions, so it is safe to import from it here.
109-
from . import _api, _version, cbook, docstring, rcsetup
109+
from . import _api, _version, cbook, _docstring, rcsetup
110110
from matplotlib.cbook import sanitize_sequence
111111
from matplotlib._api import MatplotlibDeprecationWarning
112112
from matplotlib.rcsetup import validate_backend, cycler
@@ -593,7 +593,7 @@ def gen_candidates():
593593
_deprecated_remain_as_none = {}
594594

595595

596-
@docstring.Substitution(
596+
@_docstring.Substitution(
597597
"\n".join(map("- {}".format, sorted(rcsetup._validators, key=str.lower)))
598598
)
599599
class RcParams(MutableMapping, dict):

lib/matplotlib/_docstring.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import inspect
2+
3+
from . import _api
4+
5+
6+
class Substitution:
7+
"""
8+
A decorator that performs %-substitution on an object's docstring.
9+
10+
This decorator should be robust even if ``obj.__doc__`` is None (for
11+
example, if -OO was passed to the interpreter).
12+
13+
Usage: construct a docstring.Substitution with a sequence or dictionary
14+
suitable for performing substitution; then decorate a suitable function
15+
with the constructed object, e.g.::
16+
17+
sub_author_name = Substitution(author='Jason')
18+
19+
@sub_author_name
20+
def some_function(x):
21+
"%(author)s wrote this function"
22+
23+
# note that some_function.__doc__ is now "Jason wrote this function"
24+
25+
One can also use positional arguments::
26+
27+
sub_first_last_names = Substitution('Edgar Allen', 'Poe')
28+
29+
@sub_first_last_names
30+
def some_function(x):
31+
"%s %s wrote the Raven"
32+
"""
33+
def __init__(self, *args, **kwargs):
34+
if args and kwargs:
35+
raise TypeError("Only positional or keyword args are allowed")
36+
self.params = params = args or kwargs
37+
38+
def __call__(self, func):
39+
if func.__doc__:
40+
func.__doc__ = inspect.cleandoc(func.__doc__) % self.params
41+
return func
42+
43+
def update(self, *args, **kwargs):
44+
"""
45+
Update ``self.params`` (which must be a dict) with the supplied args.
46+
"""
47+
self.params.update(*args, **kwargs)
48+
49+
50+
class _ArtistKwdocLoader(dict):
51+
def __missing__(self, key):
52+
if not key.endswith(":kwdoc"):
53+
raise KeyError(key)
54+
name = key[:-len(":kwdoc")]
55+
from matplotlib.artist import Artist, kwdoc
56+
try:
57+
cls, = [cls for cls in _api.recursive_subclasses(Artist)
58+
if cls.__name__ == name]
59+
except ValueError as e:
60+
raise KeyError(key) from e
61+
return self.setdefault(key, kwdoc(cls))
62+
63+
64+
class _ArtistPropertiesSubstitution(Substitution):
65+
"""
66+
A `.Substitution` with two additional features:
67+
68+
- Substitutions of the form ``%(classname:kwdoc)s`` (ending with the
69+
literal ":kwdoc" suffix) trigger lookup of an Artist subclass with the
70+
given *classname*, and are substituted with the `.kwdoc` of that class.
71+
- Decorating a class triggers substitution both on the class docstring and
72+
on the class' ``__init__`` docstring (which is a commonly required
73+
pattern for Artist subclasses).
74+
"""
75+
76+
def __init__(self):
77+
self.params = _ArtistKwdocLoader()
78+
79+
def __call__(self, obj):
80+
super().__call__(obj)
81+
if isinstance(obj, type) and obj.__init__ != object.__init__:
82+
self(obj.__init__)
83+
return obj
84+
85+
86+
def copy(source):
87+
"""Copy a docstring from another source function (if present)."""
88+
def do_copy(target):
89+
if source.__doc__:
90+
target.__doc__ = source.__doc__
91+
return target
92+
return do_copy
93+
94+
95+
# Create a decorator that will house the various docstring snippets reused
96+
# throughout Matplotlib.
97+
dedent_interpd = interpd = _ArtistPropertiesSubstitution()

lib/matplotlib/_enums.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"""
1212

1313
from enum import Enum, auto
14-
from matplotlib import docstring
14+
from matplotlib import _docstring
1515

1616

1717
class _AutoStringNameEnum(Enum):
@@ -181,5 +181,5 @@ def demo():
181181
+ ", ".join([f"'{cs.name}'" for cs in CapStyle]) \
182182
+ "}"
183183

184-
docstring.interpd.update({'JoinStyle': JoinStyle.input_description,
184+
_docstring.interpd.update({'JoinStyle': JoinStyle.input_description,
185185
'CapStyle': CapStyle.input_description})

0 commit comments

Comments
 (0)
0