Skip to content

Commit

Permalink
Merge pull request matplotlib#12642 from anntzer/fmt_xdata
Browse files Browse the repository at this point in the history
Don't silence TypeErrors in fmt_{x,y}data.
  • Loading branch information
jklymak authored Oct 28, 2018
2 parents f288977 + b4db196 commit 2bd2e93
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 37 deletions.
7 changes: 7 additions & 0 deletions doc/api/next_api_changes/2018-10-27-AL.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
``Axes.fmt_xdata`` and ``Axes.fmt_ydata`` no longer ignore TypeErrors raised by a user-provided formatter
`````````````````````````````````````````````````````````````````````````````````````````````````````````

Previously, if the user provided a ``fmt_xdata`` or ``fmt_ydata`` function that
raised a TypeError (or set them to a non-callable), the exception would be
silently ignored and the default formatter be used instead. This is no longer
the case; the exception is now propagated out.
32 changes: 13 additions & 19 deletions lib/matplotlib/axes/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3654,32 +3654,26 @@ def yaxis_date(self, tz=None):

def format_xdata(self, x):
"""
Return *x* string formatted. This function will use the attribute
self.fmt_xdata if it is callable, else will fall back on the xaxis
major formatter
Return *x* formatted as an x-value.
This function will use the `.fmt_xdata` attribute if it is not None,
else will fall back on the xaxis major formatter.
"""
try:
return self.fmt_xdata(x)
except TypeError:
func = self.xaxis.get_major_formatter().format_data_short
val = func(x)
return val
return (self.fmt_xdata if self.fmt_xdata is not None
else self.xaxis.get_major_formatter().format_data_short)(x)

def format_ydata(self, y):
"""
Return y string formatted. This function will use the
:attr:`fmt_ydata` attribute if it is callable, else will fall
back on the yaxis major formatter
Return *y* formatted as an y-value.
This function will use the `.fmt_ydata` attribute if it is not None,
else will fall back on the yaxis major formatter.
"""
try:
return self.fmt_ydata(y)
except TypeError:
func = self.yaxis.get_major_formatter().format_data_short
val = func(y)
return val
return (self.fmt_ydata if self.fmt_ydata is not None
else self.yaxis.get_major_formatter().format_data_short)(y)

def format_coord(self, x, y):
"""Return a format string formatting the *x*, *y* coord"""
"""Return a format string formatting the *x*, *y* coordinates."""
if x is None:
xs = '???'
else:
Expand Down
42 changes: 24 additions & 18 deletions lib/matplotlib/tests/test_backend_bases.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import re

from matplotlib.backend_bases import (
FigureCanvasBase, LocationEvent, RendererBase)
import matplotlib.pyplot as plt
Expand Down Expand Up @@ -71,22 +73,26 @@ def test_non_gui_warning():
in str(rec[0].message))


def test_location_event_position():
# LocationEvent should cast its x and y arguments
# to int unless it is None
fig = plt.figure()
@pytest.mark.parametrize(
"x, y", [(42, 24), (None, 42), (None, None), (200, 100.01), (205.75, 2.0)])
def test_location_event_position(x, y):
# LocationEvent should cast its x and y arguments to int unless it is None.
fig, ax = plt.subplots()
canvas = FigureCanvasBase(fig)
test_positions = [(42, 24), (None, 42), (None, None),
(200, 100.01), (205.75, 2.0)]
for x, y in test_positions:
event = LocationEvent("test_event", canvas, x, y)
if x is None:
assert event.x is None
else:
assert event.x == int(x)
assert isinstance(event.x, int)
if y is None:
assert event.y is None
else:
assert event.y == int(y)
assert isinstance(event.y, int)
event = LocationEvent("test_event", canvas, x, y)
if x is None:
assert event.x is None
else:
assert event.x == int(x)
assert isinstance(event.x, int)
if y is None:
assert event.y is None
else:
assert event.y == int(y)
assert isinstance(event.y, int)
if x is not None and y is not None:
assert re.match(
"x={} +y={}".format(ax.format_xdata(x), ax.format_ydata(y)),
ax.format_coord(x, y))
ax.fmt_xdata = ax.fmt_ydata = lambda x: "foo"
assert re.match("x=foo +y=foo", ax.format_coord(x, y))

0 comments on commit 2bd2e93

Please sign in to comment.