There is nothing confusing about the feature. It tells you right up front what it does:
-O : remove assert and __debug__-dependent statements; add .opt-1 before
.pyc extension; also PYTHONOPTIMIZE=x
Getting this information is as simple as python -h
at the command line. You don’t even need to look up documentation.
If someone uses a flag that removes assert statements from the code, that is clearly described as such, and then the code breaks because the assert statements have been removed, then that is not a confusion about the flag; that is a confusion about how to use assert statements.
But assert
in Python is not confusing, either. It works the same way, and has the same purpose, as assert
in every other language that has it.
The purpose of assert
is twofold:
-
Document to the reader of the code that something is necessarily true at a certain point in the code’s operation.
-
Fail loudly if the expected condition is false, in a way that the code should not attempt to recover from, so that the apparent logical contradiction can be resolved by fixing the code, which has thereby been proven to be incorrect. The problem cannot be resolved in any other way.
That does not mean “we cannot continue if this is false”. It does not mean “oh, well this file with a .json
file extension actually doesn’t contain JSON at all”. It means “if this assertion fails, that fact proves that there is a logical error in the code itself”. In hypothetical code that is actually completely correct and bug-free, which uses assert
properly and does not have a bug in the assertion itself, running on a machine without defects, the assert
cannot fail, and evaluating it cannot impact the program state (unless we count the time taken for verification). It’s the sort of thing that points to memory corruption (undefined behaviour in languages that have that; another process scribbling on our memory; a freak cosmic ray incident…).
Code that depends on the assert
being left in - i.e., because evaluating it meaningfully impacts the program state, or because it’s used for data validation - is, inherently, incorrectly written code. This is not a realistic point of confusion. It is something that I was repeatedly warned about in my own programming education, using C, more than 20 years ago.
The purpose of -O
is to remove assertions and other code meant only for debug mode (i.e. guarded by the built-in __debug__
value, which is provided for the explicit purpose of guarding such code, the execution of which is not supposed to impact on program state in a way that matters in production). There is, practically speaking, only one way to achieve this purpose: by… just doing it. There is no way to be less confusing or more explicit about it, because it is a trivial task that is fully and clearly documented.
If you believe that these uses of assert
are improper, file a bug report with the library.
No, not “by default” and not “for historical reasons”. It gets stripped in release mode because that’s part of the definition of release mode; and it happens for the very explicit purpose of having a “release mode” that avoids spending time on things that are only needed during development.
Using a release mode is entirely optional. Nothing prevents C programmers from compiling and distributing debug-mode executables and expecting others to use those.
However, programmers are expected to understand the proper use of assertions, in any language that has them. An educator who allows the student to know that assert
exists, without clearly explaining its purpose, is ipso facto negligent.
For that matter, I’m not convinced that most Python programmers “learn about assert
in their lives” - unless, of course, Python is not their first programming language and they’ve seen assert
in other languages, in which case they should already understand how this works.