Repository navigation
Bind built-in named arguments by parameter name - #307
luisleo526 wants to merge 1 commit into
Conversation
…ames math.pow names its second parameter exponent. The registry called it exp, so a keyword exponent was dropped and the call lowered to a one-argument std::pow that does not compile, while the spelling exp compiled and ran. Callables whose declared parameter names are their complete keyword set now carry keyword_names_verified. For such a record an undeclared keyword is refused at its name through the catalog (PF-E2027), in the support check and in the shared merge helper. Records without the flag keep their existing keyword handling byte for byte. math.pow is the first record to carry it. Tests cover the named, mixed and reversed forms against the positional call, the refusal and its span, a flag-driven generic family built at test time, registry coverage of the lookup, and the absence of evidence fields in the registry. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 1 advisory finding(s) below merit a look before merge.
Not checked: tests were not run; formal verification proved 0 of 10 changed function(s) (1 sampled, not proven, 9 not verified).
Formal verification. PR-changed functions: 1/10 verified (0 proven, 1 may-equivalent, 0 distinguished) · 9 not verified (3 vacuous, 6 unsupported).
Not verified on this run: \_build\_security\_math\_call (unsupported), \_resolve\_func\_args (unsupported), \_visit\_func\_call (unsupported), \_visit\_math\_call (unsupported), \_visit\_str\_call (unsupported), \_parse\_call\_args (vacuous: never exercised), \_func (vacuous: never exercised), \_math (vacuous: never exercised), \_visit\_FuncCall (unsupported).
Graphify review — findings
Adds keyword-name validation for registry builtins marked keyword_names_verified, so an unknown keyword reports PF-E2027 at the keyword instead of being silently dropped. The names are checked by the support checker before lowering and again in _merge_kwargs, which now accepts the intrinsic record from the math, str, time, timestamp, request and generic-signature call paths; records without the flag keep their existing binding. math.pow now declares base, exponent so both named forms emit the positional expression, and argument ordering stays under the separate PF-E2074 check.
Worth a look
- Unknown-keyword validation only runs in SupportChecker, so check_support=False silently accepts bad kwargs —
pineforge_codegen/support_checker.py:1639· Escalate · medium- NOT verified (no proof, no reproducing execution) — needs human review
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 4326 functions depend on the 1181 functions this change touches.
Health — this change adds coupling hotspots:
- new:
intrinsic_keyword_diagnostics()— 3 callers, 4 callees - new:
test_shared_parameter_names_resolve_each_callable_record()— 0 callers, 6 callees
Verification — 4326 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 3731 function(s) in the blast radius were not formally verified this run
Cross-repo impact
Cross-repo impact
No cross-repo impact detected among the indexed peer repo(s).
1 peer repo(s) in this group are not yet indexed — cross-repo impact may be incomplete.
Cross-repo linkage is derived (SCIP-moniker matches are sound; name/contract matches are heuristic) and ADVISORY — it never affects this check's conclusion.
Formal verification
Could not verify: Could not verify \_build\_security\_math\_call.
The verifier did not have enough to check \_build\_security\_math\_call, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
No difference found (not proven): No behavior difference found in \_merge\_kwargs (not a proof).
The verifier ran both versions of \_merge\_kwargs on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.
Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.
Note: An input the sampler did not try could still differ.
Could not verify: Could not verify \_resolve\_func\_args.
The verifier did not have enough to check \_resolve\_func\_args, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify \_visit\_func\_call.
The verifier did not have enough to check \_visit\_func\_call, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify \_visit\_math\_call.
The verifier did not have enough to check \_visit\_math\_call, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify \_visit\_str\_call.
The verifier did not have enough to check \_visit\_str\_call, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify \_parse\_call\_args.
The verifier did not have enough to check \_parse\_call\_args, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: not verifiable: all 3 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly __init__ raised on the synthesized receiver args — names the real obstacle, not a sampling gap)
Could not verify: Could not verify \_func.
The verifier did not have enough to check \_func, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: not verified: a runtime divergence was observed, but the two versions' package snapshots loaded differently in the sandbox (old: {'fallback': {'pineforge_codegen': 'ImportError', 'pineforge_codegen.codegen': 'ImportError', 'pineforge_codegen.codegen.base': 'ModuleNotFoundError'}, 'missing': ['pineforge_codegen.codegen.emit_top', 'pineforge_codegen.codegen.input', 'pineforge_codegen.codegen.security', 'pineforge_codegen.codegen.ta', 'pineforge_codegen.codegen.types', 'pineforge_codegen.codegen.visit_call', 'pineforge_codegen.codegen.visit_expr', 'pineforge_codegen.codegen.visit_stmt']}, new: {'fallback': {'pineforge_codegen': 'ImportError', 'pineforge_codegen.codegen': 'ImportError', 'pineforge_codegen.codegen.base': 'ModuleNotFoundError', 'pineforge_codegen.codegen.collection_history': 'ModuleNotFoundError'}, 'missing': ['pineforge_codegen.codegen.emit_top', 'pineforge_codegen.codegen.history_sharing', 'pineforge_codegen\…
Could not verify: Could not verify \_math.
The verifier did not have enough to check \_math, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: not verified: a runtime divergence was observed, but the two versions' package snapshots loaded differently in the sandbox (old: {'fallback': {'pineforge_codegen': 'ImportError', 'pineforge_codegen.codegen': 'ImportError', 'pineforge_codegen.codegen.base': 'ModuleNotFoundError'}, 'missing': ['pineforge_codegen.codegen.emit_top', 'pineforge_codegen.codegen.input', 'pineforge_codegen.codegen.security', 'pineforge_codegen.codegen.ta', 'pineforge_codegen.codegen.types', 'pineforge_codegen.codegen.visit_call', 'pineforge_codegen.codegen.visit_expr', 'pineforge_codegen.codegen.visit_stmt']}, new: {'fallback': {'pineforge_codegen': 'ImportError', 'pineforge_codegen.codegen': 'ImportError', 'pineforge_codegen.codegen.base': 'ModuleNotFoundError', 'pineforge_codegen.codegen.collection_history': 'ModuleNotFoundError'}, 'missing': ['pineforge_codegen.codegen.emit_top', 'pineforge_codegen.codegen.history_sharing', 'pineforge_codegen\…
Could not verify: Could not verify \_visit\_FuncCall.
The verifier did not have enough to check \_visit\_FuncCall, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
· 2 grounded finding(s) anchored inline below.
| from .signatures import IntrinsicFunc | ||
|
|
||
|
|
||
| def intrinsic_keyword_diagnostics( |
There was a problem hiding this comment.
intrinsic_keyword_diagnostics()
high coupling complexity (Ca·Ce = 12).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| 'request.security(syminfo.tickerid, "60", {expression})', | ||
| )) | ||
| @pytest.mark.parametrize("check_support", (True, False)) | ||
| def test_shared_parameter_names_resolve_each_callable_record( |
There was a problem hiding this comment.
test_shared_parameter_names_resolve_each_callable_record()
fans out to 6 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
Built-in calls now bind named arguments by the parameter's name instead of failing in the generated C++.
math.pow(base=..., exponent=...), mixed positional-then-named calls and reversed named order now compile and produce the same value as the positional form.exp=onmath.pow) is refused at its source location with a catalog diagnostic, as TradingView refuses it.Compiling scripts that do not use named built-in arguments are unchanged.
🤖 Generated with Claude Code