[Python-Dev] unicode Exception messages in py2.7

Steven D'Aprano steve at pearwood.info
Fri Nov 15 06:42:07 CET 2013

On Fri, Nov 15, 2013 at 02:28:48PM +1100, Cameron Simpson wrote:

> > Non-ascii Unicode strings are just a special case of the more general 
> > problem of what to do if printing the exception raises. If 
> > str(exception.message) raises, suppressing the message seems like a 
> > perfectly reasonable approach to me.
> Not to me. Silent failure is really nasty. In fact, doesn't the Zen
> speak explicitly against it?

But its not really a silent failure, since you're already dealing with 
an exception, and that's the important one. The original exception is 
not suppressed, just the error message. If the original exception was 
replaced with a different exception:

    # this doesn't actually happen
    py> raise ValueError(u"¿what?")
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    TypeError: error displaying exception message

or lost altogether:

    # neither does this
    py> raise ValueError(u"¿what?")

then I would consider that a bug. Ideally, we should get a chained 
exception so you can see both the original and subsequent exceptions:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xbf' in 
position 0: ordinal not in range(128)

but Python 2 doesn't have chained exceptions so that's not an option.

As for the Zen, the nice thing about that is that it can argue both 
sides of most questions :-) The Zen has something else to say about 
this: Special cases aren't special enough to break the rules.

Except as the next line in the Zen suggests, sometimes they are :-)

UnicodeEncoding errors are just a special case of arbitrary objects that 
can't be converted to byte strings. If the exception message can't be 
stringified, in general there's really nothing you can do about it. I 
suppose one might argue for inserting a meta-error message:

    ValueError: ***the error message could not be displayed***

but that strikes me as too subtle, potentially confusing, and generally 
problematic. Ultimately, in the absense of chained exceptions I don't 
think there's any good solution to the general problem, and I'm not 
convinced that treating Unicode strings as a special case is justified. 
It's been at least four, and possibly six (back to 2.2) point releases 
with this behaviour, and until now apparently nobody has noticed.


More information about the Python-Dev mailing list