Add optional tz parameter to datetime_now and reject extra positional args#725
Add optional tz parameter to datetime_now and reject extra positional args#725tautschnig merged 17 commits intomainfrom
Conversation
When a Python function call passes more positional arguments than the Laurel prelude signature declares (e.g., datetime.now(timezone.utc) where datetime_now has 0 params), truncate the argument list to the signature length instead of passing the extra args through. This fixes an arity mismatch that caused check_storage_costs to fail with "call [end_time] := datetime_now($hole_12($heap_in))" — the timezone.utc argument was being passed to a 0-parameter procedure. The fix is general: any prelude function that models fewer parameters than the Python signature will silently drop the unmodeled trailing arguments, which is correct for verification since those parameters do not affect the modeled behavior. Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR adjusts the Python→Laurel translator to avoid arity mismatches when Python call sites pass more positional arguments than a modeled/prelude Laurel signature declares (e.g., datetime.now(timezone.utc) when the model declares 0 params), and adds a regression test for that scenario.
Changes:
- Truncate positional arguments to the modeled signature length during argument combination in
PythonToLaurel. - Add a new Python pipeline test covering
datetime.now(timezone.utc)and basic datetime arithmetic. - Register the new test in the Python CBMC expected-outcomes list as
PASS.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| Strata/Languages/Python/PythonToLaurel.lean | Truncates extra positional args during call argument processing to prevent Laurel arity mismatch. |
| StrataTest/Languages/Python/tests/test_datetime_now_tz.py | Adds regression test exercising datetime.now(timezone.utc) and timedelta arithmetic. |
| StrataTest/Languages/Python/tests/cbmc_expected.txt | Marks the new test as expected PASS in the CBMC pipeline runner. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
The previous truncation of extra positional arguments applied to all calls with a known funcDecl, including user-defined functions. This could silently hide real Python arity errors, making verification unsound. Now only prelude/external functions (where we intentionally under-model parameters) have extra trailing args silently dropped. User-defined functions raise an error when called with too many positional arguments, matching Python's TypeError semantics. Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Exercise the datetime.now(timezone.utc) scenario through the full Python → Laurel → Core → SMT pipeline in VerifyPythonTest, so the fix is tested by 'lake test' and not only via the CBMC pipeline. Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
olivier-aws
left a comment
There was a problem hiding this comment.
I'm surprised this is sound in general. Another solution would be to modify our Prelude functions to have the optional argument, and add "holes" when one argument is missing. Any reason why we shouldn't use this approach?
…tions Verify that calling a user-defined function with extra positional arguments produces the expected error through the full pipeline, exercised by 'lake test'. Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
…al args Instead of silently truncating extra positional arguments for prelude functions, add the missing optional parameter to the prelude signature. This is cleaner: the prelude accurately models Python's datetime.now(tz) signature, and extra positional args are now an error for all functions (user-defined and prelude alike). Changes: - Add tz:Any parameter to datetime_now in Laurel prelude - Add tz:AnyOrNone parameter to datetime_now in Core prelude - Add tz:AnyOrNone to datetime_now in FunctionSignatures - Remove arg-truncation and userFunctions distinction from combinePositionalAndKeywordArgs; extra args are always an error - Update PreludeVerifyTest assertion IDs (prelude size changed) Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
That's a great point that we are using a different approach elsewhere. I have now adopted that approach here as well. |
timezone.utc is not modeled in the prelude, causing resolution errors in CI where strata.gen is available. Use None to test the optional tz parameter instead. Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
…tional-args Resolve PreludeVerifyTest assertion ID conflict: adjust IDs for both upstream changes and the tz parameter addition. Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
The isVarKwargs path (** dict expansion) bypassed combinePositionalAndKeywordArgs entirely, so extra positional args before the **dict were not caught. Add the same arity check. Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Exercises the arity check in the isVarKwargs call path. Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
…tional-args # Conflicts: # StrataTest/Languages/Python/VerifyPythonTest.lean # StrataTest/Languages/Python/tests/cbmc_expected.txt
…tional-args # Conflicts: # StrataTest/Languages/Python/VerifyPythonTest.lean # StrataTest/Languages/Python/tests/cbmc_expected.txt
Problem
datetime.now(timezone.utc)caused an arity mismatch because the prelude'sdatetime_nowdeclared 0 parameters while the Python call passed 1 argument. This surfaced as a "call [end_time] := datetime_now($hole_12($heap_in))" error in check_storage_costs.Approach
Rather than silently dropping extra positional arguments (which could mask real bugs), we model the missing optional parameter in the prelude and add an arity check that rejects extra positional arguments for all functions.
Prelude changes:
tz: Anyparameter todatetime_nowin the Laurel preludetz: AnyOrNoneparameter todatetime_nowin the Core prelude and FunctionSignaturesArity checking:
combinePositionalAndKeywordArgsnow raises a user error when a call passes more positional arguments than the function signature declares, for both user-defined and prelude functions alikeBy submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.