FAQ
I'm working on an audio/video converter script (moving from bash to
Python for some extra functionality), and part of it is chaining the
audio decoder (FFmpeg) either into SoX to change the volume and then to
the Nero AAC encoder or directly into the Nero encoder. This is the
chunk of code from my working bash script to give an idea of what I'm
trying to accomplish (it's indented because it's nested inside a while
loop and an if statement):
if [ "$process_audio" = "true" ]
then
if [ $vol == 1.0 ]
then
ffmpeg -i "${ifile_a}" -f wav - 2>$nul | neroaacenc
-ignorelength -q 0.4 -if - -of ${prefix}${zero}${ep}.m4a
else
# the pipeline-as-file option of sox fails on Windows
7, so I use the safe method since there's only one pipeline going into sox
ffmpeg -i "${ifile_a}" -f sox - 2>$nul | sox -t sox -
-t wav - vol $vol 2>$nul | neroaacenc -ignorelength -q 0.4 -if - -of
${prefix}${zero}${ep}.m4a
fi
else
echo "Audio skipped."
fi
This is pretty easy and straightforward in bash, but not so in Python.
This is what I have in Python (queue[position] points to an object I
create earlier that holds a bunch of info on what needs to be encoded -
input and output file names, command line options for the various
encoders used, and so forth), but clearly it has some problems:
try:
ffmpeg_proc = subprocess.Popen(queue[position].ffmpeg_cmd,
stdout=subprocess.PIPE, stderr=os.devnull)
except WindowsError:
error_info = str(sys.exc_info()[1])
last_win_error_num = find_win_error_no(error_msg=error_info)
if last_win_error_num == '2': # Error 2 = 'The system cannot
find the file specified'
logger.critical('Could not execute ' +
queue[position].ffmpeg_exe + ': File not found.')
elif last_win_error_num == '193': # Error 193 = '%1 is not a
valid Win32 application'
logger.critical('Could not execute ' +
queue[position].ffmpeg_exe + ': It\'s not a valid Win32 application.')
break
if queue[position].vol != 1:
try:
sox_proc = subprocess.Popen(queue[position].sox_cmd,
stdin=ffmpeg_proc.stdout, stdout=subprocess.PIPE, stderr=os.devnull)
except WindowsError:
error_info = str(sys.exc_info()[1])
last_win_error_num = find_win_error_no(error_msg=error_info)
if last_win_error_num == '2': # Error 2 = 'The system
cannot find the file specified'
logger.critical('Could not execute ' +
queue[position].sox_exe + ': File not found.')
elif last_win_error_num == '193': # Error 193 = '%1 is not
a valid Win32 application'
logger.critical('Could not execute ' +
queue[position].sox_exe + ': It\'s not a valid Win32 application.')
break
wav_pipe = sox_proc.stdout
else:
wav_pipe = ffmpeg_proc.stdout
try:
nero_aac_proc = subprocess.Popen(queue[position].nero_aac_cmd,
stdin=wav_pipe)
except WindowsError:
error_info = str(sys.exc_info()[1])
last_win_error_num = find_win_error_no(error_msg=error_info)
if last_win_error_num == '2': # Error 2 = 'The system cannot
find the file specified'
logger.critical('Could not execute ' +
queue[position].sox_exe + ': File not found.')
elif last_win_error_num == '193': # Error 193 = '%1 is not a
valid Win32 application'
logger.critical('Could not execute ' +
queue[position].sox_exe + ': It\'s not a valid Win32 application.')
break

ffmpeg_proc.wait()
if queue[position].vol != 1:
sox_proc.wait()
nero_aac_proc.wait()
break
Note: those break statements are there to break out of the while loop
this is in.
Firstly, that first assignment to ffmpeg_proc raises an exception:
Traceback (most recent call last):
File "C:\Users\Bahamut\workspace\Disillusion\disillusion.py", line
288, in <module>
ffmpeg_proc = subprocess.Popen(queue[position].ffmpeg_cmd,
stdout=subprocess.PIPE, stderr=os.devnull)
File "C:\Python32\lib\subprocess.py", line 700, in __init__
errread, errwrite) = self._get_handles(stdin, stdout, stderr)
File "C:\Python32\lib\subprocess.py", line 861, in _get_handles
errwrite = msvcrt.get_osfhandle(stderr.fileno())
AttributeError: 'str' object has no attribute 'fileno'
I'm not really sure what it's complaining about since the exception
propagates from the msvcrt module through the subprocess module into my
program. I'm thinking it has to do my stderr assignment, but if that's
not right, I don't know what is.
Secondly, there are no Popen.stdout.close() calls because I'm not sure
where to put them.
Thirdly, I have nearly identical except WindowsError: blocks repeated -
I'm sure I can avoid this with decorators as suggested in a recent
thread, but I haven't learned decorators yet. This code isn't very
complete; I'm trying to get it to work in ideal conditions first, then
worry about how to handle failure.

Using Python 3 on Windows 7.

Search Discussions

  • Peter Otten at Jun 28, 2011 at 6:32 am

    Andrew Berg wrote:

    I'm working on an audio/video converter script (moving from bash to
    Python for some extra functionality), and part of it is chaining the
    audio decoder (FFmpeg) either into SoX to change the volume and then to
    the Nero AAC encoder or directly into the Nero encoder. This is the
    chunk of code from my working bash script to give an idea of what I'm
    trying to accomplish (it's indented because it's nested inside a while
    loop and an if statement):
    if [ "$process_audio" = "true" ]
    then
    if [ $vol == 1.0 ]
    then
    ffmpeg -i "${ifile_a}" -f wav - 2>$nul | neroaacenc
    -ignorelength -q 0.4 -if - -of ${prefix}${zero}${ep}.m4a
    else
    # the pipeline-as-file option of sox fails on Windows
    7, so I use the safe method since there's only one pipeline going into
    sox
    ffmpeg -i "${ifile_a}" -f sox - 2>$nul | sox -t sox -
    -t wav - vol $vol 2>$nul | neroaacenc -ignorelength -q 0.4 -if - -of
    ${prefix}${zero}${ep}.m4a
    fi
    else
    echo "Audio skipped."
    fi
    This is pretty easy and straightforward in bash, but not so in Python.
    This is what I have in Python (queue[position] points to an object I
    create earlier that holds a bunch of info on what needs to be encoded -
    input and output file names, command line options for the various
    encoders used, and so forth), but clearly it has some problems:
    try:
    ffmpeg_proc = subprocess.Popen(queue[position].ffmpeg_cmd,
    stdout=subprocess.PIPE, stderr=os.devnull)
    except WindowsError:
    error_info = str(sys.exc_info()[1])
    last_win_error_num = find_win_error_no(error_msg=error_info)
    if last_win_error_num == '2': # Error 2 = 'The system cannot
    find the file specified'
    logger.critical('Could not execute ' +
    queue[position].ffmpeg_exe + ': File not found.')
    elif last_win_error_num == '193': # Error 193 = '%1 is not a
    valid Win32 application'
    logger.critical('Could not execute ' +
    queue[position].ffmpeg_exe + ': It\'s not a valid Win32 application.')
    break
    if queue[position].vol != 1:
    try:
    sox_proc = subprocess.Popen(queue[position].sox_cmd,
    stdin=ffmpeg_proc.stdout, stdout=subprocess.PIPE, stderr=os.devnull)
    except WindowsError:
    error_info = str(sys.exc_info()[1])
    last_win_error_num = find_win_error_no(error_msg=error_info)
    if last_win_error_num == '2': # Error 2 = 'The system
    cannot find the file specified'
    logger.critical('Could not execute ' +
    queue[position].sox_exe + ': File not found.')
    elif last_win_error_num == '193': # Error 193 = '%1 is not
    a valid Win32 application'
    logger.critical('Could not execute ' +
    queue[position].sox_exe + ': It\'s not a valid Win32 application.')
    break
    wav_pipe = sox_proc.stdout
    else:
    wav_pipe = ffmpeg_proc.stdout
    try:
    nero_aac_proc = subprocess.Popen(queue[position].nero_aac_cmd,
    stdin=wav_pipe)
    except WindowsError:
    error_info = str(sys.exc_info()[1])
    last_win_error_num = find_win_error_no(error_msg=error_info)
    if last_win_error_num == '2': # Error 2 = 'The system cannot
    find the file specified'
    logger.critical('Could not execute ' +
    queue[position].sox_exe + ': File not found.')
    elif last_win_error_num == '193': # Error 193 = '%1 is not a
    valid Win32 application'
    logger.critical('Could not execute ' +
    queue[position].sox_exe + ': It\'s not a valid Win32 application.')
    break

    ffmpeg_proc.wait()
    if queue[position].vol != 1:
    sox_proc.wait()
    nero_aac_proc.wait()
    break
    Note: those break statements are there to break out of the while loop
    this is in.
    Firstly, that first assignment to ffmpeg_proc raises an exception:
    Traceback (most recent call last):
    File "C:\Users\Bahamut\workspace\Disillusion\disillusion.py", line
    288, in <module>
    ffmpeg_proc = subprocess.Popen(queue[position].ffmpeg_cmd,
    stdout=subprocess.PIPE, stderr=os.devnull)
    File "C:\Python32\lib\subprocess.py", line 700, in __init__
    errread, errwrite) = self._get_handles(stdin, stdout, stderr)
    File "C:\Python32\lib\subprocess.py", line 861, in _get_handles
    errwrite = msvcrt.get_osfhandle(stderr.fileno())
    AttributeError: 'str' object has no attribute 'fileno'
    I'm not really sure what it's complaining about since the exception
    propagates from the msvcrt module through the subprocess module into my
    program. I'm thinking it has to do my stderr assignment, but if that's
    not right, I don't know what is.
    os.devnull is a string, but you need a writable file:
    subprocess.call(["ls"], stdout=os.devnull)
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/lib/python2.6/subprocess.py", line 470, in call
    return Popen(*popenargs, **kwargs).wait()
    File "/usr/lib/python2.6/subprocess.py", line 614, in __init__
    errread, errwrite) = self._get_handles(stdin, stdout, stderr)
    File "/usr/lib/python2.6/subprocess.py", line 971, in _get_handles
    c2pwrite = stdout.fileno()
    AttributeError: 'str' object has no attribute 'fileno'
    subprocess.call(["ls"], stdout=open(os.devnull, "w"))
    Secondly, there are no Popen.stdout.close() calls because I'm not sure
    where to put them.
    Thirdly, I have nearly identical except WindowsError: blocks repeated -
    I'm sure I can avoid this with decorators as suggested in a recent
    thread, but I haven't learned decorators yet. This code isn't very
    complete; I'm trying to get it to work in ideal conditions first, then
    worry about how to handle failure.
    Start with factoring out common code into a good old function.
    Using Python 3 on Windows 7.
  • Andrew Berg at Jun 28, 2011 at 6:47 am

    On 2011.06.28 01:32 AM, Peter Otten wrote:
    subprocess.call(["ls"], stdout=open(os.devnull, "w"))
    D'oh! Not sure why I was thinking os.devnull was a file object. :-[
    Start with factoring out common code into a good old function.
    For some reason I was thinking I would have problems doing that, but
    looking at it again, I could probably refactor that into a really nice
    function that logs at least all the common Windows error codes that may
    arise.

    Thanks for pointing those out.
  • Chris Rebert at Jun 28, 2011 at 6:52 am

    On Mon, Jun 27, 2011 at 11:47 PM, Andrew Berg wrote:
    On 2011.06.28 01:32 AM, Peter Otten wrote:
    subprocess.call(["ls"], stdout=open(os.devnull, "w"))
    D'oh! Not sure why I was thinking os.devnull was a file object. :-[
    On the bright side, I think in part due to this /exact/
    misunderstanding, in bleeding-edge Python v3.3 you can now write:
    subprocess.call(["ls"], stdout=subprocess.DEVNULL)
    http://docs.python.org/dev/library/subprocess.html#subprocess.DEVNULL

    Cheers,
    Chris
  • Andrew Berg at Jul 1, 2011 at 1:40 am
    Okay, so I've refactored those except WindowsError blocks into calls to
    a function and fixed the os.devnull bug, but I still can't get the
    triple chain working. I added calls to ffmpeg_proc.stdout.close() and
    sox_proc.stdout.close(), but I really am not sure where to put them. The
    following code works if SoX isn't part of the chain (that is, if vol ==
    1), but not otherwise (the Nero encoder says "truncation error" after it
    finishes; the same error I get if omit the close() calls):
    while True:
    if queue[position].audio:
    if queue[position].vol != 1:
    queue[position].ffmpeg_cmd = [
    queue[position].ffmpeg_exe,
    '-i', queue[position].ifile,
    '-f', 'sox', '-'
    ]
    queue[position].sox_cmd = [
    queue[position].sox_exe,
    '-t', 'sox', '-',
    '-t', 'wav', '-',
    'vol', str(queue[position].vol)
    ]
    else:
    queue[position].ffmpeg_cmd = [
    queue[position].ffmpeg_exe,
    '-i', queue[position].ifile,
    '-f', 'wav', '-'
    ]
    queue[position].nero_aac_cmd = [
    queue[position].nero_aac_exe,
    '-ignorelength',
    '-q', str(queue[position].aac_quality),
    '-if', '-',
    '-of', queue[position].outdir + queue[position].prefix + '.m4a'
    ]
    print(queue[position].ffmpeg_cmd)
    print(queue[position].sox_cmd)
    print(queue[position].nero_aac_cmd)
    try:
    ffmpeg_proc = subprocess.Popen(queue[position].ffmpeg_cmd,
    stdout=subprocess.PIPE, stderr=open(os.devnull, 'w'))
    except WindowsError as exc:
    log_windows_error(exc, queue[position].ffmpeg_cmd, 'critical')
    break
    if queue[position].vol != 1:
    try:
    sox_proc = subprocess.Popen(queue[position].sox_cmd,
    stdin=ffmpeg_proc.stdout, stdout=subprocess.PIPE,
    stderr=open(os.devnull, 'w'))
    wav_pipe = sox_proc.stdout
    except WindowsError as exc:
    log_windows_error(exc, queue[position].sox_cmd, 'critical')
    break
    else:
    wav_pipe = ffmpeg_proc.stdout
    try:
    nero_aac_proc = subprocess.Popen(queue[position].nero_aac_cmd,
    stdin=wav_pipe)
    except WindowsError as exc:
    log_windows_error(exc, queue[position].nero_aac_cmd, 'critical')
    break
    finally:
    ffmpeg_proc.stdout.close()
    if queue[position].vol != 1:
    sox_proc.stdout.close()
    ffmpeg_proc.wait()
    if queue[position].vol != 1:
    sox_proc.wait()
    nero_aac_proc.wait()
    break
  • Peter Otten at Jul 1, 2011 at 7:26 am

    Andrew Berg wrote:

    Okay, so I've refactored those except WindowsError blocks into calls to
    a function and fixed the os.devnull bug, but I still can't get the
    triple chain working. I added calls to ffmpeg_proc.stdout.close() and
    sox_proc.stdout.close(), but I really am not sure where to put them. The
    following code works if SoX isn't part of the chain (that is, if vol ==
    1), but not otherwise (the Nero encoder says "truncation error" after it
    finishes; the same error I get if omit the close() calls):
    I can't reproduce your setup, but I'd try using communicate() instead of
    wait() and close().
  • Andrew Berg at Jul 1, 2011 at 8:02 am

    On 2011.07.01 02:26 AM, Peter Otten wrote:
    I can't reproduce your setup, but I'd try using communicate() instead of
    wait() and close().
    I don't really know what communicate() does. The docs don't give much
    info or any examples (that explain communicate() anyway), and don't say
    when communicate() is useful.
  • Chris Rebert at Jul 1, 2011 at 8:24 am

    On Fri, Jul 1, 2011 at 1:02 AM, Andrew Berg wrote:
    On 2011.07.01 02:26 AM, Peter Otten wrote:
    I can't reproduce your setup, but I'd try using communicate() instead of
    wait() and close().
    I don't really know what communicate() does.
    "Read data from stdout and stderr, until end-of-file is reached. Wait
    for process to terminate."
    It then returns the read data as two strings. It's pretty straightforward.
    The docs don't give much
    info or any examples (that explain communicate() anyway), and don't say
    when communicate() is useful.
    They are slightly roundabout in that respect. The warnings for .wait()
    and .stdout/err explain communicate()'s utility:
    "Warning: This will deadlock when using stdout=PIPE and/or stderr=PIPE
    and the child process generates enough output to a pipe such that it
    blocks waiting for the OS pipe buffer to accept more data. ***Use
    communicate() to avoid that.***" [emphasis added]

    Cheers,
    Chris
  • Andrew Berg at Jul 2, 2011 at 12:25 pm

    This code is working:
    try:
    ffmpeg_proc = subprocess.Popen(queue[position].ffmpeg_cmd,
    stdout=subprocess.PIPE, stderr=open(os.devnull, 'w'))
    except WindowsError as exc:
    log_windows_error(exc, queue[position].ffmpeg_cmd, 'critical')
    break
    if queue[position].vol != 1:
    try:
    sox_proc = subprocess.Popen(queue[position].sox_cmd,
    stdin=ffmpeg_proc.stdout, stdout=subprocess.PIPE,
    stderr=open(os.devnull, 'w'))
    wav_pipe = sox_proc.stdout
    except WindowsError as exc:
    log_windows_error(exc, queue[position].sox_cmd, 'critical')
    break
    finally:
    ffmpeg_proc.stdout.close()
    else:
    wav_pipe = ffmpeg_proc.stdout
    try:
    nero_aac_proc = subprocess.Popen(queue[position].nero_aac_cmd,
    stdin=wav_pipe)
    except WindowsError as exc:
    log_windows_error(exc, queue[position].nero_aac_cmd, 'critical')
    break
    finally:
    if queue[position].vol != 1:
    sox_proc.stdout.close()
    else:
    ffmpeg_proc.stdout.close()
    ffmpeg_proc.wait()
    if queue[position].vol != 1:
    sox_proc.wait()
    nero_aac_proc.wait()
    I can't figure out what I changed since the last time I tried and
    failed, though; I only ran it again after directing the stderr of FFmpeg
    and SoX to actual files to see if they could gives me any clues.
  • Thomas Rachel at Jun 28, 2011 at 7:44 am

    Am 28.06.2011 07:57 schrieb Andrew Berg:
    I'm working on an audio/video converter script (moving from bash to
    Python for some extra functionality), and part of it is chaining the
    audio decoder (FFmpeg) either into SoX to change the volume and then to
    the Nero AAC encoder or directly into the Nero encoder. This is the
    chunk of code from my working bash script to give an idea of what I'm
    trying to accomplish (it's indented because it's nested inside a while
    loop and an if statement):
    if [ "$process_audio" = "true" ]
    then
    if [ $vol == 1.0 ]
    then
    ffmpeg -i "${ifile_a}" -f wav - 2>$nul | neroaacenc
    -ignorelength -q 0.4 -if - -of ${prefix}${zero}${ep}.m4a
    else
    # the pipeline-as-file option of sox fails on Windows
    7, so I use the safe method since there's only one pipeline going into sox
    ffmpeg -i "${ifile_a}" -f sox - 2>$nul | sox -t sox -
    -t wav - vol $vol 2>$nul | neroaacenc -ignorelength -q 0.4 -if - -of
    ${prefix}${zero}${ep}.m4a
    fi
    else
    echo "Audio skipped."
    fi
    This is pretty easy and straightforward in bash, but not so in Python.
    This is what I have in Python (queue[position] points to an object I
    create earlier that holds a bunch of info on what needs to be encoded -
    input and output file names, command line options for the various
    encoders used, and so forth), but clearly it has some problems:
    try:
    ffmpeg_proc = subprocess.Popen(queue[position].ffmpeg_cmd,
    stdout=subprocess.PIPE, stderr=os.devnull)
    except WindowsError:
    error_info = str(sys.exc_info()[1])
    last_win_error_num = find_win_error_no(error_msg=error_info)
    if last_win_error_num == '2': # Error 2 = 'The system cannot
    find the file specified'
    logger.critical('Could not execute ' +
    queue[position].ffmpeg_exe + ': File not found.')
    elif last_win_error_num == '193': # Error 193 = '%1 is not a
    valid Win32 application'
    logger.critical('Could not execute ' +
    queue[position].ffmpeg_exe + ': It\'s not a valid Win32 application.')
    break
    if queue[position].vol != 1:
    try:
    sox_proc = subprocess.Popen(queue[position].sox_cmd,
    stdin=ffmpeg_proc.stdout, stdout=subprocess.PIPE, stderr=os.devnull)
    except WindowsError:
    error_info = str(sys.exc_info()[1])
    last_win_error_num = find_win_error_no(error_msg=error_info)
    if last_win_error_num == '2': # Error 2 = 'The system
    cannot find the file specified'
    logger.critical('Could not execute ' +
    queue[position].sox_exe + ': File not found.')
    elif last_win_error_num == '193': # Error 193 = '%1 is not
    a valid Win32 application'
    logger.critical('Could not execute ' +
    queue[position].sox_exe + ': It\'s not a valid Win32 application.')
    break
    wav_pipe = sox_proc.stdout
    else:
    wav_pipe = ffmpeg_proc.stdout
    try:
    nero_aac_proc = subprocess.Popen(queue[position].nero_aac_cmd,
    stdin=wav_pipe)
    except WindowsError:
    error_info = str(sys.exc_info()[1])
    last_win_error_num = find_win_error_no(error_msg=error_info)
    if last_win_error_num == '2': # Error 2 = 'The system cannot
    find the file specified'
    logger.critical('Could not execute ' +
    queue[position].sox_exe + ': File not found.')
    elif last_win_error_num == '193': # Error 193 = '%1 is not a
    valid Win32 application'
    logger.critical('Could not execute ' +
    queue[position].sox_exe + ': It\'s not a valid Win32 application.')
    break

    ffmpeg_proc.wait()
    if queue[position].vol != 1:
    sox_proc.wait()
    nero_aac_proc.wait()
    break
    Note: those break statements are there to break out of the while loop
    this is in.
    Firstly, that first assignment to ffmpeg_proc raises an exception:
    Traceback (most recent call last):
    File "C:\Users\Bahamut\workspace\Disillusion\disillusion.py", line
    288, in<module>
    ffmpeg_proc = subprocess.Popen(queue[position].ffmpeg_cmd,
    stdout=subprocess.PIPE, stderr=os.devnull)
    File "C:\Python32\lib\subprocess.py", line 700, in __init__
    errread, errwrite) = self._get_handles(stdin, stdout, stderr)
    File "C:\Python32\lib\subprocess.py", line 861, in _get_handles
    errwrite = msvcrt.get_osfhandle(stderr.fileno())
    AttributeError: 'str' object has no attribute 'fileno'
    I'm not really sure what it's complaining about since the exception
    propagates from the msvcrt module through the subprocess module into my
    program. I'm thinking it has to do my stderr assignment, but if that's
    not right, I don't know what is.
    Secondly, there are no Popen.stdout.close() calls because I'm not sure
    where to put them.
    Thirdly, I have nearly identical except WindowsError: blocks repeated -
    I'm sure I can avoid this with decorators as suggested in a recent
    thread, but I haven't learned decorators yet.
    There is a variety of possibilities. As you are a starter, a function is
    prefecty fine, as Peter already pointed out. Then you have something like

    def handle_winerr(exc):
    error_info = str(exc)
    last_win_error_num = find_win_error_no(error_msg=error_info)
    if last_win_error_num == '2': # Error 2 = 'The system cannot find
    the file specified'
    logger.critical('Could not execute ' +
    queue[position].sox_exe + ': File not found.')
    elif last_win_error_num == '193': # Error 193 = '%1 is not a valid
    Win32 application'
    logger.critical('Could not execute ' +
    queue[position].sox_exe + ': It\'s not a valid Win32
    application.')

    try:
    <do_stuff>
    except WindowsError:
    exc = sys.exc_info()[1]
    handle_winerr(exc)
    break


    On the next step, you could write like this:

    try:
    <do_stuff>
    except WindowsError, exc:
    handle_winerr(exc)
    break


    The way you work with the exception is not the very best - instead of
    parsing the stringified exception, you better would trigger on
    exc.winerror (it is an integer with the error number).

    Or, even better, just pas the error information contained in the exception:

    def handle_winerr(exc):
    logger.critical('Could not execute %s: %s' %
    (queue[position].sox_exe, exc.strerror))


    Next step: If you always break out of the loop when there is an error,
    you could as well do the error handling outside the loop:


    try:
    while <whatever>:
    <do_stuff>
    except WindowsError, exc:
    handle_winerr(exc)



    In the following, I'm pointing out some more or less advanced techniques
    which you also could use.

    If you want to, you can create a context manager dealing with the stuff:

    import contextlib

    @contextlib.contextmanager
    def winerr_handling():
    try:
    yield None
    except WindowsError, exc:
    handle_winerr(exc) # <-- the function from above

    and then write

    with winerr_handling():
    while <whatever>:
    <do_stuff>

    And, if you absolutely want a decorator, you can do so:

    def make_exc_ctx(hdlr):
    from functools import wraps
    @wraps(hdlr)
    def wrapper():
    try:
    yield None
    except WindowsError, exc:
    hdlr(exc) # <-- the function from above


    and then

    @make_exc_ctx
    def winerr_handling(exc):
    logger.critical('Could not execute %s: %s' %
    (queue[position].sox_exe, exc.strerror))

    with winerr_handling():
    while <whatever>:
    <do_stuff>


    HTH,

    Thomas
  • Andrew Berg at Jun 28, 2011 at 8:09 am

    On 2011.06.28 02:44 AM, Thomas Rachel wrote:
    The way you work with the exception is not the very best - instead of
    parsing the stringified exception, you better would trigger on
    exc.winerror (it is an integer with the error number).

    Or, even better, just pas the error information contained in the exception:

    def handle_winerr(exc):
    logger.critical('Could not execute %s: %s' %
    (queue[position].sox_exe, exc.strerror))
    I didn't see winerror and strerror in the docs before, but another look
    and they are indeed documented. I brought up Windows error codes before,
    and I'm surprised no one pointed this out. Thanks for that.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedJun 28, '11 at 5:57a
activeJul 2, '11 at 12:25p
posts11
users4
websitepython.org

People

Translate

site design / logo © 2022 Grokbase