Repository navigation
v1.2.4
Fixed — Issue #3: if cond: return x was being folded into return cond and x
src/depyo/handlers/misc_other.py was unconditionally rewriting one-statement
if cond: return x blocks into a short-circuit return cond and x. The
rewrite is only sound when the compiler actually emitted a sticky-truth
jump (JUMP_IF_FALSE_OR_POP, real short-circuit). For a normal
if-statement the compiler emits POP_JUMP_IF_FALSE, and the fold then
quietly loses information.
What was broken
- Falsy returns silently disappeared.
if cond: return 0collapses to
cond and 0which evaluates toconditself when cond is truthy — the
decompiled source no longer matches the original semantics. Same for
return None,return "",return [], etc. - elif chains imploded. A 4-way
if leftover == 1: ... elif leftover == 2: ...
chain in stdlibbase64.encodewas rendered as
return leftover == 1 and ...; return leftover == 2 and ...; ...
on a single line. - Dead
returnartifacts. Code below the folded if was emitted as
unreachable but still rendered. - Cascade folds.
if a: if b: return xcould re-enter the fold and
produce nonsense likereturn a and b and None.
Fix
Removed the fold entirely. The handler still pops the if-block, appends it
to the parent block, and consumes the trailing JUMP_ABSOLUTE/JUMP_FORWARD
— but no longer rewrites the AST. Genuine cond and x short-circuit
round-trips through the JUMP_IF_FALSE_OR_POP handler in
control_flow_jumps.py and is unaffected.
Fixed — Issue #2: Garbled non-ASCII output on Windows
depyo opens output files (.py, .dump, .pyasm text variant) without
explicitly setting an encoding. Python defaults open(path, "w") to the
locale codepage on Windows — CP936 for Simplified Chinese, CP1251 for
Russian, CP932 for Japanese — so any non-ASCII identifier or string
literal in the decompiled source gets either mojibake'd or raises
UnicodeEncodeError. On macOS/Linux you don't notice because the locale
default is already UTF-8.
Fix
open(...) calls in src/depyo/__main__.py for the three text-mode
outputs now explicitly pass encoding="utf-8". Bytes-mode outputs
(.pyc, binary .dump/.pyasm) are unchanged.
Regression coverage
New fixture test/modern_features/issue12_if_return_falsy.py covers:
falsy_x— the exact issue #3 case (x = 1; if cond: return x; return 0)none_x,empty_string— falsy return value variantstruthy_x— control case where the fold would have looked superficially finenegative_branch—if not condformreal_short_circuit— genuinereturn cond and x(must still fold via
theJUMP_IF_FALSE_OR_POPpath)
Compiled for 3.10–3.14 via the shared test root used by both the JS and
Python ports.
The UTF-8 encoding fix doesn't have a dedicated fixture (CI runs on
Linux/macOS where the default is already UTF-8), but the symptom only
appears when the OS locale is non-UTF-8, which the explicit encoding
fully removes.
Compatibility
No API changes. Output paths and CLI flags are unchanged. Decompiled
output for any code matching the buggy fold pattern (#3) will change
shape — refresh your local snapshots if you maintain any.
Thanks to @CtrlCThenCtrlV for both reports.