Python 2.5 fails where 2.4 works when running external program

Heikki Toivonen heikki at osafoundation.org
Fri Mar 30 01:53:09 EDT 2007


We have successfully used a script to run external programs for several
years. Now we upgraded our Python to 2.5, and are hitting a mysterious
error.

The expected output from the sample script (see below) with 2.4 looks
like this:

ret ['5\n']
else
********************
ExternalCommandErrorWithOutputList 1 ['Traceback (most recent call
last):\n', '  File "<string>", line 1, in ?\n', 'ZeroDivisionError:
integer division or modulo by zero\n']
********************
ret ['6\n', '7\n', '8\n']
else
********************

With 2.5 we get:

ret ['5\n']
else
********************
Exception 'int' object is not iterable
Traceback (most recent call last):
  File "...test.py", line 43, in <module>
    ret = executeCommandReturnOutput(cmd)
  File "...test.py", line 6, in __init__
    self.args = args[0]
TypeError: 'int' object is not iterable

********************
ret ['6\n', '7\n', '8\n']
else
********************

What is going on? How do we fix this? We'd like to be able to run with
both python 2.4 and 2.5.

And here is the script:

---CLIP---
import os, traceback, sys

class ExternalCommandErrorWithOutputList(Exception):
    def __init__(self,args=None):
        if args:
            self.args = args[0]
            self.outputList = args[1]
        else:
            self.args = args
            self.outputList = []


def executeCommandReturnOutput(args):
    args_str = ' '.join(args)

    if os.name not in ['nt', 'os2']:
        import popen2
        p = popen2.Popen4(args_str)
        p.tochild.close()
        outputList = p.fromchild.readlines()
        exitCode = p.wait()
        if exitCode == 0:
            exitCode = None
        else:
            exitCode >>= 8
    else:
        i,k = os.popen4(args_str)
        i.close()
        outputList = k.readlines()
        exitCode = k.close()

    if exitCode is not None:
        raise ExternalCommandErrorWithOutputList, [exitCode, outputList]

    return outputList


if __name__ == "__main__":
    for cmd in [['python', '-c', '"print 5"'],
                ['python', '-c', '"1/0"'],
                ['python', '-c', '"print 6;import
sys;sys.stdout.flush();print >>sys.stderr, 7;print 8"'],
                ]:
        try:
            ret = executeCommandReturnOutput(cmd)
            print 'ret', ret
        except ExternalCommandErrorWithOutputList, e:
            print 'ExternalCommandErrorWithOutputList', e, e.outputList
        except Exception, e:
            print 'Exception', e
            type, value, stack = sys.exc_info()
            print ''.join(traceback.format_exception(type, value, stack))
        except:
            print 'except'
            type, value, stack = sys.exc_info()
            print ''.join(traceback.format_exception(type, value, stack))
        else:
            print 'else'
        print '*' * 20
---CLIP---

-- 
  Heikki Toivonen



More information about the Python-list mailing list