Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Python 2.5 fails where 2.4 works when running external program

Reply
Thread Tools

Python 2.5 fails where 2.4 works when running external program

 
 
Heikki Toivonen
Guest
Posts: n/a
 
      03-30-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
 
Reply With Quote
 
 
 
 
Peter Otten
Guest
Posts: n/a
 
      03-30-2007
Heikki Toivonen wrote:

> 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.


I think Exception.args always was supposed to be a tuple. Starting with 2.5
Python enforces that constraint:

[Python2.4]
>>> e = Exception()
>>> e.args

()
>>> e.args = "abc"
>>> e.args

'abc'
>>> e.args = 1
>>> e.args

1

[Python 2.5]
>>> e = Exception()
>>> e.args

()
>>> e.args = "abc"
>>> e.args

('a', 'b', 'c')
>>> e.args = 1

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable

The quick fix is of course

>>> e.args = [1]


but also note that according to the tutorial

http://docs.python.org/tut/node10.ht...00000000000000
"""
But use of .args is discouraged. Instead, the preferred use is to pass a
single argument to an exception (which can be a tuple if multiple arguments
are needed) and have it bound to the message attribute.
"""

Peter

 
Reply With Quote
 
 
 
 
Heikki Toivonen
Guest
Posts: n/a
 
      03-30-2007
Peter Otten wrote:
> I think Exception.args always was supposed to be a tuple. Starting with 2.5
> Python enforces that constraint:

[...]
> http://docs.python.org/tut/node10.ht...00000000000000
> """
> But use of .args is discouraged. Instead, the preferred use is to pass a
> single argument to an exception (which can be a tuple if multiple arguments
> are needed) and have it bound to the message attribute.
> """


Excellent, thank you!

--
Heikki Toivonen
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
subprocess.Popen and multiprocessing fails to execute external program Niklas Berliner Python 0 01-10-2013 04:08 AM
newbie - script works in PythonWin - fails from Python marcus.tettmar@gmail.com Python 13 02-04-2006 08:44 PM
When I turn on my PC, it works, works, works. Problem! Fogar Computer Information 1 01-17-2006 12:57 AM
After rebooting my PC works, works, works! Antivirus problem? Adriano Computer Information 1 12-15-2003 05:30 AM
How can I call a sub and keep the main program running while it works? Razor Perl 2 08-18-2003 11:56 PM



Advertisments