Re: Access to return / exception context in finally block
>In your example when would isinstance(__exit_context__, ReturnContext) >be True and when would it be False? What would __exit_context__.value >be? I can't think of a sensible meaning for it. If no exception occurs, >is the value returned by f supposed to be 10/x or __exit_context__.value >+ 1 # whatever that is >Best wishes >Rob Cliffe Dear Rob, isinstance(__exit_context__, ReturnContext) would only be True, when the try, except or else block is left using a return statement. __exit_context__.value would be the return value of f(x), in that case 10/x. Currently it is not possible to access this value in the finally block, but it can be overwritten, as the return statement is compiled into a new RETURN_VALUE opcode. In this example, f(x) would return 10/x + 1 if x != 0 else 0. I think that this magic variable would make error handling much more easier. What do you think? Best wishes Marius Spix -- https://mail.python.org/mailman3//lists/python-list.python.org
Re: Access to return / exception context in finally block
>def f(x): > try: > quot = 10 / x > except ZeroDivisionError as exc: > log_error(exc) > return 0 > else: > log_return(quot) > return quot + 1 > finally: > "Any cleanup processing needed before returning" This involves defining the new variable quot, which is only defined, when the try block succeeds. quot is undefined in the except block and in the finally block after an exception occured. The scoping of that variable is fragile and it is hard to track, why that variable is declared and where it is used. This also worsens the readability of the coding and worsens the expandability, for example, if you want to do something in the finally block later. >def f(x): > try: > quot = 10 / x > except ZeroDivisionError as exc: > log_error(exc) > res = 0 > else: > log_return(quot) > res = quot + 1 > finally: > return res This is even worse. The variable res is declared in both branches. If you want to catch another exception different from ZeroDivisionError, you would have to declare res again, because the finally block is always run and now expects this variable. A finally block depending on variables declared in the except or else block is very confusing. __exit_context__ would solve this issue, because that magic variable would be always available and you don't have to juggle with local variables. The finally block can write to the return value, so there is no reason to hide the return value or already caught exceptions here. This would make the code much cleaner and avoids messing up with the scope of variables. -- https://mail.python.org/mailman3//lists/python-list.python.org
Access to return / exception context in finally block
Dear mailing list, there is currently no direct way to observe the current interpreter state in a finally block without tracing. My idea is introducing an immutable __exit_context__ magic variable, which would have one of three possible values: * ReturnContext(value), if a return statement is about to exit the try, except or else block * ExceptionContext(exc, tb, caught: bool), if an exception has occured in the try, except or else block * None, if the try block completes normally without return or exception This variable would allow to inspect the cause, why a try block is left and make post-processing easier without using workarounds like storing the exception in a temporary variable. sys.exc_info() is not always useful, because it always returns (None, None, None) when the exception has been caught in the except block. This is an example, how __exit_context__ could be used: def f(x): try: return 10 / x except ZeroDivisionError: pass finally: if isinstance(__exit_context__, ExceptionContext): log_error(__exit_context__.exc) return 0 elif isinstance(__exit_context__, ReturnContext): log_return(__exit_context__.value) return __exit_context__.value + 1 I wonder if it would be a candidate for a PEP to be implemented in the Python standard. Best regards Marius Spix -- https://mail.python.org/mailman3//lists/python-list.python.org
