Possibly. It was brought up during the Python 3 transition but was deemed to disruptive to follow through with. Personally I would love to make bare except
statements illegal and then after a proper amount of time bring them back to mean except Exception
.
It is handy for the “do something and reraise” condition. E.g. you want to abort a transaction no matter what exception occurred. It probably wouldn’t be easy, but raising an exception if a bare except
clause didn’t call bare raise
would be useful.
You would still be able catch any exception; that’s just except BaseException
. It’s already TypeError
to raise anything that doesn’t derive from BaseException
.
Maybe it would have been, but actually it’s something 2to3
would have been able to fix pretty reliably by rewriting to except BaseException
.
There was also disagreement over what a bare except
should mean. Regardless, it’s not worth arguing about since we’re kind of done with worrying about what features to put into Python 3.0.
I might be convinced to support deprecating and removing bare except clauses: they’re a real problem and I see them often in many code-bases. But I’d be highly against bringing them back later with a new meaning.
If followed by “raise” bare except has a legitimate use case which is not so rare to encounter. If removed, how should the new code be ported in order to mean exactly the same thing as “except:”?
except BaseException:
already means the same so I’m not sure what you’re after beyond that.
What advantage does except BaseException
provide over a bare except
? Meaning, if we were to deprecate the latter, is there any real improvement to code quality or readability?
For me the only advantage is that bare except
, being much shorter to type, is an attractive nuisance to people who are not experienced Python programmers.
I agree with @pitrou. Writing except BaseException:
proves that the person who wrote that actively thought about which exception class to use. It’s not something that you write by mistake.
Precisely because except:
is so simple, it is regularly misused by people that don’t really understand what it means or are simply lazy.
Python seems to be chosen by none-fulltime-programmers (scientists, mathematicians, financial, sysadmins, … ) for the more flexible programming and no need to know underlying programming logics unless you really want/need. ‘Just catch any exception while figuring out the code for the function.’ or ‘Just drop the anomalies but keep on treating the rest of the data’. I understand it’s no good practice, but it’s easy and well readable if you want to spend more precious time on working with the partial data/results instead of figuring out all coding obligations.
I understand that ‘except:’ now means ‘except BaseException:’, but ideally should have been ‘except Exception’? First deprecate to not use ‘except:’ and bring back is confusing. What would be the impact just changing it one version to another? SystemExit, KeyboardInterrupt and GeneratorExit will not be caught. Those are deliberate actions to stop the script/program anyway?
It would avoid a lot of kill $(ps aux | grep python-project | awk '{print $2}')
actions. Now understanding the reason, I don’t know if I will start writing ‘except Exception:’ everywhere? Next kill pid situation will raise my attention to this anyhow. Thanks, interesting. “exception hierarchy” helped understanding the situation.
It would break a lot of existing code, especially KeyboardInterrupt
. I have no concrete data points (maybe it’s worthwhile to look into this), but anecdotally it is common to use this to perform some final cleanup when user interrupts your program. Changing bare except without deprecation would make those cleanups not run, leading to subtle bugs not immediately apparent.
Do any linters warn on bare except
? That could be a start without having to change the language. PEP 8 could also be updated to recommend never to use bare except
.
- pycodestyle (and inheritantly flake8) lints it by default (against heated objections).
- PyLint has W0702 (not sure if it’s on by default; I think so?)
- Black does not change a bare except (maybe this is a good place to start, given its “officially recommended” status?)
What would it change it into?
- If
Exception
then this changes the functionality, which is something black must not do IMHO. - If
BaseException
then any incorrectly used bare excepts are now much less obvious, andpycodestyle
andpylint
will stop warning about them.
Understood. So using bare except for any exception to do some final cleanup, because user knew that also deliberate interrupts (keyboard/system/kill/…) were caught by bare except. Then indeed would cause some backward compatibility issues.
My original thought went to BaseException
(ruling out Exception
with the same reason as yours), but you got a good point here. I guess Black, being a code formatter, is not a suitable tool to make such a logical correction.
This definitely feels more like the responsibility of linters than Python itself.