Python - except (OSError, e) - No longer working in 3.3.3?

Torxed picture Torxed · Dec 11, 2013 · Viewed 47.5k times · Source

The following have worked throughout Python 3.X and is not broke in 3.3.3, can't find what's changed in the docs.

import os

def pid_alive(pid):
    pid = int(pid)
    if pid < 0:
        return False
    try:
        os.kill(pid, 0)
    except (OSError, e):
        return e.errno == errno.EPERM
    else:
        return True

Tried different variations of the except line, for instance except OSError as e: but then errno.EPERM breaks etc.

Any quick pointers?

Answer

Martijn Pieters picture Martijn Pieters · Dec 11, 2013

The expression except (OSError, e) never worked in Python, not in the way you think it works. That expresion catches two types of exception; OSError or whatever the global e refers to. Your code breaks when there is no global name e.

The correct expression for Python 3 and Python 2.6 and newer is:

except OSError as e:

Python 2 also supports the syntax:

except OSError, e:

without parenthesis, or:

except (OSError, ValueError), e:

to catch more than one type. The syntax was very confusing, as you yourself discovered here.

The change was added in Python 2.6 and up, see PEP 3110 - Catching Exceptions in Python 3000 and the Exception-handling changes section of the 2.6 What's New document.

As for an exception for errno.EPERM; you didn't import errno, so that is a NameError as well.