New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
if __debug__: has nonobvious behaviour when evaluating .pyo without -O #52626
Comments
In certain circumstances, "if __debug__" seems to be evaluating its "else" clause even when -O is not specified. This can cause very surprising behavior. a.zip contains a single file named a/init.pyo. It is the compiled form of the following code: if __debug__:
print 'DEBUG'
else:
print 'RELEASE'
if __debug__ == True:
raise Exception("this is impossible") pythonbug.py evaluates this script with the following: import sys
sys.path = ['a.zip']
import a When using Windows Python 2.6.2 and 2.6.5, running pythonbug.py produces this output: RELEASE
Traceback (most recent call last):
File "pythonbug.py", line 3, in <module>
import a
File "__init__.py", line 8, in <module>
raise Exception("this is impossible")
Exception: this is impossible When -O is passed, the exception is not raised. My best guess is that the Python bytecode is optimizing the "if __debug__" test away in the produced .pyo, but does not actually affect the value of __debug__ or check more complex expressions involving __debug__. |
It's probably caused by optimizations in the peepholer indeed. |
Your assessment of what is going on, Andy, is correct; the peephole optimizer for bytecode optimizes away the But that is actually a reasonable thing for the compiler to do as you are not supposed to run optimized bytecode with the interpreter not running under -O. Running a .pyo file under an interpreter run w/o -O is like compiling for 64-bit but then running on a 32-bit system; you are not following assumptions you told the compiler could be made about the runtime. So I am closing this as 'wont fix'. Best solution is to simply not run bytecode directly and instead execute the source as bytecode should be treated more as an optimization than some directly executable file format. But if you must execute the bytecode directly, simply make sure you don't mix .pyo/.pyc with an improper setting of -O. |
In this case bytecode isn't an optimization, it's a distribution choice (this bug reared it's ugly head in our closed-source downloadable client). I think that implausible execution paths are still a bug. Running a .pyo without -O should be explicitly an error. For instance can we change python to reliably blow up at import time? Or implicitly run as if you added -O? |
So technically Python does not know that some bytecode was compiled with optimization flags on; that is simply not carried in the bytecode format. You also cannot rely on file name extensions as the bytecode could have been generated by an interpreter that used .pyo as the file extension for non-optimized bytecode. So you can't really make this an "explicit error" without changing the format of bytecode files. As for a distribution choice for only shipping bytecode, you should then only ship .pyc files to avoid this issue. Raymond who (most likely) added the optimization is already on the nosy list so he can decide to disagree with me if he wants, but I am personally still not viewing this as a bug. |
Does that mean you agree that the behavior is a bug? If we're agreed that the behavior is a bug, then it's just a matter of solving the implementation details. One suggestion is to compile in a __debug__ check at the top of every .pyo file, effectively prepending every file with "if __debug__ == True: raise AssertionError()". Another could be to add a header to the bytecode (clearly waiting for the next major release of Python). We'll gladly contribute patches once a suitable implementation has been chosen. |
No, Brett said he thought it was not a bug. If Raymond disagrees, he'll say so. If I may attempt to channel Brett, I suspect his logic for closing it "won't fix" went more or less like this: "it might be theoretically possible to change this behavior, but it is not something we wish to do." Unless Raymond disagrees, of course. |
On Wed, Apr 14, 2010 at 18:35, R. David Murray <report@bugs.python.org>wrote:
Yep, that's what I meant. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: