Skip to content

Commit 929d398

Browse files
FIX: Move AttackStrategy import to TYPE_CHECKING to break circular import
PR #1881 (Pydantic identifiers refactor) re-merged with this PR's compute_inner_attack_eval_hash addition and hoisted rom pyrit.executor.attack.core.attack_strategy import AttackStrategy to module level. That import triggers a cycle through `pyrit.executor.attack` -> `pyrit.message_normalizer` -> `pyrit.common.data_url_converter` -> `pyrit.models`, which fails because `pyrit.models` is still being initialised at that point (DataTypeSerializer is not yet defined). `from __future__ import annotations` is already enabled, so the type annotation `attack: AttackStrategy` works as a string. Moving the import inside `if TYPE_CHECKING:` restores the original lazy boundary and unblocks CI. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 115d1f7 commit 929d398

2 files changed

Lines changed: 8 additions & 2 deletions

File tree

pyrit/models/identifiers/evaluation_identifier.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@
2323
from __future__ import annotations
2424

2525
from abc import ABC
26-
from typing import Any, ClassVar, Optional
26+
from typing import TYPE_CHECKING, Any, ClassVar, Optional
2727

2828
from pydantic import BaseModel, ConfigDict, Field
2929

30-
from pyrit.executor.attack.core.attack_strategy import AttackStrategy
3130
from pyrit.models.identifiers.component_identifier import ComponentIdentifier, config_hash
3231

32+
if TYPE_CHECKING:
33+
from pyrit.executor.attack.core.attack_strategy import AttackStrategy
34+
3335
# Behavioral params that define model output quality for scoring.
3436
TARGET_EVAL_PARAMS: frozenset[str] = frozenset({"underlying_model_name", "temperature", "top_p"})
3537
TARGET_EVAL_PARAM_FALLBACKS: dict[str, str] = {"underlying_model_name": "model_name"}

tests/unit/models/identifiers/test_evaluation_identifier.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,7 @@ def test_scorer_eval_hash_matches_with_and_without_round_robin(self):
585585

586586
assert eval_direct == eval_rr
587587

588+
588589
class TestComputeInnerAttackEvalHash:
589590
"""``compute_inner_attack_eval_hash`` should match what the executor stamps."""
590591

@@ -654,6 +655,8 @@ def test_matches_persisted_row_eval_hash(self):
654655
)
655656
entry = AttackResultEntry(entry=result)
656657
assert entry.atomic_attack_identifier["eval_hash"] == predicted
658+
659+
657660
# ---------------------------------------------------------------------------
658661
# OWN_RULE / leaf-entity eval-hash tests
659662
# ---------------------------------------------------------------------------
@@ -864,6 +867,7 @@ def test_stored_eval_hash_takes_precedence(self):
864867

865868
assert ObjectiveTargetEvaluationIdentifier(cid).eval_hash == stored
866869

870+
867871
class TestComputeInnerAttackEvalHash:
868872
"""``compute_inner_attack_eval_hash`` should match what the executor stamps."""
869873

0 commit comments

Comments
 (0)