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 ethan.furman
Recipients Arfrever, Tyler.Crompton, ethan.furman, ncoghlan
Date 2012-06-28.16:08:14
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <4FEC846F.8020006@stoneleaf.us>
In-reply-to <1340894637.46.0.0674161925355.issue15209@psf.upfronthosting.co.za>
Content
Tyler Crompton wrote:
> I'm in a little over my head as I can't conceptualize __cause__, so I may be looking over things.
> 
> First, you, Ethan, said the following:
> 
>> It's also not difficult to work around if you really want to toss the extra info:
>>
>>        except NameError:
>>            try:
>>                fallback_module.getch()
>>            except Exception as exc:
>>                raise exc from None
>>
>> A total of three more words to get the desired behavior (and small ones at that).
> 
> Counter-argument: if it's just three words, then why was the shorthand without the from clause implemented in the first place?

I'm not sure I understand the question -- do you mean why can we do 
'raise' by itself to re-raise an exception?  'from' is new, and was 
added in Py3k (see below).  'raise', as a shortcut, is there to allow 
clean-up (or whatever) in the except clause before re-raising the same 
exception.

In 3.0 exceptions were enhanced to include a link to previous 
exceptions.  So if you are handling exception A and exception B occurs, 
exception B will be raised and will have a link to A.  That link is kept 
in __context__.  This complete chain will then be printed if the last 
exception raised is uncaught.

However, there are times when you may want to add more exception 
information yourself, so we have the `from` clause, which store the 
extra exception in __cause__.

And, there are times when you are changing from one exception to another 
and do not want the previous one displayed -- so we now have 'from None' 
(which sets __suppress_context__ to True).  So if some underlying 
function raises ValueError, but you want to transform that to an 
XyzError, your can do:

     try:
         some_function()
     except ValueError:
         raise XyzError from None

and then, if the exception is uncaught and printed, only the XyzError 
will be displayed (barring custom print handlers).

> My use case was primarily based on the idea that the unavailability of the windows module (from the example) is irrelevant information to, say, Unix users. When an exception is raised, the user shouldn't have to see any Windows-related exceptions (that is if there is an alternate solution).

So you are using the absence of the Windows based module as evidence 
that you are not running on Windows... but what if you are on Windows 
and there is some other problem with that module?

The usual way to code for possible different modules is:

     try:
         import windows_module as utils  # or whatever name
     except ImportError:
         import fallback_module as utils
History
Date User Action Args
2012-06-28 16:08:16ethan.furmansetrecipients: + ethan.furman, ncoghlan, Arfrever, Tyler.Crompton
2012-06-28 16:08:15ethan.furmanlinkissue15209 messages
2012-06-28 16:08:14ethan.furmancreate