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

Skip to content

Commit 6cdfe15

Browse files
committed
Harmonize error messages from _api.check_in_list and _api.getitem_checked
This also means that the former now gains suggestions.
1 parent d0d2413 commit 6cdfe15

3 files changed

Lines changed: 35 additions & 17 deletions

File tree

lib/matplotlib/_api/__init__.py

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,36 @@ def type_name(tp):
107107
type_name(type(v))))
108108

109109

110+
def list_suggestion_error_msg(name, potential, values):
111+
"""
112+
Generate an error message if a potential setting is not an acceptable value.
113+
114+
If the acceptable values are all strings, and sufficiently large, then add just a
115+
few suggestions to the end of the message. Otherwise list the supported values.
116+
117+
Parameters
118+
----------
119+
name : str
120+
The name of the setting, keyword argument, etc. to generate the message for.
121+
potential
122+
The potential value from the user that is not a valid choice.
123+
values : iterable
124+
Sequence of values to check on.
125+
"""
126+
if len(values) > 5 and all(isinstance(v, str) for v in [potential, *values]):
127+
best = difflib.get_close_matches(potential, values, cutoff=0.5)
128+
match len(best):
129+
case 0:
130+
suggestion = ""
131+
case 1:
132+
suggestion = f" Did you mean: {best[0]!r}?"
133+
case _:
134+
suggestion = f" Did you mean one of: {', '.join(map(repr, best))}?"
135+
else:
136+
suggestion = f" Supported values are {', '.join(map(repr, values))}"
137+
return f"{potential!r} is not a valid value for {name}.{suggestion}"
138+
139+
110140
def check_in_list(values, /, **kwargs):
111141
"""
112142
For each *key, value* pair in *kwargs*, check that *value* is in *values*;
@@ -146,9 +176,7 @@ def check_in_list(values, /, **kwargs):
146176
# the individual `val == values[i]` ValueError surface.
147177
exists = False
148178
if not exists:
149-
msg = (f"{val!r} is not a valid value for {key}"
150-
f"; supported values are {', '.join(map(repr, values))}")
151-
raise ValueError(msg)
179+
raise ValueError(list_suggestion_error_msg(key, val, values))
152180

153181

154182
def check_shape(shape, /, **kwargs):
@@ -207,18 +235,7 @@ def getitem_checked(mapping, /, _error_cls=ValueError, **kwargs):
207235
try:
208236
return mapping[v]
209237
except KeyError:
210-
if len(mapping) > 5:
211-
best = difflib.get_close_matches(v, mapping.keys(), cutoff=0.5)
212-
match len(best):
213-
case 0:
214-
suggestion = ""
215-
case 1:
216-
suggestion = f" Did you mean: {best[0]!r}?"
217-
case _:
218-
suggestion = f" Did you mean one of: {', '.join(map(repr, best))}?"
219-
else:
220-
suggestion = f" Supported values are {', '.join(map(repr, mapping))}"
221-
raise _error_cls(f"{v!r} is not a valid value for {k}.{suggestion}") from None
238+
raise _error_cls(list_suggestion_error_msg(k, v, mapping.keys())) from None
222239

223240

224241
def caching_module_getattr(cls):

lib/matplotlib/_api/__init__.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class classproperty(Any):
3838
def check_isinstance(
3939
types: type | tuple[type | None, ...], /, **kwargs: Any
4040
) -> None: ...
41+
def list_suggestion_error_msg(name: str, potential: str, values: Sequence[Any]) -> str: ...
4142
def check_in_list(values: Sequence[Any], /, **kwargs: Any) -> None: ...
4243
def check_shape(shape: tuple[int | None, ...], /, **kwargs: NDArray) -> None: ...
4344
def getitem_checked(

lib/matplotlib/tests/test_transforms.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,8 +1072,8 @@ def test_scale_swapping(fig_test, fig_ref):
10721072

10731073
def test_offset_copy_errors():
10741074
with pytest.raises(ValueError,
1075-
match="'fontsize' is not a valid value for units;"
1076-
" supported values are 'dots', 'points', 'inches'"):
1075+
match="'fontsize' is not a valid value for units. "
1076+
"Supported values are 'dots', 'points', 'inches'"):
10771077
mtransforms.offset_copy(None, units='fontsize')
10781078

10791079
with pytest.raises(ValueError,

0 commit comments

Comments
 (0)