[Python-ideas] PEP-3151 pattern-matching

Mike Graham mikegraham at gmail.com
Fri Apr 8 16:04:50 CEST 2011


On Thu, Apr 7, 2011 at 2:59 AM, Devin Jeanpierre <jeanpierreda at gmail.com> wrote:
> 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

I don't see how either solution is better than continuing to do what
we have right now. The PEP's idea introduces new syntax for a problem
that is currently solved in two lines. Your suggestion makes a new
pattern within the Python exception world, and further helps make the
exception hierarchy a little harder to understand again.

Neither of these seem justified for a rare case (this sort of patter
is fairly rare, most notably this one example) when there's nothing
that awful about the current solution.

Mike



More information about the Python-ideas mailing list