8000 Merge pull request #23088 from anntzer/misspelled-data-key · matplotlib/matplotlib@feb1ca1 · GitHub
[go: up one dir, main page]

Skip to content

Commit feb1ca1

Browse files
authored
Merge pull request #23088 from anntzer/misspelled-data-key
Improve error for invalid format strings / mispelled data keys.
2 parents ae830fa + d7bf480 commit feb1ca1

File tree

2 files changed

+33
-22
lines changed

2 files changed

+33
-22
lines changed

lib/matplotlib/axes/_base.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def __call__(self, ax, renderer):
118118
self._transform - ax.figure.transSubfigure)
119119

120120

121-
def _process_plot_format(fmt):
121+
def _process_plot_format(fmt, *, ambiguous_fmt_datakey=False):
122122
"""
123123
Convert a MATLAB style color/line style format string to a (*linestyle*,
124124
*marker*, *color*) tuple.
@@ -163,31 +163,31 @@ def _process_plot_format(fmt):
163163
except ValueError:
164164
pass # No, not just a color.
165165

166+
errfmt = ("{!r} is neither a data key nor a valid format string ({})"
167+
if ambiguous_fmt_datakey else
168+
"{!r} is not a valid format string ({})")
169+
166170
i = 0
167171
while i < len(fmt):
168172
c = fmt[i]
169173
if fmt[i:i+2] in mlines.lineStyles: # First, the two-char styles.
170174
if linestyle is not None:
171-
raise ValueError(
172-
f'Illegal format string {fmt!r}; two linestyle symbols')
175+
raise ValueError(errfmt.format(fmt, "two linestyle symbols"))
173176
linestyle = fmt[i:i+2]
174177
i += 2
175178
elif c in mlines.lineStyles:
176179
if linestyle is not None:
177-
raise ValueError(
178-
f'Illegal format string {fmt!r}; two linestyle symbols')
180+
raise ValueError(errfmt.format(fmt, "two linestyle symbols"))
179181
linestyle = c
180182
i += 1
181183
elif c in mlines.lineMarkers:
182184
if marker is not None:
183-
raise ValueError(
184-
f'Illegal format string {fmt!r}; two marker symbols')
185+
raise ValueError(errfmt.format(fmt, "two marker symbols"))
185186
marker = c
186187
i += 1
187188
elif c in mcolors.get_named_colors_mapping():
188189
if color is not None:
189-
raise ValueError(
190-
f'Illegal format string {fmt!r}; two color symbols')
190+
raise ValueError(errfmt.format(fmt, "two color symbols"))
191191
color = c
192192
i += 1
193193
elif c == 'C' and i < len(fmt) - 1:
@@ -196,7 +196,7 @@ def _process_plot_format(fmt):
196196
i += 2
197197
else:
198198
raise ValueError(
199-
f'Unrecognized character {c} in format string {fmt!r}')
199+
errfmt.format(fmt, f"unrecognized character {c!r}"))
200200

201201
if linestyle is None and marker is None:
202202
linestyle = mpl.rcParams['lines.linestyle']
@@ -293,6 +293,7 @@ def __call__(self, *args, data=None, **kwargs):
293293
kwargs["label"] = mpl._label_from_arg(
294294
replaced[label_namer_idx], args[label_namer_idx])
295295
args = replaced
296+
ambiguous_fmt_datakey = data is not None and len(args) == 2
296297

297298
if len(args) >= 4 and not cbook.is_scalar_or_string(
298299
kwargs.get("label")):
@@ -308,7 +309,8 @@ def __call__(self, *args, data=None, **kwargs):
308309
if args and isinstance(args[0], str):
309310
this += args[0],
310311
args = args[1:]
311-
yield from self._plot_args(this, kwargs)
312+
yield from self._plot_args(
313+
this, kwargs, ambiguous_fmt_datakey=ambiguous_fmt_datakey)
312314

313315
def get_next_color(self):
314316
"""Return the next color in the cycle."""
@@ -402,7 +404,8 @@ def _makefill(self, x, y, kw, kwargs):
402404
seg.set(**kwargs)
403405
return seg, kwargs
404406

405-
def _plot_args(self, tup, kwargs, return_kwargs=False):
407+
def _plot_args(self, tup, kwargs, *,
408+
return_kwargs=False, ambiguous_fmt_datakey=False):
406409
"""
407410
Process the arguments of ``plot([x], y, [fmt], **kwargs)`` calls.
408411
@@ -429,9 +432,13 @@ def _plot_args(self, tup, kwargs, return_kwargs=False):
429432
The keyword arguments passed to ``plot()``.
430433
431434
return_kwargs : bool
432-
If true, return the effective keyword arguments after label
435+
Whether to also return the effective keyword arguments after label
433436
unpacking as well.
434437
438+
ambiguous_fmt_datakey : bool
439+
Whether the format string in *tup* could also have been a
440+
misspelled data key.
441+
435442
Returns
436443
-------
437444
result
@@ -445,7 +452,8 @@ def _plot_args(self, tup, kwargs, return_kwargs=False):
445452
if len(tup) > 1 and isinstance(tup[-1], str):
446453
# xy is tup with fmt stripped (could still be (y,) only)
447454
*xy, fmt = tup
448-
linestyle, marker, color = _process_plot_format(fmt)
455+
linestyle, marker, color = _process_plot_format(
456+
fmt, ambiguous_fmt_datakey=ambiguous_fmt_datakey)
449457
elif len(tup) == 3:
450458
raise ValueError('third arg must be a format string')
451459
else:

lib/matplotlib/tests/test_axes.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7698,16 +7698,19 @@ def test_empty_line_plots():
76987698

76997699

77007700
@pytest.mark.parametrize('fmt, match', (
7701-
("foo", "Unrecognized character f in format string 'foo'"),
7702-
("o+", "Illegal format string 'o\\+'; two marker symbols"),
7703-
(":-", "Illegal format string ':-'; two linestyle symbols"),
7704-
("rk", "Illegal format string 'rk'; two color symbols"),
7705-
(":o-r", "Illegal format string ':o-r'; two linestyle symbols"),
7701+
("f", r"'f' is not a valid format string \(unrecognized character 'f'\)"),
7702+
("o+", r"'o\+' is not a valid format string \(two marker symbols\)"),
7703+
(":-", r"':-' is not a valid format string \(two linestyle symbols\)"),
7704+
("rk", r"'rk' is not a valid format string \(two color symbols\)"),
7705+
(":o-r", r"':o-r' is not a valid format string \(two linestyle symbols\)"),
77067706
))
7707-
def test_plot_format_errors(fmt, match):
7707+
@pytest.mark.parametrize("data", [None, {"string": range(3)}])
7708+
def test_plot_format_errors(fmt, match, data):
77087709
fig, ax = plt.subplots()
7709-
with pytest.raises(ValueError, match=match):
7710-
ax.plot((0, 0), fmt)
7710+
if data is not None:
7711+
match = match.replace("not", "neither a data key nor")
7712+
with pytest.raises(ValueError, match=r"\A" + match + r"\Z"):
7713+
ax.plot("string", fmt, data=data)
77117714

77127715

77137716
def test_clim():

0 commit comments

Comments
 (0)
0