[Python-ideas] PEP-3151 pattern-matching

Devin Jeanpierre jeanpierreda at gmail.com
Thu Apr 7 08:59:12 CEST 2011


Hello,

PEP-3151 < http://www.python.org/dev/peps/pep-3151/ > mentions a
really weird syntax for pattern-matching. I was hoping I could suggest
an alternative that's both more concise, and possible to implement
without doing something drastic like changing existing syntax or
semantics.

The PEP offers the pattern-matching syntax:

> except IOError as e if e.errno == errno.ENOENT: ...

I'd instead suggest something along the lines of

> except io_error(errno.ENOENT): ...

Implementing this is fairly straightforward, I've included it in the
bottom of this email. Raising an exception becomes `raise
io_error(errno.ENOENT)(msg)`. Some notational sugar can be implemented
(for example, `raise io_error(errno.ENOENT, msg)` could also be made
to work). I'm not fussed about the details.

I personally prefer keeping the errnos as a big part of handling
exceptions, they're common across OSes and involve less research /
memorization for those that are already aware of errno. I guess what
I'd like to see is the same exception hierarchy proposed by the PEP,
but with the addition of allowing errnos to be specified by
pattern-matching, so that errors not covered by the hierarchy, or more
specific than the hierarchy, can be concisely caught. However, I'm not
really well-versed in the pros and cons for all of this.

Above all, I'd like for the pattern matching alternative to be a bit
more reasonable. It doesn't have to be verbose and it doesn't have to
involve new syntax. Apologies for any mistakes in the code, they are
my own.

Here's the code:


# evil global state or something
error_classes = {}

def io_error(errno_, msg=None): # or something, you get the idea
    try:
        cls = error_classes[errno_]
    except LookupError:
        class IOErrorWithErrno(IOError):
            errno = errno_

        cls = error_classes[errno_] = IOErrorWithErrno

    return error_classes[errno_]


# example of usage
import errno
try:
    raise io_error(errno.ENOENT)("<Error message>")
except io_error(errno.ENOENT):
    print("success")


Thanks for your time!
Devin Jeanpierre



More information about the Python-ideas mailing list