Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 98534b6

Browse files
committed
Use __set_name__ for better wrapping.
1 parent 73e44cc commit 98534b6

File tree

2 files changed

+40
-24
lines changed

2 files changed

+40
-24
lines changed

lib/matplotlib/axes/_base.py

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from collections import OrderedDict
22
from contextlib import ExitStack
3-
import functools
43
import inspect
54
import itertools
65
import logging
@@ -31,42 +30,59 @@
3130
_log = logging.getLogger(__name__)
3231

3332

34-
def _axis_method_wrapper(attr_name, method_name, *, doc_sub=None):
33+
class _axis_method_wrapper:
3534
"""
3635
Helper to generate Axes methods wrapping Axis methods.
3736
3837
After ::
3938
4039
get_foo = _axis_method_wrapper("xaxis", "get_bar")
4140
42-
``get_foo`` is a method that forwards it arguments to the ``get_bar``
43-
method of the ``xaxis`` attribute, and gets its signature and docstring
44-
from ``Axis.get_bar``.
41+
(in the body of a class) ``get_foo`` is a method that forwards it arguments
42+
to the ``get_bar`` method of the ``xaxis`` attribute, and gets its
43+
signature and docstring from ``Axis.get_bar``.
4544
4645
The docstring of ``get_foo`` is built by replacing "this Axis" by "the
4746
{attr_name}" ("the xaxis", "the yaxis") in the wrapped method's docstring;
4847
additional replacements can by given in *doc_sub*. The docstring is also
4948
dedented to simplify further manipulations.
5049
"""
5150

52-
method = getattr(maxis.Axis, method_name)
53-
get_method = attrgetter(f"{attr_name}.{method_name}")
54-
55-
@functools.wraps(method)
56-
def wrapper(self, *args, **kwargs):
57-
return get_method(self)(*args, **kwargs)
58-
59-
doc = wrapper.__doc__
60-
if doc:
61-
doc_sub = {"this Axis": f"the {attr_name}", **(doc_sub or {})}
62-
for k, v in doc_sub.items():
63-
assert k in doc, \
64-
(f"The docstring of wrapped Axis method {method_name!r} must "
65-
f"contain {k!r} as a substring.")
66-
doc = doc.replace(k, v)
67-
wrapper.__doc__ = inspect.cleandoc(doc)
68-
69-
return wrapper
51+
def __init__(self, attr_name, method_name, *, doc_sub=None):
52+
self.attr_name = attr_name
53+
self.method_name = method_name
54+
self.doc_sub = doc_sub
55+
56+
def __set_name__(self, owner, name):
57+
# This is called at the end of the class body as
58+
# ``self.__set_name__(cls, name_under_which_self_is_assigned)``; we
59+
# rely on that to give the wrapper the correct __name__/__qualname__.
60+
get_method = attrgetter(f"{self.attr_name}.{self.method_name}")
61+
62+
def wrapper(self, *args, **kwargs):
63+
return get_method(self)(*args, **kwargs)
64+
65+
wrapper.__module__ = owner.__module__
66+
wrapper.__name__ = name
67+
wrapper.__qualname__ = f"{owner.__qualname__}.{name}"
68+
# Manually copy the signature instead of using functools.wraps because
69+
# displaying the Axis method source when asking for the Axes method
70+
# source would be confusing.
71+
wrapped_method = getattr(maxis.Axis, self.method_name)
72+
wrapper.__signature__ = inspect.signature(wrapped_method)
73+
doc = wrapped_method.__doc__
74+
if doc:
75+
doc_sub = {"this Axis": f"the {self.attr_name}",
76+
**(self.doc_sub or {})}
77+
for k, v in doc_sub.items():
78+
assert k in doc, \
79+
(f"The definition of {wrapper.__qualname__} expected that "
80+
f"the docstring of Axis.{self.method_name} contains "
81+
f"{k!r} as a substring.")
82+
doc = doc.replace(k, v)
83+
wrapper.__doc__ = inspect.cleandoc(doc)
84+
85+
setattr(owner, name, wrapper)
7086

7187

7288
def _process_plot_format(fmt):

lib/mpl_toolkits/mplot3d/axes3d.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,7 @@ def set_zscale(self, value, **kwargs):
829829
get_zticklabels = _axis_method_wrapper("zaxis", "get_ticklabels")
830830
set_zticklabels = _axis_method_wrapper(
831831
"zaxis", "_set_ticklabels",
832-
doc_sub={"Axis.set_ticks": "Axes.set_zticks"})
832+
doc_sub={"Axis.set_ticks": "Axes3D.set_zticks"})
833833

834834
zaxis_date = _axis_method_wrapper("zaxis", "axis_date")
835835
if zaxis_date.__doc__:

0 commit comments

Comments
 (0)