[Python-Dev] Avoid formatting an error message on attribute error

Nick Coghlan ncoghlan at gmail.com
Thu Nov 7 23:01:29 CET 2013


On 8 Nov 2013 04:44, "Brett Cannon" <brett at python.org> wrote:
> On Thu, Nov 7, 2013 at 7:41 AM, Nick Coghlan <ncoghlan at gmail.com> wrote:
>>
>> The bigger problem is you can't change the constructor signature in a
backwards incompatible way. You would need a new class method as an
alternative constructor instead, or else use optional parameters.
>
>
> The optional parameter approach is the one ImportError took for
introducing its `name` and `path` attributes, so there is precedent.
Currently it doesn't use a default exception message for
backwards-compatibility, but adding one wouldn't be difficult technically.
>
> In the case of AttributeError, what you could do is follow the suggestion
I made in http://bugs.python.org/issue18156 and add an `attr` keyword-only
argument and correpsonding attribute to AttributeError. If you then add
whatever other keyword arguments are needed to generate a good error
message (`object` so you have the target, or at least get the string name
to prevent gc issues for large objects?) you could construct the message
lazily in the __str__ method very easily while also doing away with
inconsistencies in the message which should make doctest users happy. Lazy
message creation through __str__ does leave the message out of `args`,
though.
>
> In a perfect world (Python 4 maybe?) BaseException would take a single
argument which would be an optional message, `args` wouldn't exist, and
people called `str(exc)` to get the message for the exception. That would
allow subclasses to expand the API with keyword-only arguments to carry
extra info and have reasonable default messages that were built on-demand
when __str__ was called. It would also keep `args` from just being a
dumping ground of stuff that has no structure except by calling convention
(which is not how to do an API; explicit > implicit and all). IOW the
original dream of PEP 352 (
http://python.org/dev/peps/pep-0352/#retracted-ideas).

A related problem (that rich exceptions cause, rather than solve) is one I
encountered recently in trying to improve the error messages thrown by the
codec machinery to ensure they mention the specific codec operation that
failed: you can't easily create a copy of a rich exception with all the
same attributes, but a different error message (at least through the C API
- copy.copy may work at the Python level, but I don't want to make the
codec infrastructure depend on the copy module).

Rich exception types that require more than one parameter are also
incompatible with PyErr_Format in general.

For the current patch [1], I've "solved" the problem by whitelisting a
common set of types that the chaining code knows how to handle, but it
would be good to have some kind of BaseException.replace() API that did the
heavy lifting and returned None rather than throwing an exception if
replacement wasn't supported (since blindly bitwise copying instance
objects isn't safe for subclasses that add extra C level pointers and
throwing an exception would be really annoying for exception chaining code
that wants to reraise the original exception if replacement isn't possible).

Cheers,
Nick.

[1] http://bugs.python.org/issue17828
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20131108/2a2636f3/attachment.html>


More information about the Python-Dev mailing list