matplotlib.cbook.iterable

The function matplotlib.cbook.iterable has the documentation:

def iterable(obj):
     'return true if *obj* is iterable'
     try: len(obj)
     except: return False
     return True

However, in Sage, we have some objects that have __len__ defined, but are not iterable (i.e., they don't implement the iterator protocol). This is causing us problems when we try to plot some things that use this function, and matplotlib falsely assumes that the things are iterable. After checking around online, it seems that it is safer to check for iterability by doing something like:

try: iter(obj)
except TypeError: return False
return True

or

import collections
return isinstance(obj, collections.Iterable) # only works for new-style classes

Or maybe even combining these would be better (though it might be really redundant and slow, after looking at the code in collections.Iterable...):

try: iter(obj)
except TypeError:
     import collections
     return isinstance(obj, collections.Iterable)
return True

You guys are the python experts, though. What do you think?

Thanks,

Jason

I think this first one is sufficient and should work correctly for more things than the second. I'll go ahead and add this to matplotlib master -- I'm a little wary of changing this in 1.0.x in case someone is relying on the currently broken behavior.

Mike

try: iter(obj)
except TypeError: return False
return True

···

________________________________________
From: Jason Grout [jason-sage@...691...]
Sent: Tuesday, March 22, 2011 11:27 PM
To: matplotlib-devel@lists.sourceforge.net
Subject: [matplotlib-devel] matplotlib.cbook.iterable

The function matplotlib.cbook.iterable has the documentation:

def iterable(obj):
     'return true if *obj* is iterable'
     try: len(obj)
     except: return False
     return True

However, in Sage, we have some objects that have __len__ defined, but
are not iterable (i.e., they don't implement the iterator protocol).
This is causing us problems when we try to plot some things that use
this function, and matplotlib falsely assumes that the things are
iterable. After checking around online, it seems that it is safer to
check for iterability by doing something like:

try: iter(obj)
except TypeError: return False
return True

or

import collections
return isinstance(obj, collections.Iterable) # only works for new-style
classes

Or maybe even combining these would be better (though it might be really
redundant and slow, after looking at the code in collections.Iterable...):

try: iter(obj)
except TypeError:
     import collections
     return isinstance(obj, collections.Iterable)
return True

You guys are the python experts, though. What do you think?

Thanks,

Jason

------------------------------------------------------------------------------
Enable your software for Intel(R) Active Management Technology to meet the
growing manageability and security demands of your customers. Businesses
are taking advantage of Intel(R) vPro (TM) technology - will your software
be a part of the solution? Download the Intel(R) Manageability Checker
today! http://p.sf.net/sfu/intel-dev2devmar
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel