On Sun, Apr 29, 2018 at 01:14:54PM +1000, Chris Angelico wrote: [...] > def f(): > e = 2.71828 > try: > 1/0 > except Exception as e: > print(e) > print(e) > f()
> I propose to change the semantics as follows: > > 1) Bind the caught exception to a sublocal 'e' > 2) Execute the suite, with the reference to 'e' seeing the sublocal > 3) Set the sublocal e to None > 4) Unbind the sublocal e > > At the unindent, the sublocal name will vanish, and the original 'e' > will reappear. Thus the final print will display 2.71828, just as it > would if no exception had been raised. What problem does this solve? The current behaviour where 'e' is unbound when the except clause finishes is a neccessary but ugly hack that forces you to do bind 'e' to another variable if you want to inspect it after the exception: try: something() except Exception as e: err = e # defeat the automatic deletion of e print(e) For example, in the interactive interpreter, where I do this very frequently. I understand and accept the reasons for deleting e in Python 3, and don't wish to re-debate those. But regardless of whether we have Python 3 behaviour or Python 2 behaviour, binding to e has always replaced the value of e. Just as if I had written: except Exception as some_other_name: e = some_other_name It has never been the case that binding to e in the except clause won't replace any existing binding to e, and I see no reason why anyone would desire that. If you don't want to replace e, then don't use e as the name for the exception. Your proposal doesn't solve any known problem that I can see. For people like me who want to inspect the error object outside the except clause, we still have to defeat the compiler, so you're not solving anything for me. You're not solving any problems for those people who desire (for some reason) that except clauses are their own scope. It is only the exception variable itself which is treated as a special case. The one use-case you give is awfully dubious: if I wanted 'e' to keep its value from before the exception, why on earth would I rebind 'e' when there are approximately a zillion alternative names I could use? Opportunities for confusion should be obvious: e = 2.71 x = 1 try: ... except Exception as e: assert isinstance(e, Exception) x = 2 assert isinstance(e, Exception) # why does this fail? assert x != 2 # why does this fail? Conceptually, this is even more more complex than the idea of giving the except block its own scope. The block shares the local scope, it's just the block header (the except ... as ... line itself) which introduces a new scope. -- Steve _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/