Skip to content
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

Closed
afriesen mannequin opened this issue Apr 12, 2010 · 8 comments
Closed

if __debug__: has nonobvious behaviour when evaluating .pyo without -O #52626

afriesen mannequin opened this issue Apr 12, 2010 · 8 comments
Labels
type-bug An unexpected behavior, bug, or error

Comments

@afriesen
Copy link
Mannequin

afriesen mannequin commented Apr 12, 2010

BPO 8379
Nosy @brettcannon, @rhettinger, @pitrou, @bitdancer
Files
  • pythonbug.zip
  • unnamed
  • 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:

    assignee = None
    closed_at = <Date 2010-04-12.22:00:04.163>
    created_at = <Date 2010-04-12.21:34:05.586>
    labels = ['type-bug']
    title = 'if __debug__: has nonobvious behaviour when evaluating .pyo without -O'
    updated_at = <Date 2010-04-15.02:15:13.238>
    user = 'https://bugs.python.org/afriesen'

    bugs.python.org fields:

    activity = <Date 2010-04-15.02:15:13.238>
    actor = 'brett.cannon'
    assignee = 'none'
    closed = True
    closed_date = <Date 2010-04-12.22:00:04.163>
    closer = 'brett.cannon'
    components = []
    creation = <Date 2010-04-12.21:34:05.586>
    creator = 'afriesen'
    dependencies = []
    files = ['16901', '16926']
    hgrepos = []
    issue_num = 8379
    keywords = []
    message_count = 8.0
    messages = ['102975', '102978', '102979', '102990', '103072', '103162', '103172', '103176']
    nosy_count = 6.0
    nosy_names = ['brett.cannon', 'rhettinger', 'pitrou', 'r.david.murray', 'afriesen', 'Timothy.Fitz']
    pr_nums = []
    priority = 'low'
    resolution = 'wont fix'
    stage = None
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue8379'
    versions = ['Python 2.6', 'Python 3.1', 'Python 2.7', 'Python 3.2']

    @afriesen
    Copy link
    Mannequin Author

    afriesen mannequin commented Apr 12, 2010

    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__.

    @afriesen afriesen mannequin added the type-bug An unexpected behavior, bug, or error label Apr 12, 2010
    @pitrou
    Copy link
    Member

    pitrou commented Apr 12, 2010

    It's probably caused by optimizations in the peepholer indeed.

    @brettcannon
    Copy link
    Member

    Your assessment of what is going on, Andy, is correct; the peephole optimizer for bytecode optimizes away the if __debug__ section of the if statement for .pyo files.

    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.

    @timothyfitz
    Copy link
    Mannequin

    timothyfitz mannequin commented Apr 12, 2010

    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?

    @brettcannon
    Copy link
    Member

    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.

    @timothyfitz
    Copy link
    Mannequin

    timothyfitz mannequin commented Apr 15, 2010

    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.

    @bitdancer
    Copy link
    Member

    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.

    @brettcannon
    Copy link
    Member

    On Wed, Apr 14, 2010 at 18:35, R. David Murray <report@bugs.python.org>wrote:

    R. David Murray <rdmurray@bitdance.com> added the comment:

    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."

    Yep, that's what I meant.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    3 participants