Support multiple assignment targets in Python frontend#937
Support multiple assignment targets in Python frontend#937olivier-aws merged 11 commits intomainfrom
Conversation
Desugar `a = b = 5` into individual assignments for each target, all sharing the same RHS expression. This removes the 'Multiple assignment targets not yet supported' error. Moves test_multi_assign.py and test_multiple_assign_targets.py out of pending/ into the active test suite. Fixes #890
CBMC cannot verify assertions in these tests because the mathematical functions (PEq, Any_to_bool, normalize_any) are uninterpreted in the GOTO model. The Strata pipeline translation is correct, but CBMC reports VERIFICATION FAILED for the assert statements.
|
The CBMC CI failure was caused by incorrect expected outcomes in Root cause: The Python-to-GOTO pipeline correctly translates the multi-assignment code, but the generated GOTO model uses uninterpreted mathematical functions ( This is consistent with the existing tests — all tests with assertions ( Fix: Changed expected outcomes from |
|
@keyboardDrummer-bot with this solution, it seems to me that the rhs of a multi-assignment would be evaluated multiple times. This is not correct if it has side effects, as the Python semantics is to evaluate the rhs only once and affect it then to all the lhs. Can you confirm? |
|
@olivier-aws You're right. The current implementation calls In Python, (Note: Python assigns right-to-left across targets, but left-to-right within tuple unpacking.) This is similar to the tuple unpacking pattern already in |
Introduce a temporary variable for the RHS expression when there are multiple assignment targets (e.g. a = b = f()). This matches Python semantics where the RHS is evaluated exactly once and then assigned to each target.
|
Good catch — I've pushed a fix in bd44966. The multi-assignment This follows the same temporary-variable pattern already used for tuple unpacking. The single-target case ( Verified: |
|
@keyboardDrummer-bot Looks great. Can you extend the tests for multi assignment to also check the case when the this has side effects? |
Test that a = b = c.next() evaluates the RHS exactly once: - New .py test file: test_multi_assign_side_effect.py - Inline VerifyPythonTest: verifies the full pipeline handles it - cbmc_expected.txt: added new test as SKIP (class methods)
|
Done — pushed eb86939 with a side-effect test for multi-assignment. New test: c: Counter = Counter()
a = b = c.next()
assert a == 1
assert b == 1
assert c.count == 1 # next() called exactly onceThis would fail if the RHS were evaluated per-target (counter would be 2 for Also added an inline test in Verified: |
|
@keyboardDrummer-bot resolve git conflicts |
|
Resolved the merge conflict in Pushed as commit 32d9c6e. |
Added comment regarding analysis imprecision affecting asserts.
Replaced vague comment with a precise explanation of why the test is in pending/ (CBMC cannot verify asserts due to uninterpreted functions from Counter class methods) and what the test verifies (multi-assignment evaluates RHS exactly once).
PR requested and agreed on by @olivier-aws
Desugar
a = b = 5(anda = b = c = 1, etc.) into individual assignments for each target, all sharing the same RHS expression. This removes the "Multiple assignment targets not yet supported" error.Changes
Strata/Languages/Python/PythonToLaurel.lean: Replace the single-target guard with a loop over all targets, callingtranslateAssignfor each one and threading the translation context through.test_multi_assign.pyandtest_multiple_assign_targets.pyfrompending/to the active test suite and add them tocbmc_expected.txt.Verification
lake build Strata.Languages.Python.PythonToLaurel✅)strata toIonpipeline succeeds for both test files ✅VerifyPythonTest,ToLaurelTest✅)Fixes #890