From 6e5a7b42a6c7ec5443870bc1df4ae1d33c9d969c Mon Sep 17 00:00:00 2001 From: squid-protocol Date: Tue, 22 Sep 2026 18:36:20 -0400 Subject: [PATCH] fix: rename calls_out_ignore to _calls_out_ignore per helper-key convention (#3282) The foundation shipped the per-language ignore set as a bare rule key; two audits correctly rejected that: test_global_regex_syntax_integrity (every non-underscore rule must be a compiled regex) and the signal contract audit (every non-underscore key needs a SignalContract). The repo's convention for non-regex strategy keys is an underscore prefix + a HELPER_KEYS entry (#1209) -- adopted here: detector reads rules['_calls_out_ignore'], HELPER_KEYS documents it, dead-key baseline entry renamed with its removal condition intact. Co-Authored-By: Claude Fable 5 --- gitgalaxy/core/detector.py | 4 ++-- gitgalaxy/standards/signal_contracts.py | 1 + tests/core_engine/test_detector.py | 6 +++--- tests/dead_key_audit_baseline.json | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/gitgalaxy/core/detector.py b/gitgalaxy/core/detector.py index 3467735db6..8bfc034b68 100644 --- a/gitgalaxy/core/detector.py +++ b/gitgalaxy/core/detector.py @@ -867,7 +867,7 @@ def _cpp_class_has_body(code_stream: str, scan_start: int) -> bool: # control-flow keywords and cross-language builtins the invocation regexes # cannot distinguish from user calls. Case-sensitive on purpose: languages # whose keywords are case-insensitive (fortran, abap, pli, rexx, db2_sql, ada) -# declare their own lowercase words via the per-language `calls_out_ignore` +# declare their own lowercase words via the per-language `_calls_out_ignore` # rule, which is compared casefolded at the filter site. _CALLS_OUT_GLOBAL_IGNORE = frozenset( { @@ -8708,7 +8708,7 @@ def _calculate_block_metrics( # Per-language additions to the global ignore set (Epic #3264 Phase 3). # Authored lowercase in the profile and compared casefolded, so # case-insensitive languages filter their keywords in any spelling. - lang_ignore = rules.get("calls_out_ignore") or frozenset() + lang_ignore = rules.get("_calls_out_ignore") or frozenset() # Deduplicate and filter (excluding the function calling itself recursively) calls_out = list( dict.fromkeys( diff --git a/gitgalaxy/standards/signal_contracts.py b/gitgalaxy/standards/signal_contracts.py index 836be2e669..b6d646aacd 100644 --- a/gitgalaxy/standards/signal_contracts.py +++ b/gitgalaxy/standards/signal_contracts.py @@ -764,6 +764,7 @@ def _c(name, phase, kind, contract, **kw): # tabular constructor, see rows belo "_visibility_export": "per-function export-statement form, for the api orphan census (#2727/#2729)", "_visibility_export_list": "capture group(s) = a region holding MANY exported names, same census (#2823)", "_args_arrow_count_groups": "args strategy: arrow-function parameter groups", + "_calls_out_ignore": "frozenset of lowercase callee names UNIONed with the detector's global calls_out ignore set, compared casefolded (case-insensitive languages filter keywords in any spelling) -- Epic #3264 Phase 3 (#3282)", "_args_bare_body_groups": "args strategy: bare-body parameter groups", "_args_colon_selector_groups": "args strategy: colon-selector parameter groups (objective-c)", "_args_findall_max_groups": "args strategy: take the maximum over findall groups", diff --git a/tests/core_engine/test_detector.py b/tests/core_engine/test_detector.py index d86e3ceb6a..46eadefccc 100644 --- a/tests/core_engine/test_detector.py +++ b/tests/core_engine/test_detector.py @@ -1109,7 +1109,7 @@ def test_detector_classification_and_wiring(): def test_detector_calls_out_language_ignore_union(): """ - Proves the per-language `calls_out_ignore` rule (Epic #3264 Phase 3) is + Proves the per-language `_calls_out_ignore` rule (Epic #3264 Phase 3) is unioned with the global ignore set and compared casefolded: a language authoring lowercase words filters them in any spelling (case-insensitive languages get correct behavior for free), while the global set keeps @@ -1121,7 +1121,7 @@ def test_detector_calls_out_language_ignore_union(): "rules": { "func_start": re.compile(r"^[ \t]*def\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\(", re.M), "calls_out": re.compile(r"\b([a-zA-Z_][a-zA-Z0-9_]*)\s*\("), - "calls_out_ignore": frozenset({"open"}), + "_calls_out_ignore": frozenset({"open"}), }, } } @@ -1132,7 +1132,7 @@ def test_detector_calls_out_language_ignore_union(): func = result["functions"][0] assert func["calls_out_to"] == ["db_insert"], ( - "calls_out_ignore must filter casefolded (OPEN/Open) and the global " + "_calls_out_ignore must filter casefolded (OPEN/Open) and the global " f"set must keep filtering (print); got {func['calls_out_to']}" ) diff --git a/tests/dead_key_audit_baseline.json b/tests/dead_key_audit_baseline.json index 6b112f2f65..84c6fafa9f 100644 --- a/tests/dead_key_audit_baseline.json +++ b/tests/dead_key_audit_baseline.json @@ -1,3 +1,3 @@ { - "calls_out_ignore": "Read added by the #3282 foundation (Epic #3264 Phase 3) ahead of its writers by design: the per-language ignore sets land in #3284-#3287, and the foundation must merge first while staying output-neutral. Remove this entry in the first batch PR that ships a rules['calls_out_ignore'] set." + "_calls_out_ignore": "Read added by the #3282 foundation (Epic #3264 Phase 3) ahead of its writers by design: the per-language ignore sets land in #3284-#3287, and the foundation must merge first while staying output-neutral. Remove this entry in the first batch PR that ships a rules['_calls_out_ignore'] set." }