[issue32317] sys.exc_clear() clears exception in other stack frames

2020-11-22 Thread Irit Katriel


Irit Katriel  added the comment:

sys.exc_clear was removed in Python 3:
https://docs.python.org/3/whatsnew/3.0.html#index-22

--
nosy: +iritkatriel
resolution:  -> out of date
stage:  -> resolved
status: open -> closed

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32317] sys.exc_clear() clears exception in other stack frames

2017-12-13 Thread Garrett Berg

Garrett Berg  added the comment:

I found a workaround, and probably the reason this has not been detected before:

import sys

def doclear2()
try:
1/0
except ZeroDivisionError:
sys.exc_clear()

try:
1/0
except ZeroDivisionError:
exc = sys.exc_info()[0]
print("third exc (before doclear):", exc)
doclear2()
exc = sys.exc_info()[0]
print("third exc (after  doclear):", exc)
assert sys.exc_info()[0] is ZeroDivisionError

The above passes. It seems that being inside a local exception block allows for 
the spec to hold, only the "local exception" is cleared.

I still think this is a pretty major bug, but it is good to know what the 
workaround/reason it's "been working" is.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32317] sys.exc_clear() clears exception in other stack frames

2017-12-13 Thread Garrett Berg

New submission from Garrett Berg :

# Summary
In python (2 or 3) it should always be valid to have a bare *raise* statement 
in an exception block.

try:
do_something()
except SomeException:
do_cleanup()
raise # always reraises SomeException with original stack trace

You can see this in the python exception documentation:
https://docs.python.org/2.7/tutorial/errors.html#raising-exceptions


# Reproduction of Failure of invariants
Example python file where this doesn't work:

from __future__ import print_function

import sys

def doclear():
"""This should basically be a noop"""
sys.exc_clear()

try:
1/0
except ZeroDivisionError:
exc = sys.exc_info()[0]
print("first exc:", exc)
assert exc is ZeroDivisionError

try:
1/0
except ZeroDivisionError:
exc = sys.exc_info()[0]
print("second exc (before doclear):", exc)
doclear()
exc = sys.exc_info()[0]
print("second exc (after  doclear):", exc)
assert sys.exc_info()[0] is ZeroDivisionError  # fails


Running in python2.7 gives:

first exc: 
second exc (before doclear): 
second exc (after  doclear): None
Traceback (most recent call last):
  File "doclear.py", line 23, in 
assert sys.exc_info()[0] is ZeroDivisionError  # fails
AssertionError


# Conclusion
There seems to be a bug in python 2.7 where it doesn't follow it's own spec.
[sys.exc_clear()](https://docs.python.org/2/library/sys.html#sys.exc_clear)
states:

> This function clears all information relating to the current or last
> exception that occurred in the current thread. After calling this function,
> exc_info() will return three None values until another exception is raised in
> the current thread or *the execution stack returns to a frame where another
> exception is being handled*.

The above code is clear example where sys.exc_clear() is changing the value of
sys.exc_info() *in a different stack frame*, which is against what is stated in
the above docs.

This bug makes it impossible to reraise with a bare raise statement when doing
cleanup that could use sys.exc_clear(). In other words, calling into functions
can *change your local state* with regards to what exception is being handled.

--
components: Interpreter Core
messages: 308264
nosy: Garrett Berg
priority: normal
severity: normal
status: open
title: sys.exc_clear() clears exception in other stack frames
type: behavior
versions: Python 2.7

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32317] sys.exc_clear() clears exception in other stack frames

2017-12-13 Thread Garrett Berg

Garrett Berg  added the comment:

I forgot to post this:

python --version



Python 2.7.14

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com