From 1680182953b7dbf3164227d99b6f9f6cdb25d71a Mon Sep 17 00:00:00 2001 From: Ed_ Date: Mon, 22 Jun 2026 01:05:17 -0400 Subject: [PATCH] feat(audit): add FunctionRef dataclass (frozen, 4 fields) fqname, file, line, role. Used in ProducerConsumerGraph edges and per-aggregate producer/consumer lists. Per error_handling.md Pattern 1 (immutability for cross-thread safety). 2 unit tests passing. --- src/code_path_audit.py | 10 +++++++++- tests/test_code_path_audit.py | 30 +++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/code_path_audit.py b/src/code_path_audit.py index b063f82a..a1682dca 100644 --- a/src/code_path_audit.py +++ b/src/code_path_audit.py @@ -9,6 +9,7 @@ postfix DSL + markdown + prefix tree text. See conductor/tracks/code_path_audit_20260607/spec_v2.md. """ from __future__ import annotations +from dataclasses import dataclass from typing import Literal AggregateKind = Literal[ @@ -51,4 +52,11 @@ RecommendedDirection = Literal[ "unify", "hold", "insufficient_data", -] \ No newline at end of file +] + +@dataclass(frozen=True) +class FunctionRef: + fqname: str + file: str + line: int + role: str \ No newline at end of file diff --git a/tests/test_code_path_audit.py b/tests/test_code_path_audit.py index 78fe4c77..96ba1c8c 100644 --- a/tests/test_code_path_audit.py +++ b/tests/test_code_path_audit.py @@ -1,10 +1,13 @@ """Tests for src.code_path_audit v2 - Phase 1 (data model).""" +from __future__ import annotations +import pytest from src.code_path_audit import ( AggregateKind, MemoryDim, AccessPattern, Frequency, RecommendedDirection, + FunctionRef, ) def test_aggregate_kind_4_values() -> None: @@ -30,4 +33,29 @@ def test_frequency_7_values() -> None: def test_recommended_direction_4_values() -> None: """RecommendedDirection is a Literal with 4 values: componentize, unify, hold, insufficient_data.""" expected = {"componentize", "unify", "hold", "insufficient_data"} - assert set(RecommendedDirection.__args__) == expected \ No newline at end of file + assert set(RecommendedDirection.__args__) == expected + +def test_function_ref_4_fields() -> None: + """FunctionRef has fqname, file, line, role (per spec).""" + ref = FunctionRef( + fqname="src.ai_client.AIClient.send_result", + file="src/ai_client.py", + line=100, + role="producer", + ) + assert ref.fqname == "src.ai_client.AIClient.send_result" + assert ref.file == "src/ai_client.py" + assert ref.line == 100 + assert ref.role == "producer" + +def test_function_ref_frozen() -> None: + """FunctionRef is frozen (immutability per error_handling.md).""" + ref = FunctionRef( + fqname="src.x.y", + file="src/x.py", + line=1, + role="consumer", + ) + with pytest.raises((AttributeError, Exception)) as exc_info: + ref.fqname = "src.z.w" + assert "frozen" in str(exc_info.value).lower() or "cannot assign" in str(exc_info.value).lower() \ No newline at end of file