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

Skip to content

Commit dab0fcf

Browse files
committed
Fixes a bug that caused the use of _as_mpl_axes to crash if one of the returned axes arguments defined __getitem__ but was not iterable.
1 parent 1342d32 commit dab0fcf

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

lib/matplotlib/figure.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,13 @@ def fixitems(items):
786786
ret = []
787787
for k, v in items:
788788
if iterable(v):
789-
v = tuple(v)
789+
# some objects can define __getitem__ without being
790+
# iterable and in those cases the conversion to tuples
791+
# will fail.
792+
try:
793+
v = tuple(v)
794+
except:
795+
pass
790796
ret.append((k, v))
791797
return tuple(ret)
792798

lib/matplotlib/tests/test_figure.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from nose.tools import assert_equal, assert_true, assert_raises
88
from matplotlib.testing.decorators import image_comparison, cleanup
9+
from matplotlib.axes import Axes
910
import matplotlib.pyplot as plt
1011

1112

@@ -110,6 +111,36 @@ def test_too_many_figures():
110111
assert len(w) == 1
111112

112113

114+
def test_iterability_axes_argument():
115+
116+
# This is a regression test for matplotlib/matplotlib#3196. If one of the
117+
# arguments returned by _as_mpl_axes defines __getitem__ but is not
118+
# iterable, this would raise an execption. This is because we check
119+
# whether the arguments are iterable, and if so we try and convert them
120+
# to a tuple. However, the ``iterable`` function returns True if
121+
# __getitem__ is present, but some classes can define __getitem__ without
122+
# being iterable. The tuple conversion is now done in a try...except in
123+
# case it fails.
124+
125+
class MyAxes(Axes):
126+
def __init__(self, *args, **kwargs):
127+
kwargs.pop('myclass', None)
128+
return Axes.__init__(self, *args, **kwargs)
129+
130+
class MyClass(object):
131+
132+
def __getitem__(self, item):
133+
if item != 'a':
134+
raise ValueError("item should be a")
135+
136+
def _as_mpl_axes(self):
137+
return MyAxes, {'myclass': self}
138+
139+
fig = plt.figure()
140+
ax = fig.add_subplot(1, 1, 1, projection=MyClass())
141+
plt.close(fig)
142+
143+
113144
if __name__ == "__main__":
114145
import nose
115146
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)

0 commit comments

Comments
 (0)