This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author abarry
Recipients abarry, r.david.murray, xiang.zhang, ztane
Date 2016-08-21.16:27:48
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1471796868.81.0.379385981847.issue27823@psf.upfronthosting.co.za>
In-reply-to
Content
Attached patch changes bare attribute errors to add a useful error message. As such, `raise AttributeError` and `raise AttributeError(None)` (but not `raise AttributeError('')` for example) inside any of the attribute lookup or descriptor methods (__getattribute__, __getattr__, __setattr__, __delattr__, __get__, __set__, and __delete__). This is a followup to #27794.

As such, the following is now much more useful and less boilerplate:

class A:
    _dynamic_names = {}
    def __getattr__(self, name):
        if name in self._dynamic_names:
            return self._dynamic_names[name]
        raise AttributeError

Then, doing the following:

A().spam

Will result in a `AttributeError("'A' object has no attribute 'spam'")`, while keeping the original traceback. The patch is pretty much complete, but I have a few concerns:

- Performance hit, especially on something that's used virtually everywhere and everytime (attribute access); although PEP 487's __set_name__ lookup already hurts performance slightly. The few micro-benchmarks I ran weren't very significant, but there is a small drop in performance nonetheless.
- Four new PyErr_* API functions, one which isn't used in the current patch, but since it's 3 lines I decided to leave it in anyway.
- I don't carry over the cause or context of the raised exception to the new one. Keeping the traceback around is pretty trivial, since it has its own slot in the thread state struct, but since not all exceptions are actual exceptions at the C level (and the new exceptions I raise aren't either, at the C level), I don't know how to carry over context or cause.

Oh, and exceptions set at the C level with e.g. `PyErr_SetNone` are also properly handled that way; this would fix #27794 as a side-effect, but a few lines will need to be changed (in Objects/descrobject.c) for this to work. Such changes are not included with the patch.

Thoughts, concerns, opinions, ideas? Maybe something I didn't think of?
History
Date User Action Args
2016-08-21 16:27:50abarrysetrecipients: + abarry, r.david.murray, ztane, xiang.zhang
2016-08-21 16:27:48abarrysetmessageid: <1471796868.81.0.379385981847.issue27823@psf.upfronthosting.co.za>
2016-08-21 16:27:48abarrylinkissue27823 messages
2016-08-21 16:27:48abarrycreate