Python 2.5 fails where 2.4 works when running external program

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Heikki Toivonen

    Python 2.5 fails where 2.4 works when running external program

    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
  • Peter Otten

    #2
    Re: Python 2.5 fails where 2.4 works when running external program

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


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

    Comment

    • Heikki Toivonen

      #3
      Re: Python 2.5 fails where 2.4 works when running external program

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

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

      Comment

      Working...