Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit382ea55

Browse files
committed
Propose a less error-prone helper for module-level getattrs.
Apparently we always forget to generate the fallback AttributeError, sointroduce a helper to do so instead.The changes in `deprecation.py` are (a) so that one can correctlysuppress the inferred type when deprecating properties (the new check iscoherent with the `if isinstance(obj, type)` and other cases) and (b) tomake single-argument `__get__` work on deprecated properties(consistently with standard properties).
1 parent0a4a10c commit382ea55

File tree

8 files changed

+81
-69
lines changed

8 files changed

+81
-69
lines changed

‎lib/matplotlib/__init__.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -176,16 +176,14 @@ def _get_version():
176176
return_version.version
177177

178178

179-
@functools.lru_cache(None)
180-
def__getattr__(name):
181-
ifname=="__version__":
182-
return_get_version()
183-
elifname=="__version_info__":
184-
return_parse_to_version_info(__getattr__("__version__"))
185-
elifname=="URL_REGEX":# module-level deprecation.
186-
_api.warn_deprecated("3.5",name=name)
187-
returnre.compile(r'^http://|^https://|^ftp://|^file:')
188-
raiseAttributeError(f"module{__name__!r} has no attribute{name!r}")
179+
@_api.caching_module_getattr
180+
class__getattr__:
181+
__version__=property(lambdaself:_get_version())
182+
__version_info__=property(
183+
lambdaself:_parse_to_version_info(self.__version__))
184+
# module-level deprecations
185+
URL_REGEX=_api.deprecated("3.5",obj_type="")(property(
186+
lambdaself:re.compile(r'^http://|^https://|^ftp://|^file:')))
189187

190188

191189
def_check_versions():

‎lib/matplotlib/_api/__init__.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
1111
"""
1212

13+
importfunctools
1314
importitertools
1415
importre
1516
importsys
@@ -189,6 +190,41 @@ def check_getitem(_mapping, **kwargs):
189190
.format(v,k,', '.join(map(repr,mapping))))fromNone
190191

191192

193+
defcaching_module_getattr(cls):
194+
"""
195+
Helper decorator for implementing module-level ``__getattr__`` as a class.
196+
197+
This decorator must be used at the module toplevel as follows:
198+
199+
@caching_module_getattr
200+
class __getattr__: # The class *must* be named ``__getattr__``.
201+
@property # Only properties are taken into account.
202+
def name(self): ...
203+
204+
The ``__getattr__`` class will be replaced by a ``__getattr__``
205+
function such that trying to access ``name`` on the module will
206+
resolve the corresponding property (which may be decorated e.g. with
207+
``_api.deprecated`` for deprecating module globals). The properties are
208+
all implicitly cached. Moreover, a suitable AttributeError is generated
209+
and raised if no property with the given name exists.
210+
"""
211+
212+
assertcls.__name__=="__getattr__"
213+
# Don't accidentally export cls dunders.
214+
props= {name:propforname,propinvars(cls).items()
215+
ifisinstance(prop,property)}
216+
instance=cls()
217+
218+
@functools.lru_cache(None)
219+
def__getattr__(name):
220+
ifnameinprops:
221+
returnprops[name].__get__(instance)
222+
raiseAttributeError(
223+
f"module{cls.__module__!r} has no attribute{name!r}")
224+
225+
return__getattr__
226+
227+
192228
defselect_matching_signature(funcs,*args,**kwargs):
193229
"""
194230
Select and call the function that accepts ``*args, **kwargs``.

‎lib/matplotlib/_api/deprecation.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,13 +150,14 @@ def finalize(wrapper, new_doc):
150150
returnobj
151151

152152
elifisinstance(obj, (property,classproperty)):
153-
obj_type="attribute"
153+
ifobj_typeisNone:
154+
obj_type="attribute"
154155
func=None
155156
name=nameorobj.fget.__name__
156157
old_doc=obj.__doc__
157158

158159
class_deprecated_property(type(obj)):
159-
def__get__(self,instance,owner):
160+
def__get__(self,instance,owner=None):
160161
ifinstanceisnotNoneorownerisnotNone \
161162
andisinstance(self,classproperty):
162163
emit_warning()

‎lib/matplotlib/backends/backend_gtk3.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@
3737
Gtk.get_major_version(),Gtk.get_minor_version(),Gtk.get_micro_version())
3838

3939

40-
# module-level deprecations.
41-
@functools.lru_cache(None)
42-
def__getattr__(name):
43-
ifname=="cursord":
44-
_api.warn_deprecated("3.5",name=name)
40+
@_api.caching_module_getattr# module-level deprecations
41+
class__getattr__:
42+
@_api.deprecated("3.5",obj_type="")
43+
@property
44+
defcursord(self):
4545
try:
4646
new_cursor=functools.partial(
4747
Gdk.Cursor.new_from_name,Gdk.Display.get_default())
@@ -54,8 +54,6 @@ def __getattr__(name):
5454
}
5555
exceptTypeErrorasexc:
5656
return {}
57-
else:
58-
raiseAttributeError(f"module{__name__!r} has no attribute{name!r}")
5957

6058

6159
# Placeholder

‎lib/matplotlib/backends/backend_wx.py

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -41,25 +41,18 @@
4141
PIXELS_PER_INCH=75
4242

4343

44-
# module-level deprecations.
45-
@functools.lru_cache(None)
46-
def__getattr__(name):
47-
ifname=="IDLE_DELAY":
48-
_api.warn_deprecated("3.1",name=name)
49-
return5
50-
elifname=="cursord":
51-
_api.warn_deprecated("3.5",name=name)
52-
return {# deprecated in Matplotlib 3.5.
53-
cursors.MOVE:wx.CURSOR_HAND,
54-
cursors.HAND:wx.CURSOR_HAND,
55-
cursors.POINTER:wx.CURSOR_ARROW,
56-
cursors.SELECT_REGION:wx.CURSOR_CROSS,
57-
cursors.WAIT:wx.CURSOR_WAIT,
58-
cursors.RESIZE_HORIZONTAL:wx.CURSOR_SIZEWE,
59-
cursors.RESIZE_VERTICAL:wx.CURSOR_SIZENS,
60-
}
61-
else:
62-
raiseAttributeError(f"module{__name__!r} has no attribute{name!r}")
44+
@_api.caching_module_getattr# module-level deprecations
45+
class__getattr__:
46+
IDLE_DELAY=_api.deprecated("3.1",obj_type="")(property(lambdaself:5))
47+
cursord=_api.deprecated("3.5",obj_type="")(property(lambdaself: {
48+
cursors.MOVE:wx.CURSOR_HAND,
49+
cursors.HAND:wx.CURSOR_HAND,
50+
cursors.POINTER:wx.CURSOR_ARROW,
51+
cursors.SELECT_REGION:wx.CURSOR_CROSS,
52+
cursors.WAIT:wx.CURSOR_WAIT,
53+
cursors.RESIZE_HORIZONTAL:wx.CURSOR_SIZEWE,
54+
cursors.RESIZE_VERTICAL:wx.CURSOR_SIZENS,
55+
}))
6356

6457

6558
deferror_msg_wx(msg,parent=None):

‎lib/matplotlib/cm.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
"""
1717

1818
fromcollections.abcimportMapping,MutableMapping
19-
importfunctools
2019

2120
importnumpyasnp
2221
fromnumpyimportma
@@ -27,13 +26,11 @@
2726
frommatplotlib._cm_listedimportcmapsascmaps_listed
2827

2928

30-
# module-level deprecations.
31-
@functools.lru_cache(None)
32-
def__getattr__(name):
33-
ifname=="LUTSIZE":
34-
_api.warn_deprecated("3.5",name=name,
35-
alternative="rcParams['image.lut']")
36-
return_LUTSIZE
29+
@_api.caching_module_getattr# module-level deprecations
30+
class__getattr__:
31+
LUTSIZE=_api.deprecated(
32+
"3.5",obj_type="",alternative="rcParams['image.lut']")(
33+
property(lambdaself:_LUTSIZE))
3734

3835

3936
_LUTSIZE=mpl.rcParams['image.lut']

‎lib/matplotlib/colorbar.py

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
"""
1313

1414
importcopy
15-
importfunctools
1615
importlogging
1716
importtextwrap
1817

@@ -195,20 +194,14 @@
195194
_colormap_kw_doc))
196195

197196

198-
# module-level deprecations.
199-
@functools.lru_cache(None)
200-
def__getattr__(name):
201-
ifname=="colorbar_doc":
202-
_api.warn_deprecated("3.4",name=name)
203-
returndocstring.interpd.params["colorbar_doc"]
204-
elifname=="colormap_kw_doc":
205-
_api.warn_deprecated("3.4",name=name)
206-
return_colormap_kw_doc
207-
elifname=="make_axes_kw_doc":
208-
_api.warn_deprecated("3.4",name=name)
209-
return_make_axes_param_doc+_make_axes_other_param_doc
210-
else:
211-
raiseAttributeError(f"module{__name__!r} has no attribute{name!r}")
197+
@_api.caching_module_getattr# module-level deprecations
198+
class__getattr__:
199+
colorbar_doc=_api.deprecated("3.4",obj_type="")(property(
200+
lambdaself:docstring.interpd.params["colorbar_doc"]))
201+
colorbar_kw_doc=_api.deprecated("3.4",obj_type="")(property(
202+
lambdaself:_colormap_kw_doc))
203+
make_axes_kw_doc=_api.deprecated("3.4",obj_type="")(property(
204+
lambdaself:_make_axes_param_doc+_make_axes_other_param_doc))
212205

213206

214207
def_set_ticks_on_axis_warn(*args,**kw):

‎lib/matplotlib/style/core.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
"""
1313

1414
importcontextlib
15-
importfunctools
1615
importlogging
1716
importos
1817
frompathlibimportPath
@@ -27,13 +26,10 @@
2726
__all__= ['use','context','available','library','reload_library']
2827

2928

30-
# module-level deprecations.
31-
@functools.lru_cache(None)
32-
def__getattr__(name):
33-
ifname=="STYLE_FILE_PATTERN":
34-
_api.warn_deprecated("3.5",name=name)
35-
returnre.compile(r'([\S]+).%s$'%STYLE_EXTENSION)
36-
raiseAttributeError(f"module{__name__!r} has no attribute{name!r}")
29+
@_api.caching_module_getattr# module-level deprecations
30+
class__getattr__:
31+
STYLE_FILE_PATTERN=_api.deprecated("3.5",obj_type="")(property(
32+
lambdaself:re.compile(r'([\S]+).%s$'%STYLE_EXTENSION)))
3733

3834

3935
BASE_LIBRARY_PATH=os.path.join(mpl.get_data_path(),'stylelib')

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp