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
*************** *****
ExternalCommand ErrorWithOutput List 1 ['Traceback (most recent call
last):\n', ' File "<string>", line 1, in ?\n', 'ZeroDivisionEr ror:
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 = executeCommandR eturnOutput(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 ExternalCommand ErrorWithOutput List(Exception) :
def __init__(self,a rgs=None):
if args:
self.args = args[0]
self.outputList = args[1]
else:
self.args = args
self.outputList = []
def executeCommandR eturnOutput(arg s):
args_str = ' '.join(args)
if os.name not in ['nt', 'os2']:
import popen2
p = popen2.Popen4(a rgs_str)
p.tochild.close ()
outputList = p.fromchild.rea dlines()
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 ExternalCommand ErrorWithOutput List, [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 = executeCommandR eturnOutput(cmd )
print 'ret', ret
except ExternalCommand ErrorWithOutput List, e:
print 'ExternalComman dErrorWithOutpu tList', e, e.outputList
except Exception, e:
print 'Exception', e
type, value, stack = sys.exc_info()
print ''.join(traceba ck.format_excep tion(type, value, stack))
except:
print 'except'
type, value, stack = sys.exc_info()
print ''.join(traceba ck.format_excep tion(type, value, stack))
else:
print 'else'
print '*' * 20
---CLIP---
--
Heikki Toivonen
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
*************** *****
ExternalCommand ErrorWithOutput List 1 ['Traceback (most recent call
last):\n', ' File "<string>", line 1, in ?\n', 'ZeroDivisionEr ror:
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 = executeCommandR eturnOutput(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 ExternalCommand ErrorWithOutput List(Exception) :
def __init__(self,a rgs=None):
if args:
self.args = args[0]
self.outputList = args[1]
else:
self.args = args
self.outputList = []
def executeCommandR eturnOutput(arg s):
args_str = ' '.join(args)
if os.name not in ['nt', 'os2']:
import popen2
p = popen2.Popen4(a rgs_str)
p.tochild.close ()
outputList = p.fromchild.rea dlines()
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 ExternalCommand ErrorWithOutput List, [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 = executeCommandR eturnOutput(cmd )
print 'ret', ret
except ExternalCommand ErrorWithOutput List, e:
print 'ExternalComman dErrorWithOutpu tList', e, e.outputList
except Exception, e:
print 'Exception', e
type, value, stack = sys.exc_info()
print ''.join(traceba ck.format_excep tion(type, value, stack))
except:
print 'except'
type, value, stack = sys.exc_info()
print ''.join(traceba ck.format_excep tion(type, value, stack))
else:
print 'else'
print '*' * 20
---CLIP---
--
Heikki Toivonen
Comment