This is not a realistic view of Python code. It doesn’t exist as isolated scripts, for the most part. It’s in projects with hundreds to potentially thousands of direct and transitive dependencies. Any breaking change like this is going to cause problems for people who simply want to upgrade Python versions without having to update frozen version pins, which is essential for consistent, reliable production code.
IMHO, any notion of implicit re-raise seems like an abomination in terms of code readability and maintainability (and it’s unclear to me what the point would be: save one line of code?). Explicit is still better than implicit.
I’ve been in or worked with large companies which usually have their own fork of Python but have to maintain it and then the teams have to integrate mainline Python versions. Modifying the language to eliminate bare excepts will require more than one person’s development time and retesting major parts of their systems. This results in waiting for new Python versions to either justify cost or availability of resources.
The point is safety - so you won’t swallow an exception because you forgot that extra line. Swallowing an exception should be explicit, allowing it to propagate on should be the default, what happens when you do-nothing.
I would be interested to know how many of those will have essentially the same behaviour after. While except:does catch the extra exceptions; the amount of times (except for KeyboardInterrupt) that you’ll actually catch them is pretty low.
This change would definitely cause some interesting compat problems, but I think they may be worth it to remove what is (in my mind) a far too easy to use footgun. Principle of least astonishment applies here, except:stopping the program from exiting is pretty shocking if you don’t already know
This phrase emphasizes that Python trusts developers to make their own decisions. Python is designed to give programmers flexibility rather than imposing strict guardrails, allowing them to write code as they see fit. While it provides clear recommendations and conventions, it ultimately leaves the responsibility of writing good, maintainable code to the developer.
In practice, this philosophy shows up in Python’s relatively permissive approach to programming. For example, unlike some languages, Python doesn’t strictly enforce access control mechanisms (like private or protected fields in classes) because it assumes developers know what they are doing and can act responsibly.
I think the proposal needs motivation for the following: why does this need to be a hard error, rather than a warning?
Those who ignore a warning are likely to be the same people who just blanket search+replace except: with the new nearest equivalent. A warning may get most of the benefit without yet another hard compatibility break in the Python base language.
To be fair, I get 2.4M results for print statements (not including print ( which is valid but could be a shim). GitHub is an archive as well as a repository, so there’s going to be lots of old code there.
I think the cost outweighs the benefit of the change. Although bare except is not used many times in production code in the places I have been at, I still have to see a place where it caused problems.
The peace of mind of not having to remember in a quick script or a notebook whether Exception, BaseException or any other exception applies to an specific part of your code, and rely on a bare except if you really want for a piece of code not to break the executions seems priceless to me.
I think going any step further than issuing a warning in a linter is a step too far. There is no gain on clarity, there are no real world benefits I see except a perceived conception of correctness, and it’s longer to type when it’s actually very explicit, except on anything.
IMO, python syntax should plan for the long term. This doesn’t mean next 5 years, but more next 20. This is a footgun that most people will run into at some point and they have to be told manually that it’s a bad idea and why. (most beginners do not use linters) If we were to create python from scratch, I don’t think anyone would argue that bare except should be kept in, and from this I conclude that python in 10 years should no longer have this wart. Therefore I am a big +1 on the idea of the chance.
But I do agree that 2 years is to little time. Instead I would suggest to model after unreconigzed escape sequences in strings:
Changed in version 3.6: Unrecognized escape sequences produce a DeprecationWarning.
Changed in version 3.12: Unrecognized escape sequences produce a SyntaxWarning. In a future Python version they will be eventually a SyntaxError.
So ~5 years deprecation time where it emits a DeprecationWarning, and then a few more years where it emits a SyntaxWarning, and only then turn it into an error.
bare except is a useful language feature for debugging and also keeping code concise in some situations. you want to remove it because you have a low opinion of it… please dont ruin python.
It’s pretty hyperbolic to suggest it would “ruin” Python to make this slight change to encourage better coding practice. We’re not talking about braces, here.
That suggests that there are about 3 bare excepts per project. I just checked SymPy’s codebase and as chance would have it I found exactly 3 bare excepts:
None of these is part of the code that actually gets installed (where it would be rejected by a linter). One of them is an old script that no one uses any more and the other two are to do with trying to inject a commit hash into the sdist but not wanting to fail the sdist or docs build if injecting the commit hash doesn’t work. The failures would be if the person who builds the sdist does not have git and the person who builds the docs used the resulting sdist.
I have just considered whether it is worthwhile to open a PR to change these but I don’t think it is worth it. I could change them to catch Exception or I could figure out exactly what exception is otherwise raised but realistically it is not going to improve anything for anyone.
You are not “encouraging” better practice; you are enforcing it. One reason I like Python is that I can be lazy and get away with it. It is up to me to know when that is appropriate and when that is not. I can think of plenty of cases where I write throwaway code and inspect the output to be sure it behaved as I wanted. Making me work harder to get there is not an improvement.
You can still write except BaseException: to do exactly what you were doing before, you just have to opt in to doing that instead of the current opt-out. Not terribly strict enforcement!
I would personally argue for ‘bug’ in the sense that it is the bad kind of surprise when you trip over it, but I am biased by having been pretty badly burned by it recently¹. Corroborating evidence: pylint has a rule for it: return-in-finally
¹ in a case where someone put a return in a finally clause that should have been outside of it, clobbering an exception raised in a preceding handler.