[Python-ideas] Arguments to exceptions

Paul Moore p.f.moore at gmail.com
Mon Jul 3 17:44:20 EDT 2017


On 3 July 2017 at 21:56, Jeff Walker <jeff.walker00 at yandex.com> wrote:
> Paul,
>      Indeed, nothing gets better until people change the way they do their
> exceptions. Ken's suggested enhancement to BaseException does not
> directly solve the problem, but it removes the roadblocks that discourage
> people from passing the components to the message.

As noted, I disagree that people are not passing components because
str(e) displays them the way it does. But we're both just guessing at
people's motivations, so there's little point in speculating.

> Seems to me that to address this problem, four things are needed:
> 1. Change BaseException. This allows people to pass the components
>     to the message without ruining str(e).

I dispute this is the essential place to start. If nothing else, the
proposed approach encourages people to use a position-based "args"
attribute for exceptions, rather than properly named attributes.

> 2. A PEP that educates the Python community on this better way of
>     writing exceptions.

Educating the community can be done right now, and doesn't need a PEP.
Someone could write a blog post, or an article, that explains how to
code exception classes, how to create the exceptions, and how client
code can/should use the API. This can be done now, all you need to do
is to start with "at the moment, BaseException doesn't implement these
features, so you should create an application-specific base exception
class to minimise duplication of code". If project authors take up the
proposed approach, then that makes a good argument for moving the
supporting code into the built in BaseException class.

> 3. Changes to the base language and standard library to employ the
>     new approach. These would changes would be quite small and could
>     be done opportunistically.

And I've never said that there's a problem with these. Although I do
dispute that using an args list is the best approach here - I'd much
rather see NameError instances have a "name" attribute that had the
name that couldn't be found as its value. Opportunistic changes to
built in exceptions can implement the most appropriate API for the
given exception - why constrain such changes to a "lowest common
denominator" API that is ideal for no-one?

class NameError(BaseException):
    def __init__(self, name):
        self.name = name
    def __str__(self):
        return f"name '{self.name}' is not defined"

Of course, that's not backward compatible as it stands, but it could
probably be made so, just as easily as implementing the proposed
solution.

> 4. Time. Over time things will just get better as more people see the
>     benefits of this new approach to exceptions and adopt it. And if they
>     don't, we are no worse off than we are now.

The same could be said of any improved practice. And I agree, let's
encourage people to learn to write better code, and promote good
practices. There's definitely no reason not to do this.

> And frankly, I don't see any downside. The changes he is proposing are
> tiny and simple and backward compatible.

Well, the main downside I see is that I don't agree that the proposed
changes are the best possible approach. Implementing them in the built
in exceptions therefore makes it harder for people to choose better
approaches (or at least encourages them not to look for better
approaches). There's no way I'd consider that e.args[0] as a better
way to get the name that triggered a NameError than e.name.

This seems to me to be something that should be experimented with and
proven outside of the stdlib, before we rush to change the language. I
don't see anything that makes that impossible.

Paul


More information about the Python-ideas mailing list