On Apr 10, 2015, at 12:54, Travis Everett <travis.a.everett@gmail.com> wrote:

Hi all,

I have a specialized use case for exceptions which need to analyze their __cause__ property before they're fully initialized. The property isn't set until after init, and (forgive my ignorance of Python's source!) appears to be done at the C level in a way that it can't be observed with a property setter or __setattr__. I currently create a method to do this post-init work as a workaround, and push the burden of making sure it gets called on the code using the exceptions--but this makes the exceptions idiomatic and error-prone.

A magic method called once all of the special exception properties are already set would suffice. The exception could define something like __raised__(self) to react to the new values of those properties.

A more comprehensive approach might be a __raise__(self, cause, context, traceback...) method which has full control over setting the properties, but I assume there are good reasons why the usual channels (setters and __setattr__) are cut out of the loop.

I'd assume the only reasons are to make the code a bit simpler and a bit more efficient.

Adding some new __raise__ or __raised__ special-purpose protocol doesn't seem like it would be any simpler or more efficient than just changing the existing APIs to access the attributes via SetAttr, which would give you what you want without being a special case.

Also notice that there's an open PEP (https://www.python.org/dev/peps/pep-0490/) to make the C API for raising exceptions automatically set the context instead of forcing it to be done manually (with a private API function), as a few builtin and stdlib functions do. So it seems safer to change things in a way that would work equally well with the current APIs, with that change, and with all reasonable alternatives to that change--and again, using SetAttr seems like the simplest way to make sure of that.

But either way, it's a relatively local and simple change in Objects/exceptions.c.

I suspect the big thing you'd need to get this accepted is to show that the performance cost is negligible. Do you know how to run appropriate benchmarks and present the results if someone else writes the patch?

I was encouraged to bring discussion here (to see if there's any traction) after opening an enhancement request (http://bugs.python.org/issue23902).

Python-ideas mailing list
Code of Conduct: http://python.org/psf/codeofconduct/