Why does returning inside finally give an empty dictionary?

I want to track exceptions inside a dictionary and return the same. However, when I do this, the block blocks me with an empty dictionary. Logic works pretty much on scalars. Can someone explain the behavior please.

In a scalar context:

def test(): temp = 1 try: raise ValueError("sdfs") except: temp = 2 finally: temp = temp + 3 return temp test() 5 

With a dictionary:

 def test(): temp = dict() try: raise ValueError("something") except Exception as error: print("error is :{}".format(error)) temp['except'] = "something" + error finally: return temp test() error is : something {} 
+5
source share
2 answers

You raised another exception in the exception handler, which was swallowed because there is a finally handler that returns from the function.

You cannot just concatenate the exception object and string, so an additional TypeError is added, and assignment to the dictionary is never achieved.

Converting an exception to a string first works:

 >>> def test(): ... temp = dict() ... try: ... raise ValueError("something") ... except Exception as error: ... print("error is :{}".format(error)) ... temp['except'] = "something" + str(error) ... finally: ... return temp ... >>> test() error is :something {'except': 'somethingsomething'} 

In the try documentation:

If finally present, it indicates a "cleanup handler." The try clause is executed, including any except and else . If an exception occurs in any of the sentences and is not handled, the exception is temporarily saved . The finally clause is executed. If there is a stored exception, it will be raised again at the end of the finally clause. If the finally clause raises another exception, the saved exception is set as the context of the new exception. If the finally clause executes a return or break return , the stored exception is thrown [.]

(My bold accent).

+6
source

The string "something" + error causes an error that is thrown because you returned from finally . Due to an error, the assignment of the temp dictionary is never executed, giving the impression that nothing is happening.

This is stated in the documentation for try-except :

If finally present, it indicates a "cleanup handler." try Runs, including any except and else clauses. If an exception occurs in any of the sentences and is not processed, the exception is temporarily saved. The finally clause is executed. If there is a saved exception, it is recreated at the end of the final paragraph. If another exception occurs in the finally clause, the saved exception is set as the context of the new exception. If the statement finally executes a return or break statement, the stored exception is discarded.

(Emphasis mine)

No error (i.e. temp['except'] = error you will get the expected behavior:

 >>> test() error is :something {'except': ValueError('something')} 
+4
source

Source: https://habr.com/ru/post/1274005/


All Articles