Skip to content

The linenumber in the ast changes the result of the bytecode compilation #100378

Closed as not planned
@15r10nk

Description

@15r10nk

Bug report

I run in some unexpected issue while I was trying to build something.

I expected line numbers have no effect on the python bytecode compilation, but I found something wired which I don't understand and which might be a bug.

compile() generates an JUMP_IF_FALSE_OR_POP instead of one POP_JUMP_IF_FALSE if the line numbers are changed.

script:

import dis
import ast

source="result = a and b or c"


tree=ast.parse(source,"exec")

codea=compile(tree,"<string>","exec")

for i,node in enumerate(ast.walk(tree)):
    node.lineno=i

codeb=compile(tree,"<string>","exec")


print("code a               | code b")

for insta,instb in zip(dis.get_instructions(codea),dis.get_instructions(codeb)):
    print(f"{insta.opname:<20} | {instb.opname}","<-- not equal" if insta.opname!=instb.opname else "")

print("the result seems to be the same")
for a in (True,False):
    for b in (True,False):
        for c in (True,False):
            print()
            print("a:",a,"b:",b,"c:",c)

            eval(codea)
            print("codea:",result)
            eval(codeb)
            print("codeb:",result)

output (Python 3.10.8):

code a               | code b
LOAD_NAME            | LOAD_NAME 
POP_JUMP_IF_FALSE    | JUMP_IF_FALSE_OR_POP <-- not equal
LOAD_NAME            | LOAD_NAME 
JUMP_IF_TRUE_OR_POP  | JUMP_IF_TRUE_OR_POP 
LOAD_NAME            | LOAD_NAME 
STORE_NAME           | STORE_NAME 
LOAD_CONST           | LOAD_CONST 
RETURN_VALUE         | RETURN_VALUE 
the result seems to be the same

a: True b: True c: True
codea: True
codeb: True

a: True b: True c: False
codea: True
codeb: True

a: True b: False c: True
codea: True
codeb: True

a: True b: False c: False
codea: False
codeb: False

a: False b: True c: True
codea: True
codeb: True

a: False b: True c: False
codea: False
codeb: False

a: False b: False c: True
codea: True
codeb: True

a: False b: False c: False
codea: False
codeb: False

I was not able to reproduce this with normal source code, but this does not mean that it is impossible.

Is there any explanation for that behavior?

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions