Re: [Python-ideas] suppressing exception context when it is not relevant

2016-10-10 Thread Nick Coghlan
On 11 October 2016 at 10:43, Václav Dvořák  wrote:
> But I find this misleading, as the original KeyError is not really an error
> at all. I could of course avoid the situation by changing the try/except
> (EAFP) into a test for the key's presence (LBYL) but that's not very
> Pythonic and less thread-friendly (not that the above is thread-safe as is,
> but that's beside the point). Also, yes, I could instead subclass dict and
> implement __missing__, but that's only a solution for this particular case.
> The problem (if you agree it's a problem) occurs any time an exception is
> not actually an error, but rather a condition that just happens to be
> indicated by an exception.
>
> It's unreasonable to expect all code in some_api to change their raise X to
> raise X from None (and it wouldn't even make sense in all cases). Is there a
> clean solution to avoid the unwanted exception chain in the error message?

Yes, you can restructure the code so you're not doing further work in
the exception handler, and instead do the work after the try/except
block finishes and the exception context is cleared automatically:

value = MISSING = object()
try:
value = cache_dict[key]
except KeyError:
pass
if value is MISSING:
value = some_api.get_the_value_via_web_service_call(key)
cache_dict[key] = value

(This is the general case of MRAB's answer, as the try/except
KeyError/pass pattern above is what dict.get() implements)

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Re: [Python-ideas] suppressing exception context when it is not relevant

2016-10-10 Thread MRAB

On 2016-10-11 01:43, Václav Dvořák wrote:

I'm aware of "raise ... from None" (from PEP 415). However, how can I
achieve that same effect (of suppressing the "During handling of the
above exception, another exception occurred" message) without having
control over the code that is executed from the except clause? I thought
that sys.exc_clear() could be used for this, but that function doesn't
exist in Python 3 anymore.

Why would I want this? I have some simple caching code that looks like
(simplified):

try:
value = cache_dict[key]
except KeyError:
value = some_api.get_the_value_via_web_service_call(key)
cache_dict[key] = value


When there's an exception in the API call, the output will be something
like this:

Traceback (most recent call last):
  File ..., line ..., in ...
KeyError: '...'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File ..., line ..., in ...
some_api.TheInterestingException: ...


But I find this misleading, as the original KeyError is not really an
error at all. I could of course avoid the situation by changing the
try/except (EAFP) into a test for the key's presence (LBYL) but that's
not very Pythonic and less thread-friendly (not that the above is
thread-safe as is, but that's beside the point). Also, yes, I could
instead subclass dict and implement __missing__, but that's only a
solution for this particular case. The problem (if you agree it's a
problem) occurs any time an exception is not actually an error, but
rather a condition that just happens to be indicated by an exception.

It's unreasonable to expect all code in some_api to change their raise
X to raise X from None (and it wouldn't even make sense in all cases).
Is there a clean solution to avoid the unwanted exception chain in the
error message?

If not, would it make sense to re-introduce sys.exc_clear() for this
purpose?

(I originally asked about this
here: 
http://stackoverflow.com/questions/30235516/how-to-suppress-displaying-the-parent-exception-the-cause-for-subsequent-excep

 but
find the answer unappealing.)


You could use a sentinel instead:

MISSING = object()
value = cache_dict.get(key, MISSING)
if value is MISSING:
value = some_api.get_the_value_via_web_service_call(key)
cache_dict[key] = value

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

[Python-ideas] suppressing exception context when it is not relevant

2016-10-10 Thread Václav Dvořák
I'm aware of "raise ... from None" (from PEP 415). However, how can I
achieve that same effect (of suppressing the "During handling of the above
exception, another exception occurred" message) without having control over
the code that is executed from the except clause? I thought that
sys.exc_clear() could be used for this, but that function doesn't exist in
Python 3 anymore.

Why would I want this? I have some simple caching code that looks like
(simplified):

try:
value = cache_dict[key]
except KeyError:
value = some_api.get_the_value_via_web_service_call(key)
cache_dict[key] = value


When there's an exception in the API call, the output will be something
like this:

Traceback (most recent call last):
  File ..., line ..., in ...
KeyError: '...'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File ..., line ..., in ...
some_api.TheInterestingException: ...


But I find this misleading, as the original KeyError is not really an error
at all. I could of course avoid the situation by changing the try/except
(EAFP) into a test for the key's presence (LBYL) but that's not very
Pythonic and less thread-friendly (not that the above is thread-safe as is,
but that's beside the point). Also, yes, I could instead subclass dict and
implement __missing__, but that's only a solution for this particular case.
The problem (if you agree it's a problem) occurs any time an exception is
not actually an error, but rather a condition that just happens to be
indicated by an exception.

It's unreasonable to expect all code in some_api to change their raise
X to raise
X from None (and it wouldn't even make sense in all cases). Is there a
clean solution to avoid the unwanted exception chain in the error message?

If not, would it make sense to re-introduce sys.exc_clear() for this
purpose?

(I originally asked about this here: http://stackoverflow.
com/questions/30235516/how-to-suppress-displaying-the-
parent-exception-the-cause-for-subsequent-excep but find the answer
unappealing.)

Vashek
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/