Skip to content

Commit

Permalink
Merge pull request #7767 from anntzer/iterables-may-be-unsized
Browse files Browse the repository at this point in the history
 Don't check `iterable()` before `len()`.
  • Loading branch information
NelleV committed Jan 29, 2017
2 parents 430e308 + 199a87a commit 8b630a4
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 89 deletions.
10 changes: 7 additions & 3 deletions lib/matplotlib/axes/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import six
from six.moves import reduce, xrange, zip, zip_longest

from collections import Sized
import itertools
import math
import warnings
Expand Down Expand Up @@ -2940,8 +2941,11 @@ def extract_err(err, data):
data : iterable
x or y from errorbar
'''
if (iterable(err) and len(err) == 2):
try:
a, b = err
except (TypeError, ValueError):
pass
else:
if iterable(a) and iterable(b):
# using list comps rather than arrays to preserve units
low = [thisx - thiserr for (thisx, thiserr)
Expand All @@ -2955,8 +2959,8 @@ def extract_err(err, data):
# special case for empty lists
if len(err) > 1:
fe = safe_first_element(err)
if not ((len(err) == len(data) and not (iterable(fe) and
len(fe) > 1))):
if (len(err) != len(data)
or isinstance(fe, Sized) and len(fe) > 1):
raise ValueError("err must be [ scalar | N, Nx1 "
"or 2xN array-like ]")
# using list comps rather than arrays to preserve units
Expand Down
6 changes: 2 additions & 4 deletions lib/matplotlib/axes/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1925,11 +1925,9 @@ def update_datalim(self, xys, updatex=True, updatey=True):
# limits and set the bound to be the bounds of the xydata.
# Otherwise, it will compute the bounds of it's current data
# and the data in xydata

if iterable(xys) and not len(xys):
xys = np.asarray(xys)
if not len(xys):
return
if not isinstance(xys, np.ma.MaskedArray):
xys = np.asarray(xys)
self.dataLim.update_from_data_xy(xys, self.ignore_existing_data_limits,
updatex=updatex, updatey=updatey)
self.ignore_existing_data_limits = False
Expand Down
9 changes: 5 additions & 4 deletions lib/matplotlib/cm.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,10 +301,11 @@ def set_clim(self, vmin=None, vmax=None):
ACCEPTS: a length 2 sequence of floats
"""
if (vmin is not None and vmax is None and
cbook.iterable(vmin) and len(vmin) == 2):
vmin, vmax = vmin

if vmax is None:
try:
vmin, vmax = vmin
except (TypeError, ValueError):
pass
if vmin is not None:
self.norm.vmin = vmin
if vmax is not None:
Expand Down
29 changes: 2 additions & 27 deletions lib/matplotlib/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,31 +156,6 @@ def __init__(self,
self.update(kwargs)
self._paths = None

@staticmethod
def _get_value(val):
try:
return (float(val), )
except TypeError:
if cbook.iterable(val) and len(val):
try:
float(cbook.safe_first_element(val))
except (TypeError, ValueError):
pass # raise below
else:
return val

raise TypeError('val must be a float or nonzero sequence of floats')

@staticmethod
def _get_bool(val):
if not cbook.iterable(val):
val = (val,)
try:
bool(cbook.safe_first_element(val))
except (TypeError, IndexError):
raise TypeError('val must be a bool or nonzero sequence of them')
return val

def get_paths(self):
return self._paths

Expand Down Expand Up @@ -486,7 +461,7 @@ def set_linewidth(self, lw):
if lw is None:
lw = mpl.rcParams['lines.linewidth']
# get the un-scaled/broadcast lw
self._us_lw = self._get_value(lw)
self._us_lw = np.atleast_1d(np.asarray(lw))

# scale all of the dash patterns.
self._linewidths, self._linestyles = self._bcast_lwls(
Expand Down Expand Up @@ -608,7 +583,7 @@ def set_antialiased(self, aa):
"""
if aa is None:
aa = mpl.rcParams['patch.antialiased']
self._antialiaseds = self._get_bool(aa)
self._antialiaseds = np.atleast_1d(np.asarray(aa, bool))
self.stale = True

def set_antialiaseds(self, aa):
Expand Down
12 changes: 7 additions & 5 deletions lib/matplotlib/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@

from __future__ import (absolute_import, division, print_function,
unicode_literals)
import re
import six
from six.moves import zip

from collections import Sized
import re
import warnings

import numpy as np
Expand Down Expand Up @@ -693,12 +695,12 @@ def from_list(name, colors, N=256, gamma=1.0):
if not cbook.iterable(colors):
raise ValueError('colors must be iterable')

if cbook.iterable(colors[0]) and len(colors[0]) == 2 and \
not cbook.is_string_like(colors[0]):
if (isinstance(colors[0], Sized) and len(colors[0]) == 2
and not cbook.is_string_like(colors[0])):
# List of value, color pairs
vals, colors = list(zip(*colors))
vals, colors = zip(*colors)
else:
vals = np.linspace(0., 1., len(colors))
vals = np.linspace(0, 1, len(colors))

cdict = dict(red=[], green=[], blue=[], alpha=[])
for val, color in zip(vals, colors):
Expand Down
36 changes: 11 additions & 25 deletions lib/matplotlib/legend.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

from matplotlib import rcParams
from matplotlib.artist import Artist, allow_rasterization
from matplotlib.cbook import is_string_like, iterable, silent_list, is_hashable
from matplotlib.cbook import is_string_like, silent_list, is_hashable
from matplotlib.font_manager import FontProperties
from matplotlib.lines import Line2D
from matplotlib.patches import Patch, Rectangle, Shadow, FancyBboxPatch
Expand Down Expand Up @@ -408,17 +408,6 @@ def _set_loc(self, loc):
# find_offset function will be provided to _legend_box and
# _legend_box will draw itself at the location of the return
# value of the find_offset.
self._loc_real = loc
if loc == 0:
_findoffset = self._findoffset_best
else:
_findoffset = self._findoffset_loc

# def findoffset(width, height, xdescent, ydescent):
# return _findoffset(width, height, xdescent, ydescent, renderer)

self._legend_box.set_offset(_findoffset)

self._loc_real = loc
self.stale = True

Expand All @@ -427,24 +416,20 @@ def _get_loc(self):

_loc = property(_get_loc, _set_loc)

def _findoffset_best(self, width, height, xdescent, ydescent, renderer):
"Helper function to locate the legend at its best position"
ox, oy = self._find_best_position(width, height, renderer)
return ox + xdescent, oy + ydescent

def _findoffset_loc(self, width, height, xdescent, ydescent, renderer):
"Helper function to locate the legend using the location code"
def _findoffset(self, width, height, xdescent, ydescent, renderer):
"Helper function to locate the legend"

if iterable(self._loc) and len(self._loc) == 2:
# when loc is a tuple of axes(or figure) coordinates.
fx, fy = self._loc
bbox = self.get_bbox_to_anchor()
x, y = bbox.x0 + bbox.width * fx, bbox.y0 + bbox.height * fy
else:
if self._loc == 0: # "best".
x, y = self._find_best_position(width, height, renderer)
elif self._loc in Legend.codes.values(): # Fixed location.
bbox = Bbox.from_bounds(0, 0, width, height)
x, y = self._get_anchored_bbox(self._loc, bbox,
self.get_bbox_to_anchor(),
renderer)
else: # Axes or figure coordinates.
fx, fy = self._loc
bbox = self.get_bbox_to_anchor()
x, y = bbox.x0 + bbox.width * fx, bbox.y0 + bbox.height * fy

return x + xdescent, y + ydescent

Expand Down Expand Up @@ -701,6 +686,7 @@ def _init_legend_box(self, handles, labels, markerfirst=True):
children=[self._legend_title_box,
self._legend_handle_box])
self._legend_box.set_figure(self.figure)
self._legend_box.set_offset(self._findoffset)
self.texts = text_list
self.legendHandles = handle_list

Expand Down
8 changes: 5 additions & 3 deletions lib/matplotlib/markers.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,12 @@
import six
from six.moves import xrange

from collections import Sized

import numpy as np

from .cbook import is_math_text, is_string_like, is_numlike, iterable
from matplotlib import rcParams
from . import rcParams
from .cbook import is_math_text, is_string_like, is_numlike
from .path import Path
from .transforms import IdentityTransform, Affine2D

Expand Down Expand Up @@ -247,7 +249,7 @@ def get_marker(self):
return self._marker

def set_marker(self, marker):
if (iterable(marker) and len(marker) in (2, 3) and
if (isinstance(marker, Sized) and len(marker) in (2, 3) and
marker[1] in (0, 1, 2, 3)):
self._marker_function = self._set_tuple_marker
elif isinstance(marker, np.ndarray):
Expand Down
9 changes: 2 additions & 7 deletions lib/matplotlib/rcsetup.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,13 @@

import six

from collections import Iterable, Mapping
from functools import reduce
import operator
import os
import warnings
import re

try:
import collections.abc as abc
except ImportError:
# python 2
import collections as abc

from matplotlib.cbook import mplDeprecation
from matplotlib.fontconfig_pattern import parse_fontconfig_pattern
from matplotlib.colors import is_color_like
Expand Down Expand Up @@ -92,7 +87,7 @@ def f(s):
# Numpy ndarrays, and pandas data structures. However, unordered
# sequences, such as sets, should be allowed but discouraged unless the
# user desires pseudorandom behavior.
elif isinstance(s, abc.Iterable) and not isinstance(s, abc.Mapping):
elif isinstance(s, Iterable) and not isinstance(s, Mapping):
# The condition on this list comprehension will preserve the
# behavior of filtering out any empty strings (behavior was
# from the original validate_stringlist()), while allowing
Expand Down
12 changes: 6 additions & 6 deletions lib/matplotlib/tests/test_collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import io

import numpy as np
from numpy.testing import assert_array_equal, assert_array_almost_equal
from numpy.testing import assert_equal
from numpy.testing import (
assert_array_equal, assert_array_almost_equal, assert_equal)
import pytest

import matplotlib.pyplot as plt
Expand Down Expand Up @@ -641,9 +641,9 @@ def test_lslw_bcast():
col.set_linestyles(['-', '-'])
col.set_linewidths([1, 2, 3])

assert col.get_linestyles() == [(None, None)] * 6
assert col.get_linewidths() == [1, 2, 3] * 2
assert_equal(col.get_linestyles(), [(None, None)] * 6)
assert_equal(col.get_linewidths(), [1, 2, 3] * 2)

col.set_linestyles(['-', '-', '-'])
assert col.get_linestyles() == [(None, None)] * 3
assert col.get_linewidths() == [1, 2, 3]
assert_equal(col.get_linestyles(), [(None, None)] * 3)
assert_equal(col.get_linewidths(), [1, 2, 3])
14 changes: 9 additions & 5 deletions lib/matplotlib/units.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,15 @@ def get_converter(self, x):
converter = self.get_converter(next_item)
return converter

if converter is None and iterable(x) and (len(x) > 0):
thisx = safe_first_element(x)
if classx and classx != getattr(thisx, '__class__', None):
converter = self.get_converter(thisx)
return converter
if converter is None:
try:
thisx = safe_first_element(x)
except (TypeError, StopIteration):
pass
else:
if classx and classx != getattr(thisx, '__class__', None):
converter = self.get_converter(thisx)
return converter

# DISABLED self._cached[idx] = converter
return converter
Expand Down

0 comments on commit 8b630a4

Please sign in to comment.