This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author saulshanabrook
Recipients saulshanabrook
Date 2022-02-11.17:22:25
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1644600146.24.0.968453673832.issue46724@roundup.psfhosted.org>
In-reply-to
Content
I noticed that in Python 3.10, and also in main, a certain control flow construct produces some very odd bytecode (showing on main but same on python 3.10 tags):

```
./python.exe -c 'import dis; dis.dis("while not (a < b < c): pass")'
              0 RESUME                   0

  1           2 LOAD_NAME                0 (a)
              4 LOAD_NAME                1 (b)
              6 SWAP                     2
              8 COPY                     2
             10 COMPARE_OP               0 (<)
             12 POP_JUMP_IF_FALSE       11 (to 22)
             14 LOAD_NAME                2 (c)
             16 COMPARE_OP               0 (<)
             18 POP_JUMP_IF_TRUE        28 (to 56)
             20 JUMP_FORWARD             1 (to 24)
        >>   22 POP_TOP
        >>   24 LOAD_NAME                0 (a)
             26 LOAD_NAME                1 (b)
             28 SWAP                     2
             30 COPY                     2
             32 COMPARE_OP               0 (<)
             34 POP_JUMP_IF_FALSE       23 (to 46)
             36 LOAD_NAME                2 (c)
             38 COMPARE_OP               0 (<)
             40 POP_JUMP_IF_FALSE       12 (to 24)
             42 LOAD_CONST               0 (None)
             44 RETURN_VALUE
        >>   46 POP_TOP
             48 EXTENDED_ARG           255
             50 EXTENDED_ARG         65535
             52 EXTENDED_ARG         16777215
             54 JUMP_FORWARD         4294967280 (to 8589934616)
        >>   56 LOAD_CONST               0 (None)
             58 RETURN_VALUE
```

The last JUMP_FORWARD has a rather larger argument! This was the minimal example I could find to replicate this.

However, this is an example of some runnable code that also encounters it:

```
a = b = c = 1
while not (a < b < c):
    if c == 1:
        c = 3
    else:
        b = 2
    print(a, b, c)
```

This actually executes fine, but I notice that when it's executing it does execute that very large arg, but that the `oparg` to JUMP_FORWARD ends up being negative! By adding some tracing, I was able to see that the `oparg` variable in the `TARGET(JUMP_FORWARD)` case is `-32`.

I am not sure if this is a bug or intended behavior. It does seem a bit odd to have this unnecessarily large argument that ends up turning into a negative jump! But the behavior seems fine.

At the least, maybe `dis` should be modified so that it properly sees this as a negative jump and debugs it properly? I am happy to submit a PR to modify `dis` to handle this case, but I also wanted to flag that maybe it's a bug to being with.
History
Date User Action Args
2022-02-11 17:22:26saulshanabrooksetrecipients: + saulshanabrook
2022-02-11 17:22:26saulshanabrooksetmessageid: <1644600146.24.0.968453673832.issue46724@roundup.psfhosted.org>
2022-02-11 17:22:26saulshanabrooklinkissue46724 messages
2022-02-11 17:22:25saulshanabrookcreate