Skip to content

Commit 5c34b2b

Browse files
committed
Factor out legend/figlegend nargs validation.
Currently Figure.legend supposedly supports extra_args, forwarding them to the Legend constructor, but because all parameters of the Legend constructor except for the first two have become keyword-only, extra_args actually causes a TypeError to be raised when calling Legend(...) (try e.g. `plt.figlegend([], [], "right")`). So just don't bother with extra_args anymore, check the case of "more than two positional args" in _parse_legend_args, and also fix test_legend_label_three_args, which was actually hiding the above exception via a mock and not really testing a relevant case anymore.
1 parent 060992a commit 5c34b2b

File tree

4 files changed

+13
-46
lines changed

4 files changed

+13
-46
lines changed

lib/matplotlib/axes/_axes.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -316,12 +316,7 @@ def legend(self, *args, **kwargs):
316316
--------
317317
.. plot:: gallery/text_labels_and_annotations/legend.py
318318
"""
319-
handles, labels, extra_args, kwargs = mlegend._parse_legend_args(
320-
[self],
321-
*args,
322-
**kwargs)
323-
if len(extra_args):
324-
raise _api.nargs_error('legend', '0-2', len(args))
319+
handles, labels, kwargs = mlegend._parse_legend_args([self], *args, **kwargs)
325320
self.legend_ = mlegend.Legend(self, handles, labels, **kwargs)
326321
self.legend_._remove_method = self._remove_legend
327322
return self.legend_

lib/matplotlib/figure.py

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,25 +1128,10 @@ def legend(self, *args, **kwargs):
11281128
:ref:`legend_guide` for details.
11291129
"""
11301130

1131-
handles, labels, extra_args, kwargs = mlegend._parse_legend_args(
1132-
self.axes,
1133-
*args,
1134-
**kwargs)
1135-
# check for third arg
1136-
if len(extra_args):
1137-
# _api.warn_deprecated(
1138-
# "2.1",
1139-
# message="Figure.legend will accept no more than two "
1140-
# "positional arguments in the future. Use "
1141-
# "'fig.legend(handles, labels, loc=location)' "
1142-
# "instead.")
1143-
# kwargs['loc'] = extra_args[0]
1144-
# extra_args = extra_args[1:]
1145-
pass
1146-
transform = kwargs.pop('bbox_transform', self.transSubfigure)
1131+
handles, labels, kwargs = mlegend._parse_legend_args(self.axes, *args, **kwargs)
11471132
# explicitly set the bbox transform if the user hasn't.
1148-
l = mlegend.Legend(self, handles, labels, *extra_args,
1149-
bbox_transform=transform, **kwargs)
1133+
kwargs.setdefault("bbox_transform", self.transSubfigure)
1134+
l = mlegend.Legend(self, handles, labels, **kwargs)
11501135
self.legends.append(l)
11511136
l._remove_method = self.legends.remove
11521137
self.stale = True

lib/matplotlib/legend.py

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,16 +1344,13 @@ def _parse_legend_args(axs, *args, handles=None, labels=None, **kwargs):
13441344
The legend handles.
13451345
labels : list of str
13461346
The legend labels.
1347-
extra_args : tuple
1348-
*args* with positional handles and labels removed.
13491347
kwargs : dict
13501348
*kwargs* with keywords handles and labels removed.
13511349
13521350
"""
13531351
log = logging.getLogger(__name__)
13541352

13551353
handlers = kwargs.get('handler_map')
1356-
extra_args = ()
13571354

13581355
if (handles is not None or labels is not None) and args:
13591356
_api.warn_external("You have mixed positional and keyword arguments, "
@@ -1371,17 +1368,15 @@ def _parse_legend_args(axs, *args, handles=None, labels=None, **kwargs):
13711368
handles = [handle for handle, label
13721369
in zip(_get_legend_handles(axs, handlers), labels)]
13731370

1374-
# No arguments - automatically detect labels and handles.
1375-
elif len(args) == 0:
1371+
elif len(args) == 0: # 0 args: automatically detect labels and handles.
13761372
handles, labels = _get_legend_handles_labels(axs, handlers)
13771373
if not handles:
13781374
log.warning(
13791375
"No artists with labels found to put in legend. Note that "
13801376
"artists whose label start with an underscore are ignored "
13811377
"when legend() is called with no argument.")
13821378

1383-
# One argument. User defined labels - automatic handle detection.
1384-
elif len(args) == 1:
1379+
elif len(args) == 1: # 1 arg: user defined labels, automatic handle detection.
13851380
labels, = args
13861381
if any(isinstance(l, Artist) for l in labels):
13871382
raise TypeError("A single argument passed to legend() must be a "
@@ -1391,10 +1386,10 @@ def _parse_legend_args(axs, *args, handles=None, labels=None, **kwargs):
13911386
handles = [handle for handle, label
13921387
in zip(_get_legend_handles(axs, handlers), labels)]
13931388

1394-
# Two arguments:
1395-
# * user defined handles and labels
1396-
else:
1389+
elif len(args) == 2: # 2 args: user defined handles and labels.
13971390
handles, labels = args[:2]
1398-
extra_args = args[2:]
13991391

1400-
return handles, labels, extra_args, kwargs
1392+
else:
1393+
raise _api.nargs_error('legend', '0-2', len(args))
1394+
1395+
return handles, labels, kwargs

lib/matplotlib/tests/test_legend.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -453,17 +453,9 @@ def test_legend_label_arg(self):
453453
def test_legend_label_three_args(self):
454454
fig, ax = plt.subplots()
455455
lines = ax.plot(range(10))
456-
with mock.patch('matplotlib.legend.Legend') as Legend:
456+
with pytest.raises(TypeError, match="0-2"):
457457
fig.legend(lines, ['foobar'], 'right')
458-
Legend.assert_called_with(fig, lines, ['foobar'], 'right',
459-
bbox_transform=fig.transFigure)
460-
461-
def test_legend_label_three_args_pluskw(self):
462-
# test that third argument and loc= called together give
463-
# Exception
464-
fig, ax = plt.subplots()
465-
lines = ax.plot(range(10))
466-
with pytest.raises(Exception):
458+
with pytest.raises(TypeError, match="0-2"):
467459
fig.legend(lines, ['foobar'], 'right', loc='left')
468460

469461
def test_legend_kw_args(self):

0 commit comments

Comments
 (0)