The behavior of sys.exc_info() is described in python docs and on SO and SO as:
So why does this nosetest fail?
def test_lang_stack(self):
try:
self.assertEquals((None,None,None), sys.exc_info()) # no exception
a = 5 / 0
except:
self.assertNotEquals((None,None,None), sys.exc_info()) # got exception
else:
self.fail('should not get here')
#finally:
# self.assertEquals((None,None,None), sys.exc_info()) # already handled, right?
self.assertEquals((None,None,None), sys.exc_info()) # already handled, right?
It fails at the last line. If you uncomment the finally block, it fails there instead.
I do see that if I put all this inside one method and call from a different method, then the calling method does not see the exception. The exc_info value seems to remain set to the end of the method where an exception is thrown, even after the exception is handled.
I'm using python2.7 on OSX.
sys. exc_info () This function returns a tuple of three values that give information about the exception that is currently being handled. The information returned is specific both to the current thread and to the current stack frame.
The sys module in Python provides various functions and variables that are used to manipulate different parts of the Python runtime environment. It allows operating on the interpreter as it provides access to the variables and functions that interact strongly with the interpreter.
sys. path is a built-in variable within the sys module. It contains a list of directories that the interpreter will search in for the required module. When a module(a module is a python file) is imported within a Python file, the interpreter first searches for the specified module among its built-in modules.
Before answering your question, I must explain about sys.exc_info() determines about latest/recent exception in your program:-
Your program is basically a series of function calls, with caller function calling called. Thus a call stack/execution stack is formed, where an entry is pushed for each function, being called. This entry is known as stack frame in python. Thus, when in your program, sys.exc_info() is invoked, it uses the following sequence to determining latest exception. It begins from the current stack frame, which is the function from where you are invoking sys.exc_info(). If the current stack frame is not handling/had not handled an exception, the information is taken from the calling stack frame, or its caller, and so on until a stack frame is found that is handling/had handled an exception . Here, “handling an exception” is defined as “executing or having executed an except clause.” For any stack frame, only information about the most recently handled exception is accessible.
Now, coming to your code,
def test_lang_stack(self):
try:
self.assertEquals((None,None,None), sys.exc_info()) # no exception
a = 5 / 0
except:
self.assertNotEquals((None,None,None), sys.exc_info()) # got exception
else:
self.fail('should not get here')
#finally:
# self.assertEquals((None,None,None), sys.exc_info()) # already handled, right?
self.assertEquals((None,None,None), sys.exc_info()) # already handled, right?
As per the procedure explained above, sys.exc_info() will always find recent exception being handled in your function. So, It'll be never tuple of Nones, unless you call sys.exec_clear()
explicitly.
I hope, it may help you.
In both assertEquals() and assertNotEquals() you need to call:
sys.exc_clear()
This will clear things for the next error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With