Skip to content

Commit 4f55d60

Browse files
committed
MAINT: deprecate validCap, validJoin
1 parent 2b055a0 commit 4f55d60

File tree

6 files changed

+84
-32
lines changed

6 files changed

+84
-32
lines changed
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Line2D and Patch no longer duplicate ``validJoin`` and ``validCap``
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
Validation of joinstyle and capstyles is now centralized in ``rcsetup``.

lib/matplotlib/_api/deprecation.py

+37-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,40 @@
1616
import warnings
1717

1818

19+
class _classproperty:
20+
"""
21+
Like `property`, but also triggers on access via the class, and it is the
22+
*class* that's passed as argument.
23+
24+
Examples
25+
--------
26+
::
27+
28+
class C:
29+
@_classproperty
30+
def foo(cls):
31+
return cls.__name__
32+
33+
assert C.foo == "C"
34+
"""
35+
36+
def __init__(self, fget, fset=None, fdel=None, doc=None):
37+
self._fget = fget
38+
if fset is not None or fdel is not None:
39+
raise ValueError('_classproperty only implements fget.')
40+
self.fset = fset
41+
self.fdel = fdel
42+
# docs are ignored for now
43+
self._doc = doc
44+
45+
def __get__(self, instance, owner):
46+
return self._fget(owner)
47+
48+
@property
49+
def fget(self):
50+
return self._fget
51+
52+
1953
class MatplotlibDeprecationWarning(UserWarning):
2054
"""
2155
A class for issuing deprecation warnings for Matplotlib users.
@@ -201,15 +235,15 @@ def finalize(wrapper, new_doc):
201235
obj.__init__ = functools.wraps(obj.__init__)(wrapper)
202236
return obj
203237

204-
elif isinstance(obj, property):
238+
elif isinstance(obj, (property, _classproperty)):
205239
obj_type = "attribute"
206240
func = None
207241
name = name or obj.fget.__name__
208242
old_doc = obj.__doc__
209243

210-
class _deprecated_property(property):
244+
class _deprecated_property(type(obj)):
211245
def __get__(self, instance, owner):
212-
if instance is not None:
246+
if instance is not None or owner is not None:
213247
emit_warning()
214248
return super().__get__(instance, owner)
215249

lib/matplotlib/cbook/__init__.py

+1-25
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
_rename_parameter, _delete_parameter, _make_keyword_only,
3636
_deprecate_method_override, _deprecate_privatize_attribute,
3737
_suppress_matplotlib_deprecation_warning,
38-
MatplotlibDeprecationWarning, mplDeprecation)
38+
MatplotlibDeprecationWarning, mplDeprecation, _classproperty)
3939

4040

4141
def _get_running_interactive_framework():
@@ -2262,30 +2262,6 @@ def type_name(tp):
22622262
type_name(type(v))))
22632263

22642264

2265-
class _classproperty:
2266-
"""
2267-
Like `property`, but also triggers on access via the class, and it is the
2268-
*class* that's passed as argument.
2269-
2270-
Examples
2271-
--------
2272-
::
2273-
2274-
class C:
2275-
@classproperty
2276-
def foo(cls):
2277-
return cls.__name__
2278-
2279-
assert C.foo == "C"
2280-
"""
2281-
2282-
def __init__(self, fget):
2283-
self._fget = fget
2284-
2285-
def __get__(self, instance, owner):
2286-
return self._fget(owner)
2287-
2288-
22892265
def _backend_module_name(name):
22902266
"""
22912267
Convert a backend name (either a standard backend -- "Agg", "TkAgg", ... --

lib/matplotlib/lines.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import matplotlib as mpl
1313
from . import _api, artist, cbook, colors as mcolors, docstring, rcParams
14+
from ._api.deprecation import deprecated, _classproperty
1415
from .artist import Artist, allow_rasterization
1516
from .cbook import (
1617
_to_unmasked_float_array, ls_mapper, ls_mapper_r, STEP_LOOKUP_MAP)
@@ -251,8 +252,16 @@ class Line2D(Artist):
251252
fillStyles = MarkerStyle.fillstyles
252253

253254
zorder = 2
254-
validCap = ('butt', 'round', 'projecting')
255-
validJoin = ('miter', 'round', 'bevel')
255+
256+
@deprecated("3.4")
257+
@_classproperty
258+
def validCap(cls):
259+
return ('butt', 'round', 'projecting')
260+
261+
@deprecated("3.4")
262+
@_classproperty
263+
def validJoin(cls):
264+
return ('miter', 'round', 'bevel')
256265

257266
def __str__(self):
258267
if self._label != "":

lib/matplotlib/patches.py

+16-2
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
from numbers import Number
66
import textwrap
77
from collections import namedtuple
8+
import warnings
89

910
import numpy as np
1011

1112
import matplotlib as mpl
1213
from . import (_api, artist, cbook, colors, docstring, hatch as mhatch,
1314
lines as mlines, transforms)
15+
from ._api.deprecation import deprecated, _classproperty
1416
from .bezier import (
1517
NonIntersectingPathException, get_cos_sin, get_intersection,
1618
get_parallels, inside_circle, make_wedged_bezier2,
@@ -33,8 +35,20 @@ class Patch(artist.Artist):
3335
are *None*, they default to their rc params setting.
3436
"""
3537
zorder = 1
36-
validCap = mlines.Line2D.validCap
37-
validJoin = mlines.Line2D.validJoin
38+
39+
@deprecated("3.4")
40+
@_classproperty
41+
def validCap(cls):
42+
with warnings.catch_warnings():
43+
cbook._suppress_matplotlib_deprecation_warning()
44+
return mlines.Line2D.validCap
45+
46+
@deprecated("3.4")
47+
@_classproperty
48+
def validJoin(cls):
49+
with warnings.catch_warnings():
50+
cbook._suppress_matplotlib_deprecation_warning()
51+
return mlines.Line2D.validJoin
3852

3953
# Whether to draw an edge by default. Set on a
4054
# subclass-by-subclass basis.

lib/matplotlib/tests/test_api.py

+16
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
import pytest
55

66
from matplotlib import _api
7+
from matplotlib.cbook import (
8+
_classproperty, MatplotlibDeprecationWarning)
9+
from matplotlib._api.deprecation import deprecated
710

811

912
@pytest.mark.parametrize('target,test_shape',
@@ -19,3 +22,16 @@ def test_check_shape(target, test_shape):
1922
data = np.zeros(test_shape)
2023
with pytest.raises(ValueError, match=error_pattern):
2124
_api.check_shape(target, aardvark=data)
25+
26+
27+
def test_classproperty_deprecation():
28+
class A:
29+
@deprecated("0.0.0")
30+
@_classproperty
31+
def f(cls):
32+
pass
33+
with pytest.warns(MatplotlibDeprecationWarning):
34+
A.f
35+
with pytest.warns(MatplotlibDeprecationWarning):
36+
a = A()
37+
a.f

0 commit comments

Comments
 (0)