pycdc
pycdc copied to clipboard
Processing JUMP_IF_TRUE_OR_POP incorrectly
Test under Python 3.8
Original file (sample.py)
a = {"123":"456"}
b = {}
c = a.get("123") or b
//Compile with python3.8 -m compileall sample.py
// Decompile with pycdc
Output file
# Source Generated with Decompyle++
# File: sample.cpython-38.pyc (Python 3.8)
a = {
'123': '456' }
b = { }
if not a.get('123'):
pass
c = b
This is apparently semantically incorrect.
Disassmeble with pycdas
sample.cpython-38.pyc (Python 3.8)
[Code]
File Name: ./sample.py
Object Name: <module>
Arg Count: 0
Pos Only Arg Count: 0
KW Only Arg Count: 0
Locals: 0
Stack Size: 3
Flags: 0x00000040 (CO_NOFREE)
[Names]
'a'
'b'
'get'
'c'
[Var Names]
[Free Vars]
[Cell Vars]
[Constants]
'123'
'456'
None
[Disassembly]
0 LOAD_CONST 0: '123'
2 LOAD_CONST 1: '456'
4 BUILD_MAP 1
6 STORE_NAME 0: a
8 BUILD_MAP 0
10 STORE_NAME 1: b
12 LOAD_NAME 0: a
14 LOAD_METHOD 2: get
16 LOAD_CONST 0: '123'
18 CALL_METHOD 1
20 JUMP_IF_TRUE_OR_POP 24
22 LOAD_NAME 1: b
24 STORE_NAME 3: c
26 LOAD_CONST 2: None
28 RETURN_VALUE
tried same sample above on Python 3.12:
Warning: Stack history is not empty!
Warning: block stack is not empty!
a = {
'123': '456' }
b = { }
if not a.get('123'):
c = b
return None
issue_463.cpython-312.pyc (Python 3.12)
[Code]
File Name: issue_463.py
Object Name: <module>
Qualified Name: <module>
Arg Count: 0
Pos Only Arg Count: 0
KW Only Arg Count: 0
Stack Size: 3
Flags: 0x00000000
[Names]
'a'
'b'
'get'
'c'
[Locals+Names]
[Constants]
'123'
'456'
None
[Disassembly]
0 RESUME 0
2 LOAD_CONST 0: '123'
4 LOAD_CONST 1: '456'
6 BUILD_MAP 1
8 STORE_NAME 0: a
10 BUILD_MAP 0
12 STORE_NAME 1: b
14 LOAD_NAME 0: a
16 LOAD_ATTR 5: get
36 LOAD_CONST 0: '123'
38 CALL 1
46 COPY 1
48 POP_JUMP_IF_TRUE 2 (to 54)
50 POP_TOP
52 LOAD_NAME 1: b
54 STORE_NAME 3: c
56 RETURN_CONST 2: None