Skip to content

Commit 3396bec

Browse files
committed
Remove 'in' from removal substitution for deprecation messages
Ever since matplotlib#27702, the removal will always be a version, and not "two minor/meso releases later". This tends to get messed up by people writing custom `message` arguments, and since there's no reason to add the "to" there instead of in the message any more, move it to the message. Also, fix the autogenerated message to follow what the docstring says (Falsy `removal` leaves out the removal date.)
1 parent 613c9c9 commit 3396bec

File tree

7 files changed

+57
-27
lines changed

7 files changed

+57
-27
lines changed

lib/matplotlib/_api/deprecation.py

+16-21
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,20 @@ def _generate_deprecation_warning(
2626
addendum='', *, removal=''):
2727
if pending:
2828
if removal:
29-
raise ValueError(
30-
"A pending deprecation cannot have a scheduled removal")
31-
else:
32-
if not removal:
33-
macro, meso, *_ = since.split('.')
34-
removal = f'{macro}.{int(meso) + 2}'
35-
removal = f"in {removal}"
29+
raise ValueError("A pending deprecation cannot have a scheduled removal")
30+
elif removal == '':
31+
macro, meso, *_ = since.split('.')
32+
removal = f'{macro}.{int(meso) + 2}'
3633
if not message:
3734
message = (
38-
("The %(name)s %(obj_type)s" if obj_type else "%(name)s")
39-
+ (" will be deprecated in a future version"
40-
if pending else
41-
" was deprecated in Matplotlib %(since)s and will be removed %(removal)s"
42-
)
43-
+ "."
44-
+ (" Use %(alternative)s instead." if alternative else "")
45-
+ (" %(addendum)s" if addendum else ""))
46-
warning_cls = (PendingDeprecationWarning if pending
47-
else MatplotlibDeprecationWarning)
35+
("The %(name)s %(obj_type)s" if obj_type else "%(name)s") +
36+
(" will be deprecated in a future version" if pending else
37+
(" was deprecated in Matplotlib %(since)s" +
38+
(" and will be removed in %(removal)s" if removal else ""))) +
39+
"." +
40+
(" Use %(alternative)s instead." if alternative else "") +
41+
(" %(addendum)s" if addendum else ""))
42+
warning_cls = PendingDeprecationWarning if pending else MatplotlibDeprecationWarning
4843
return warning_cls(message % dict(
4944
func=name, name=name, obj_type=obj_type, since=since, removal=removal,
5045
alternative=alternative, addendum=addendum))
@@ -295,7 +290,7 @@ def wrapper(*args, **kwargs):
295290
warn_deprecated(
296291
since, message=f"The {old!r} parameter of {func.__name__}() "
297292
f"has been renamed {new!r} since Matplotlib {since}; support "
298-
f"for the old name will be dropped %(removal)s.")
293+
f"for the old name will be dropped in %(removal)s.")
299294
kwargs[new] = kwargs.pop(old)
300295
return func(*args, **kwargs)
301296

@@ -390,12 +385,12 @@ def wrapper(*inner_args, **inner_kwargs):
390385
warn_deprecated(
391386
since, message=f"Additional positional arguments to "
392387
f"{func.__name__}() are deprecated since %(since)s and "
393-
f"support for them will be removed %(removal)s.")
388+
f"support for them will be removed in %(removal)s.")
394389
elif is_varkwargs and arguments.get(name):
395390
warn_deprecated(
396391
since, message=f"Additional keyword arguments to "
397392
f"{func.__name__}() are deprecated since %(since)s and "
398-
f"support for them will be removed %(removal)s.")
393+
f"support for them will be removed in %(removal)s.")
399394
# We cannot just check `name not in arguments` because the pyplot
400395
# wrappers always pass all arguments explicitly.
401396
elif any(name in d and d[name] != _deprecated_parameter
@@ -453,7 +448,7 @@ def wrapper(*args, **kwargs):
453448
warn_deprecated(
454449
since, message="Passing the %(name)s %(obj_type)s "
455450
"positionally is deprecated since Matplotlib %(since)s; the "
456-
"parameter will become keyword-only %(removal)s.",
451+
"parameter will become keyword-only in %(removal)s.",
457452
name=name, obj_type=f"parameter of {func.__name__}()")
458453
return func(*args, **kwargs)
459454

lib/matplotlib/_api/deprecation.pyi

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from collections.abc import Callable
22
import contextlib
3-
from typing import Any, ParamSpec, TypedDict, TypeVar, overload
3+
from typing import Any, Literal, ParamSpec, TypedDict, TypeVar, overload
44
from typing_extensions import (
55
Unpack, # < Py 3.11
66
)
@@ -17,7 +17,7 @@ class DeprecationKwargs(TypedDict, total=False):
1717
pending: bool
1818
obj_type: str
1919
addendum: str
20-
removal: str
20+
removal: str | Literal[False]
2121

2222
class NamedDeprecationKwargs(DeprecationKwargs, total=False):
2323
name: str

lib/matplotlib/backend_bases.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3333,7 +3333,7 @@ def _get_image_filename(self, tool):
33333333
_api.warn_deprecated(
33343334
"3.9", message=f"Loading icon {tool.image!r} from the current "
33353335
"directory or from Matplotlib's image directory. This behavior "
3336-
"is deprecated since %(since)s and will be removed %(removal)s; "
3336+
"is deprecated since %(since)s and will be removed in %(removal)s; "
33373337
"Tool.image should be set to a path relative to the Tool's source "
33383338
"file, or to an absolute path.")
33393339
return os.path.abspath(fname)

lib/matplotlib/hatch.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ def _validate_hatch_pattern(hatch):
192192
message=f'hatch must consist of a string of "{valid}" or '
193193
'None, but found the following invalid values '
194194
f'"{invalids}". Passing invalid values is deprecated '
195-
'since %(since)s and will become an error %(removal)s.'
195+
'since %(since)s and will become an error in %(removal)s.'
196196
)
197197

198198

lib/matplotlib/legend.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1337,7 +1337,7 @@ def _parse_legend_args(axs, *args, handles=None, labels=None, **kwargs):
13371337
_api.warn_deprecated("3.9", message=(
13381338
"You have mixed positional and keyword arguments, some input may "
13391339
"be discarded. This is deprecated since %(since)s and will "
1340-
"become an error %(removal)s."))
1340+
"become an error in %(removal)s."))
13411341

13421342
if (hasattr(handles, "__len__") and
13431343
hasattr(labels, "__len__") and

lib/matplotlib/projections/polar.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def _apply_theta_transforms_warn():
2121
message=(
2222
"Passing `apply_theta_transforms=True` (the default) "
2323
"is deprecated since Matplotlib %(since)s. "
24-
"Support for this will be removed in Matplotlib %(removal)s. "
24+
"Support for this will be removed in Matplotlib in %(removal)s. "
2525
"To prevent this warning, set `apply_theta_transforms=False`, "
2626
"and make sure to shift theta values before being passed to "
2727
"this transform."

lib/matplotlib/tests/test_api.py

+35
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,41 @@ def f(cls: Self) -> None:
4949
a.f
5050

5151

52+
def test_warn_deprecated():
53+
with pytest.warns(mpl.MatplotlibDeprecationWarning,
54+
match=r'foo was deprecated in Matplotlib 3\.10 and will be '
55+
r'removed in 3\.12\.'):
56+
_api.warn_deprecated('3.10', name='foo')
57+
with pytest.warns(mpl.MatplotlibDeprecationWarning,
58+
match=r'The foo class was deprecated in Matplotlib 3\.10 and '
59+
r'will be removed in 3\.12\.'):
60+
_api.warn_deprecated('3.10', name='foo', obj_type='class')
61+
with pytest.warns(mpl.MatplotlibDeprecationWarning,
62+
match=r'foo was deprecated in Matplotlib 3\.10 and will be '
63+
r'removed in 3\.12\. Use bar instead\.'):
64+
_api.warn_deprecated('3.10', name='foo', alternative='bar')
65+
with pytest.warns(mpl.MatplotlibDeprecationWarning,
66+
match=r'foo was deprecated in Matplotlib 3\.10 and will be '
67+
r'removed in 3\.12\. More information\.'):
68+
_api.warn_deprecated('3.10', name='foo', addendum='More information.')
69+
with pytest.warns(mpl.MatplotlibDeprecationWarning,
70+
match=r'foo was deprecated in Matplotlib 3\.10 and will be '
71+
r'removed in 4\.0\.'):
72+
_api.warn_deprecated('3.10', name='foo', removal='4.0')
73+
with pytest.warns(mpl.MatplotlibDeprecationWarning,
74+
match=r'foo was deprecated in Matplotlib 3\.10\.'):
75+
_api.warn_deprecated('3.10', name='foo', removal=False)
76+
with pytest.warns(PendingDeprecationWarning,
77+
match=r'foo will be deprecated in a future version'):
78+
_api.warn_deprecated('3.10', name='foo', pending=True)
79+
with pytest.raises(ValueError, match=r'cannot have a scheduled removal'):
80+
_api.warn_deprecated('3.10', name='foo', pending=True, removal='3.12')
81+
with pytest.warns(mpl.MatplotlibDeprecationWarning, match=r'Complete replacement'):
82+
_api.warn_deprecated('3.10', message='Complete replacement', name='foo',
83+
alternative='bar', addendum='More information.',
84+
obj_type='class', removal='4.0')
85+
86+
5287
def test_deprecate_privatize_attribute() -> None:
5388
class C:
5489
def __init__(self) -> None: self._attr = 1

0 commit comments

Comments
 (0)