fix: use python truthiness for compiled and/or Var operations#6546
Conversation
JS `&&`/`||` use JS truthiness, where `[]` and `{}` are truthy. Python
treats them as falsy, so `Var([]) | true` was compiling to `[] || true`
and returning `[]` instead of `true`. Same issue for `Var({}) & x`,
`Var("") | y`, etc.
Compile `a | b` to `pyOr(a, () => b)` and `a & b` to `pyAnd(a, () => b)`,
backed by helpers that use `isTrue` for the truthiness check. RHS is
wrapped in a thunk so short-circuit semantics are preserved.
Greptile SummaryThis PR fixes a Python/JS truthiness mismatch for the compiled
Confidence Score: 4/5Safe to merge; the helpers are tiny, clearly correct, and backed by the existing isTrue function. The change is narrowly scoped and the logic is straightforward. The only gap is that tests verify the compiled output shape but don't exercise an empty-list or empty-dict operand, leaving the motivating scenario untested at the Python unit-test level. tests/units/test_var.py could use an additional test case with empty-container Var operands to directly document and guard the fixed behaviour. Important Files Changed
Reviews (1): Last reviewed commit: "fix: use python truthiness for compiled ..." | Re-trigger Greptile |
Summary
The
and_operation/or_operationVar operations compiled to JS&&/||, but JS and Python disagree on truthiness for container values:[] or True→True(empty list is falsy)[] || true→[](empty array is truthy)So a Reflex expression like
Var([]) | Truewas producing[] || truein the frontend and resolving to[]instead ofTrue. Same for{},"", etc.This PR routes the compiled output through new
pyOr/pyAndhelpers that use the existingisTruePython-truthiness check:The RHS is passed as a thunk (
() => b) so short-circuit evaluation is preserved —bis not evaluated unless its branch is taken.Compiled output change
a | b(a || b)pyOr(a, () => (b))a & b(a && b)pyAnd(a, () => (b))Repro
Before this change, the rendered values match JS truthiness (
[]truthy) instead of Python truthiness ([]falsy). With this PR they match Python.Test plan
uv run pytest tests/units— 4468 passeduv run ruff check .anduv run ruff format --check .cleantest_var.pyassertions for the new compiled output