is parameter an iterable?

Roy Smith roy at
Thu Nov 17 15:24:56 CET 2005

Steven D'Aprano <steve at> wrote:

> Alas and alack, I have to write code which is backwards 
> compatible with older versions of Python:
> [...]
> NameError: name 'iter' is not defined
> What should I do when I can't rely on functions that 
> don't exist in older versions of Python?

It really sucks trying to support obsolete environments.  Been there, done 
that.  But sometimes you just have to pull out the duct tape and deal with 
the problem any way you can.  Parsing undocumented exception strings is 
sort of like screen scraping; it's good to know that it's possible as an 
absolute last resort, but you really want to put some effort into finding a 
better way.

You could use two nested try blocks that both catch TypeErrors, one 
enclosing the entire loop, the other enclosing just the body.  Anything 
that gets caught by the outer try had to have been generated within the 
loop control code itself:

Roy-Smiths-Computer:play$ cat
#!/usr/bin/env python

def doSomething (obj):
    sum = 0
        for i in obj:
                sum += i
            except TypeError, ex:
                print "exception (%s) in the inner block" % ex
    except TypeError, ex:
        print "non iterable object (%s)" % ex
    print "sum = %d" % sum

doSomething ([1, 2, 3])
doSomething (["one", "two", "three"])
doSomething (0)
Roy-Smiths-Computer:play$ ./
sum = 6
exception (unsupported operand type(s) for +=: 'int' and 'str') in the 
inner block
non iterable object (iteration over non-sequence)

This is pretty ugly, but I think it does what you want.  It could be made a 
bit less ugly by refactoring the body of the for loop into another function.

BTW, if you do resort to trying to parse the exception messages, and it 
breaks in some future code, you might have me to blame.  I submitted a bug 
report a while back which, if it's ever acted on, would break your code!

More information about the Python-list mailing list