Skip to content

Commit b265bcb

Browse files
author
Eve Kazarian
committed
Fix pre-commit: nbstripout ipynb, trailing newline on test file, ruff format
1 parent c5ce37f commit b265bcb

2 files changed

Lines changed: 39 additions & 77 deletions

File tree

doc/code/executor/attack/split_payload_attack.ipynb

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"cells": [
33
{
44
"cell_type": "markdown",
5-
"id": "889d45ef",
5+
"id": "0",
66
"metadata": {},
77
"source": [
88
"# Split-Payload Attack (Multi-Turn)\n",
@@ -30,7 +30,7 @@
3030
{
3131
"cell_type": "code",
3232
"execution_count": null,
33-
"id": "41206e71",
33+
"id": "1",
3434
"metadata": {},
3535
"outputs": [],
3636
"source": [
@@ -50,7 +50,7 @@
5050
},
5151
{
5252
"cell_type": "markdown",
53-
"id": "3468b00a",
53+
"id": "2",
5454
"metadata": {},
5555
"source": [
5656
"## Configure the attack\n",
@@ -64,7 +64,7 @@
6464
{
6565
"cell_type": "code",
6666
"execution_count": null,
67-
"id": "3f6c874f",
67+
"id": "3",
6868
"metadata": {},
6969
"outputs": [],
7070
"source": [
@@ -91,7 +91,7 @@
9191
{
9292
"cell_type": "code",
9393
"execution_count": null,
94-
"id": "d54e34f2",
94+
"id": "4",
9595
"metadata": {},
9696
"outputs": [],
9797
"source": [
@@ -111,7 +111,7 @@
111111
{
112112
"cell_type": "code",
113113
"execution_count": null,
114-
"id": "1ceab006",
114+
"id": "5",
115115
"metadata": {},
116116
"outputs": [],
117117
"source": [
@@ -120,7 +120,7 @@
120120
},
121121
{
122122
"cell_type": "markdown",
123-
"id": "81a3f77a",
123+
"id": "6",
124124
"metadata": {},
125125
"source": [
126126
"## Examine results\n",
@@ -135,7 +135,7 @@
135135
{
136136
"cell_type": "code",
137137
"execution_count": null,
138-
"id": "0e8b1129",
138+
"id": "7",
139139
"metadata": {},
140140
"outputs": [],
141141
"source": [
@@ -150,7 +150,7 @@
150150
{
151151
"cell_type": "code",
152152
"execution_count": null,
153-
"id": "950f71d9",
153+
"id": "8",
154154
"metadata": {},
155155
"outputs": [],
156156
"source": [

tests/unit/executor/attack/multi_turn/test_split_payload.py

Lines changed: 30 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -309,9 +309,7 @@ def test_harm_description_setter(self):
309309
class TestSplitPayloadAttackInitialization:
310310
"""Tests for SplitPayloadAttack initialization."""
311311

312-
def test_init_with_minimal_parameters(
313-
self, mock_objective_target: MagicMock, mock_adversarial_chat: MagicMock
314-
):
312+
def test_init_with_minimal_parameters(self, mock_objective_target: MagicMock, mock_adversarial_chat: MagicMock):
315313
adversarial_config = AttackAdversarialConfig(target=mock_adversarial_chat)
316314
attack = SplitPayloadAttack(
317315
objective_target=mock_objective_target,
@@ -369,9 +367,7 @@ def test_init_with_invalid_max_regenerations(
369367
max_regenerations=max_regenerations,
370368
)
371369

372-
def test_init_with_invalid_design_pattern(
373-
self, mock_objective_target: MagicMock, mock_adversarial_chat: MagicMock
374-
):
370+
def test_init_with_invalid_design_pattern(self, mock_objective_target: MagicMock, mock_adversarial_chat: MagicMock):
375371
adversarial_config = AttackAdversarialConfig(target=mock_adversarial_chat)
376372
with pytest.raises(ValueError, match="design_pattern must be one of"):
377373
SplitPayloadAttack(
@@ -400,8 +396,8 @@ def test_init_rejects_adversarial_chat_missing_capability(
400396
):
401397
from pyrit.prompt_target.common.target_capabilities import CapabilityName
402398

403-
mock_adversarial_chat.configuration.includes.side_effect = (
404-
lambda *, capability: capability != CapabilityName.SYSTEM_PROMPT
399+
mock_adversarial_chat.configuration.includes.side_effect = lambda *, capability: (
400+
capability != CapabilityName.SYSTEM_PROMPT
405401
)
406402
adversarial_config = AttackAdversarialConfig(target=mock_adversarial_chat)
407403
with pytest.raises(ValueError, match="SplitPayloadAttack"):
@@ -428,9 +424,7 @@ def test_get_attack_scoring_config(
428424
assert config.objective_scorer == mock_objective_scorer
429425
assert config.refusal_scorer == mock_refusal_scorer
430426

431-
def test_init_with_converter_config(
432-
self, mock_objective_target: MagicMock, mock_adversarial_chat: MagicMock
433-
):
427+
def test_init_with_converter_config(self, mock_objective_target: MagicMock, mock_adversarial_chat: MagicMock):
434428
from pyrit.prompt_converter import Base64Converter
435429
from pyrit.prompt_normalizer import PromptConverterConfiguration
436430

@@ -452,9 +446,7 @@ def test_init_with_converter_config(
452446
class TestContextValidation:
453447
"""Tests for context validation."""
454448

455-
def test_validate_context_empty_objective(
456-
self, mock_objective_target: MagicMock, mock_adversarial_chat: MagicMock
457-
):
449+
def test_validate_context_empty_objective(self, mock_objective_target: MagicMock, mock_adversarial_chat: MagicMock):
458450
attack = SplitPayloadTestHelper.create_attack(
459451
objective_target=mock_objective_target,
460452
adversarial_chat=mock_adversarial_chat,
@@ -540,26 +532,24 @@ async def test_setup_tracks_adversarial_conversation(
540532
class TestDecomposition:
541533
"""Tests for the decomposition phase."""
542534

543-
def test_parse_decomposition_valid(
544-
self, mock_objective_target: MagicMock, mock_adversarial_chat: MagicMock
545-
):
535+
def test_parse_decomposition_valid(self, mock_objective_target: MagicMock, mock_adversarial_chat: MagicMock):
546536
attack = SplitPayloadTestHelper.create_attack(
547537
objective_target=mock_objective_target,
548538
adversarial_chat=mock_adversarial_chat,
549539
max_turns=3,
550540
)
551-
response = json.dumps({
552-
"turns": ["Q1?", "Q2?", "Q3?"],
553-
"rationale": "test",
554-
"harm_description": "test harm",
555-
})
541+
response = json.dumps(
542+
{
543+
"turns": ["Q1?", "Q2?", "Q3?"],
544+
"rationale": "test",
545+
"harm_description": "test harm",
546+
}
547+
)
556548
result = attack._parse_decomposition_response(response)
557549
assert len(result["turns"]) == 3
558550
assert result["harm_description"] == "test harm"
559551

560-
def test_parse_decomposition_invalid_json(
561-
self, mock_objective_target: MagicMock, mock_adversarial_chat: MagicMock
562-
):
552+
def test_parse_decomposition_invalid_json(self, mock_objective_target: MagicMock, mock_adversarial_chat: MagicMock):
563553
attack = SplitPayloadTestHelper.create_attack(
564554
objective_target=mock_objective_target,
565555
adversarial_chat=mock_adversarial_chat,
@@ -811,9 +801,7 @@ async def test_regenerate_turn_returns_text(
811801
prompt_normalizer=mock_prompt_normalizer,
812802
)
813803
basic_context.session = ConversationSession()
814-
mock_prompt_normalizer.send_prompt_async.return_value = create_prompt_response(
815-
text="Alternative question?"
816-
)
804+
mock_prompt_normalizer.send_prompt_async.return_value = create_prompt_response(text="Alternative question?")
817805

818806
result = await attack._regenerate_turn_async(
819807
context=basic_context,
@@ -857,9 +845,7 @@ async def test_regenerate_turn_strips_quotes(
857845
prompt_normalizer=mock_prompt_normalizer,
858846
)
859847
basic_context.session = ConversationSession()
860-
mock_prompt_normalizer.send_prompt_async.return_value = create_prompt_response(
861-
text='"Alternative question?"'
862-
)
848+
mock_prompt_normalizer.send_prompt_async.return_value = create_prompt_response(text='"Alternative question?"')
863849

864850
result = await attack._regenerate_turn_async(
865851
context=basic_context,
@@ -898,9 +884,7 @@ async def test_perform_success_all_turns_pass_and_assembled_harmful(
898884
mock_prompt_normalizer.send_prompt_async.return_value = sample_response
899885

900886
with (
901-
patch.object(
902-
attack, "_decompose_objective_async", new_callable=AsyncMock, return_value=decomposition
903-
),
887+
patch.object(attack, "_decompose_objective_async", new_callable=AsyncMock, return_value=decomposition),
904888
patch.object(attack, "_check_refusal_async", new_callable=AsyncMock, return_value=no_refusal_score),
905889
patch.object(
906890
attack,
@@ -946,13 +930,9 @@ async def test_perform_failure_assembled_not_harmful(
946930
decomposition = {"turns": ["Q1?", "Q2?"], "harm_description": ""}
947931

948932
with (
949-
patch.object(
950-
attack, "_decompose_objective_async", new_callable=AsyncMock, return_value=decomposition
951-
),
933+
patch.object(attack, "_decompose_objective_async", new_callable=AsyncMock, return_value=decomposition),
952934
patch.object(attack, "_check_refusal_async", new_callable=AsyncMock, return_value=no_refusal_score),
953-
patch.object(
954-
attack, "_send_prompt_to_target_async", new_callable=AsyncMock, return_value=sample_response
955-
),
935+
patch.object(attack, "_send_prompt_to_target_async", new_callable=AsyncMock, return_value=sample_response),
956936
patch.object(
957937
attack,
958938
"_score_assembled_conversation_async",
@@ -989,16 +969,10 @@ async def test_perform_failure_turn_refused_after_max_regenerations(
989969

990970
# Refusal on every attempt
991971
with (
992-
patch.object(
993-
attack, "_decompose_objective_async", new_callable=AsyncMock, return_value=decomposition
994-
),
972+
patch.object(attack, "_decompose_objective_async", new_callable=AsyncMock, return_value=decomposition),
995973
patch.object(attack, "_check_refusal_async", new_callable=AsyncMock, return_value=refusal_score),
996-
patch.object(
997-
attack, "_send_prompt_to_target_async", new_callable=AsyncMock, return_value=sample_response
998-
),
999-
patch.object(
1000-
attack, "_regenerate_turn_async", new_callable=AsyncMock, return_value="Regenerated Q1?"
1001-
),
974+
patch.object(attack, "_send_prompt_to_target_async", new_callable=AsyncMock, return_value=sample_response),
975+
patch.object(attack, "_regenerate_turn_async", new_callable=AsyncMock, return_value="Regenerated Q1?"),
1002976
):
1003977
attack._memory.duplicate_conversation_excluding_last_turn.return_value = "new-conv-id"
1004978
result = await attack._perform_async(context=basic_context)
@@ -1033,18 +1007,10 @@ async def test_perform_with_regeneration_then_success(
10331007
refusal_results = [refusal_score, no_refusal_score]
10341008

10351009
with (
1036-
patch.object(
1037-
attack, "_decompose_objective_async", new_callable=AsyncMock, return_value=decomposition
1038-
),
1039-
patch.object(
1040-
attack, "_check_refusal_async", new_callable=AsyncMock, side_effect=refusal_results
1041-
),
1042-
patch.object(
1043-
attack, "_send_prompt_to_target_async", new_callable=AsyncMock, return_value=sample_response
1044-
),
1045-
patch.object(
1046-
attack, "_regenerate_turn_async", new_callable=AsyncMock, return_value="Regenerated Q1?"
1047-
),
1010+
patch.object(attack, "_decompose_objective_async", new_callable=AsyncMock, return_value=decomposition),
1011+
patch.object(attack, "_check_refusal_async", new_callable=AsyncMock, side_effect=refusal_results),
1012+
patch.object(attack, "_send_prompt_to_target_async", new_callable=AsyncMock, return_value=sample_response),
1013+
patch.object(attack, "_regenerate_turn_async", new_callable=AsyncMock, return_value="Regenerated Q1?"),
10481014
patch.object(
10491015
attack,
10501016
"_score_assembled_conversation_async",
@@ -1078,13 +1044,9 @@ async def test_perform_sets_atomic_attack_identifier(
10781044
decomposition = {"turns": ["Q1?"], "harm_description": ""}
10791045

10801046
with (
1081-
patch.object(
1082-
attack, "_decompose_objective_async", new_callable=AsyncMock, return_value=decomposition
1083-
),
1047+
patch.object(attack, "_decompose_objective_async", new_callable=AsyncMock, return_value=decomposition),
10841048
patch.object(attack, "_check_refusal_async", new_callable=AsyncMock, return_value=no_refusal_score),
1085-
patch.object(
1086-
attack, "_send_prompt_to_target_async", new_callable=AsyncMock, return_value=sample_response
1087-
),
1049+
patch.object(attack, "_send_prompt_to_target_async", new_callable=AsyncMock, return_value=sample_response),
10881050
patch.object(
10891051
attack,
10901052
"_score_assembled_conversation_async",
@@ -1278,4 +1240,4 @@ async def test_complete_successful_attack(
12781240
assert result.outcome == AttackOutcome.SUCCESS
12791241
assert result.executed_turns == 3
12801242
assert result.all_turns_passed_safety is True
1281-
assert result.assembled_payload_harmful is True
1243+
assert result.assembled_payload_harmful is True

0 commit comments

Comments
 (0)