Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ litellm = [

github-copilot = [
# Keep the last known working session API until the target is migrated (#3623).
"github-copilot-sdk>=1.0.11,<1.0.23",
"github-copilot-sdk>=1.0.11,<1.0.30",
]
a2a = [
"a2a-sdk>=1.1.5,<2",
Expand All @@ -167,7 +167,7 @@ all = [
"azure-ai-ml>=1.32.0",
"azure-cognitiveservices-speech>=1.44.0",
"flask>=3.1.3",
"github-copilot-sdk>=1.0.11,<1.0.23",
"github-copilot-sdk>=1.0.11,<1.0.30",
"ipykernel>=6.29.5",
"jupyter>=1.1.1",
"litellm>=1.104.2",
Expand Down
2 changes: 1 addition & 1 deletion pyrit/auth/browser_session_copilot_authenticator.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ def _create_playwright_context_manager() -> Any:
RuntimeError: If Playwright is not installed.
"""
try:
from playwright.async_api import async_playwright # type: ignore[ty:unresolved-import]
from playwright.async_api import async_playwright # type: ignore[ty:import-not-found]
except ImportError:
raise RuntimeError(
"Playwright is required for browser-session authentication. "
Expand Down
4 changes: 2 additions & 2 deletions pyrit/auth/copilot_authenticator.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ async def _fetch_access_token_with_playwright_async(self) -> str | None:
import sys

try:
from playwright.async_api import async_playwright # type: ignore[ty:unresolved-import] # noqa: F401
from playwright.async_api import async_playwright # type: ignore[ty:import-not-found] # noqa: F401
except ImportError:
raise RuntimeError(
"Playwright is not installed. Please install it with: "
Expand Down Expand Up @@ -365,7 +365,7 @@ async def _run_playwright_browser_automation_async(self) -> str | None:
Raises:
ValueError: If the username is not set.
"""
from playwright.async_api import async_playwright # type: ignore[ty:unresolved-import]
from playwright.async_api import async_playwright # type: ignore[ty:import-not-found]

bearer_token: str | None = None
token_expires_in = None
Expand Down
2 changes: 1 addition & 1 deletion pyrit/converter/puzzled/keyword_masker.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ def _get_nlp() -> Any:
if _nlp_loaded:
return _nlp
try:
import spacy # type: ignore[ty:unresolved-import]
import spacy # type: ignore[ty:import-not-found]

_nlp = spacy.load("en_core_web_sm")
except (ImportError, OSError):
Expand Down
2 changes: 1 addition & 1 deletion pyrit/executor/benchmark/fairness_bias.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def _get_nlp() -> Any:
if _nlp_loaded:
return _nlp
try:
import spacy # type: ignore[ty:unresolved-import]
import spacy # type: ignore[ty:import-not-found]

_nlp = spacy.load("en_core_web_sm")
except Exception:
Expand Down
4 changes: 2 additions & 2 deletions pyrit/prompt_target/hugging_face/hugging_face_chat_target.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def __init__(
self.huggingface_token = None

try:
import torch # type: ignore[ty:unresolved-import]
import torch # type: ignore[ty:import-not-found]
except ModuleNotFoundError as e:
raise RuntimeError("Could not import torch. You may need to install it via 'pip install pyrit[all]'") from e

Expand Down Expand Up @@ -538,7 +538,7 @@ def _seed_rng(self) -> None:
the same process may interfere with determinism.
"""
if self._random_seed is not None:
import torch # type: ignore[ty:unresolved-import]
import torch # type: ignore[ty:import-not-found]

torch.manual_seed(self._random_seed)
if self.use_cuda:
Expand Down
2 changes: 1 addition & 1 deletion pyrit/prompt_target/playwright_copilot_target.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

# Avoid errors for users who don't have playwright installed
if TYPE_CHECKING:
from playwright.async_api import Page # type: ignore[ty:unresolved-import]
from playwright.async_api import Page # type: ignore[ty:import-not-found]
else:
Page = None

Expand Down
2 changes: 1 addition & 1 deletion pyrit/prompt_target/playwright_target.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

# Avoid errors for users who don't have playwright installed
if TYPE_CHECKING:
from playwright.async_api import Page # type: ignore[ty:unresolved-import]
from playwright.async_api import Page # type: ignore[ty:import-not-found]
else:
Page = None

Expand Down
6 changes: 3 additions & 3 deletions pyrit/score/true_false/local_refusal_classifier_scorer.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ def _is_loaded(self) -> bool:

def _load_model(self) -> Any:
try:
import laya # type: ignore[ty:unresolved-import]
import laya # type: ignore[ty:import-not-found]
except (ImportError, ModuleNotFoundError) as exc:
raise RuntimeError(
"LocalRefusalClassifierScorer requires the 'laya' package. Install it with `pip install laya`."
Expand Down Expand Up @@ -217,7 +217,7 @@ def _training_features(

def _features_from_sequences(self, sequences: list[tuple[list[int], list[int]]]) -> list[float]:
import torch
from laya.common import QTYPES, collate_items # type: ignore[ty:unresolved-import]
from laya.common import QTYPES, collate_items # type: ignore[ty:import-not-found]

agent = self._agent
if agent is None:
Expand Down Expand Up @@ -279,7 +279,7 @@ def _response_windows(
chunk_overlap_tokens: int,
max_objective_tokens: int,
) -> tuple[Iterator[list[tuple[list[int], list[int]]]], bool]:
from laya.common import build_sequence # type: ignore[ty:unresolved-import]
from laya.common import build_sequence # type: ignore[ty:import-not-found]

agent = self._agent
if agent is None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

from pyrit.executor.attack import AttackScoringConfig
from pyrit.scenario import ScenarioTechnique
from pyrit.scenario.foundry import FoundryTechnique, RedTeamAgent # type: ignore[ty:unresolved-import]
from pyrit.scenario.foundry import FoundryTechnique, RedTeamAgent # type: ignore[ty:import-not-found]


class TestRedTeamStrategyContract:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
def _azure_ai_evaluation_available() -> bool:
"""Check if azure-ai-evaluation[redteam] is installed."""
try:
from azure.ai.evaluation.red_team import RedTeam # type: ignore[ty:unresolved-import] # noqa: F401
from azure.ai.evaluation.red_team import RedTeam # type: ignore[ty:import-not-found] # noqa: F401

return True
except ImportError:
Expand All @@ -37,7 +37,7 @@ class TestRedTeamModuleImports:

def test_redteam_public_api_imports(self):
"""Verify all public classes from azure.ai.evaluation.red_team are importable."""
from azure.ai.evaluation.red_team import ( # type: ignore[ty:unresolved-import]
from azure.ai.evaluation.red_team import ( # type: ignore[ty:import-not-found]
AttackStrategy,
RedTeam,
RedTeamResult,
Expand Down Expand Up @@ -70,7 +70,7 @@ class TestCallbackChatTargetInheritance:

def test_callback_chat_target_extends_prompt_target(self):
"""_CallbackChatTarget must be a subclass of pyrit.prompt_target.PromptTarget."""
from azure.ai.evaluation.red_team._callback_chat_target import ( # type: ignore[ty:unresolved-import]
from azure.ai.evaluation.red_team._callback_chat_target import ( # type: ignore[ty:import-not-found]
_CallbackChatTarget,
)

Expand All @@ -87,7 +87,7 @@ class TestRAIScorerInheritance:

def test_rai_scorer_extends_true_false_scorer(self):
"""RAIServiceScorer must be a subclass of pyrit.score.true_false.TrueFalseScorer."""
from azure.ai.evaluation.red_team._foundry._rai_scorer import ( # type: ignore[ty:unresolved-import]
from azure.ai.evaluation.red_team._foundry._rai_scorer import ( # type: ignore[ty:import-not-found]
RAIServiceScorer, # private: intentional
)

Expand Down
2 changes: 1 addition & 1 deletion tests/unit/auth/test_azure_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def provider():

def is_speechsdk_installed():
try:
import azure.cognitiveservices.speech # type: ignore[ty:unresolved-import] # noqa: F401
import azure.cognitiveservices.speech # type: ignore[ty:import-not-found] # noqa: F401

return True
except ModuleNotFoundError:
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/converter/test_azure_speech_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

def is_speechsdk_installed():
try:
import azure.cognitiveservices.speech # type: ignore[ty:unresolved-import] # noqa: F401
import azure.cognitiveservices.speech # type: ignore[ty:import-not-found] # noqa: F401

return True
except ModuleNotFoundError:
Expand All @@ -34,7 +34,7 @@ async def test_azure_speech_text_to_audio_convert_async(
MockSpeechSynthesizer, # noqa: N803
sqlite_instance,
):
import azure.cognitiveservices.speech as speechsdk # type: ignore[ty:unresolved-import]
import azure.cognitiveservices.speech as speechsdk # type: ignore[ty:import-not-found]

mock_synthesizer = MagicMock()
mock_result = MagicMock()
Expand Down
10 changes: 5 additions & 5 deletions tests/unit/converter/test_azure_speech_text_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

def is_speechsdk_installed():
try:
import azure.cognitiveservices.speech # type: ignore[ty:unresolved-import] # noqa: F401
import azure.cognitiveservices.speech # type: ignore[ty:import-not-found] # noqa: F401

return True
except ModuleNotFoundError:
Expand Down Expand Up @@ -39,7 +39,7 @@ def test_azure_speech_audio_text_converter_initialization(self, mock_get_require
@patch("azure.cognitiveservices.speech.SpeechRecognizer")
@patch("pyrit.converter.azure_speech_audio_to_text_converter.logger")
def test_stop_cb(self, mock_logger, MockSpeechRecognizer, mock_get_required_value): # noqa: N803
import azure.cognitiveservices.speech as speechsdk # type: ignore[ty:unresolved-import]
import azure.cognitiveservices.speech as speechsdk # type: ignore[ty:import-not-found]

# Create a mock event
mock_event = MagicMock(spec=speechsdk.SpeechRecognitionCanceledEventArgs)
Expand All @@ -63,7 +63,7 @@ def test_stop_cb(self, mock_logger, MockSpeechRecognizer, mock_get_required_valu

@patch("pyrit.converter.azure_speech_audio_to_text_converter.logger")
def test_stop_cb_session_stopped_event_has_no_result(self, mock_logger):
import azure.cognitiveservices.speech as speechsdk # type: ignore[ty:unresolved-import]
import azure.cognitiveservices.speech as speechsdk # type: ignore[ty:import-not-found]

# session_stopped delivers a SessionEventArgs, which has no `result`; spec keeps the mock
# from inventing one.
Expand All @@ -80,7 +80,7 @@ def test_stop_cb_session_stopped_event_has_no_result(self, mock_logger):

@patch("pyrit.converter.azure_speech_audio_to_text_converter.logger")
def test_stop_cb_canceled_event_logs_error_details(self, mock_logger):
import azure.cognitiveservices.speech as speechsdk # type: ignore[ty:unresolved-import]
import azure.cognitiveservices.speech as speechsdk # type: ignore[ty:import-not-found]

event = MagicMock(spec=speechsdk.SpeechRecognitionCanceledEventArgs)
event.result.reason = speechsdk.ResultReason.Canceled
Expand All @@ -103,7 +103,7 @@ def test_stop_cb_canceled_event_logs_error_details(self, mock_logger):
@patch("azure.cognitiveservices.speech.SpeechRecognizer")
@patch("pyrit.converter.azure_speech_audio_to_text_converter.logger")
def test_transcript_cb(self, mock_logger, MockSpeechRecognizer, mock_get_required_value): # noqa: N803
import azure.cognitiveservices.speech as speechsdk # type: ignore[ty:unresolved-import]
import azure.cognitiveservices.speech as speechsdk # type: ignore[ty:import-not-found]

# Create a mock event
mock_event = MagicMock()
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/executor/benchmark/test_fairness_bias.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

def is_spacy_installed():
try:
import spacy # type: ignore[ty:unresolved-import] # noqa: F401
import spacy # type: ignore[ty:import-not-found] # noqa: F401

return True
except Exception:
Expand Down
8 changes: 4 additions & 4 deletions tests/unit/executor/promptgen/gcg/test_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def test_init_does_not_touch_global_multiprocessing_state(self) -> None:
"""Regression: __init__ used to call torch.multiprocessing.set_start_method,
which crashed under coverage runs when an earlier test had already pinned a
non-spawn context. Worker spawn config now happens in _setup_async."""
import torch.multiprocessing as mp # type: ignore[ty:unresolved-import]
import torch.multiprocessing as mp # type: ignore[ty:import-not-found]

with patch.object(mp, "set_start_method") as mock_set:
GCGGenerator(models=[GCGModelConfig(name=_LLAMA_2)])
Expand All @@ -77,7 +77,7 @@ class TestEnsureSpawnStartMethod:
"""Tests for the lazily-applied spawn-method guard used before workers are spawned."""

def test_sets_spawn_when_unset(self) -> None:
import torch.multiprocessing as mp # type: ignore[ty:unresolved-import]
import torch.multiprocessing as mp # type: ignore[ty:import-not-found]

gen = GCGGenerator(models=[GCGModelConfig(name=_LLAMA_2)])
with (
Expand All @@ -89,7 +89,7 @@ def test_sets_spawn_when_unset(self) -> None:
mock_set.assert_called_once_with("spawn")

def test_noop_when_already_spawn(self) -> None:
import torch.multiprocessing as mp # type: ignore[ty:unresolved-import]
import torch.multiprocessing as mp # type: ignore[ty:import-not-found]

gen = GCGGenerator(models=[GCGModelConfig(name=_LLAMA_2)])
with (
Expand All @@ -103,7 +103,7 @@ def test_warns_and_does_not_crash_when_already_other(self, caplog) -> None:
"""Used to raise 'context has already been set' — now we warn and continue."""
import logging

import torch.multiprocessing as mp # type: ignore[ty:unresolved-import]
import torch.multiprocessing as mp # type: ignore[ty:import-not-found]

gen = GCGGenerator(models=[GCGModelConfig(name=_LLAMA_2)])
with (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

def is_torch_installed():
try:
import torch # type: ignore[ty:unresolved-import] # noqa: F401
import torch # type: ignore[ty:import-not-found] # noqa: F401

return True
except ModuleNotFoundError:
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/scenario/airt/test_leakage.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from pyrit.prompt_target import PromptTarget
from pyrit.registry import AttackTechniqueRegistry, TargetRegistry
from pyrit.scenario import DatasetAttackConfiguration, IncompatibleTechniqueError
from pyrit.scenario.airt import Leakage # type: ignore[ty:unresolved-import]
from pyrit.scenario.airt import Leakage # type: ignore[ty:import-not-found]
from pyrit.scenario.core import BaselineAttackPolicy, resolve_technique_factories_for_techniques
from pyrit.scenario.scenarios.airt.leakage import _build_leakage_technique, _leakage_factories
from pyrit.score import TrueFalseCompositeScorer
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/scenario/core/test_technique_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import pytest

from pyrit.scenario.foundry import FoundryComposite, FoundryTechnique # type: ignore[ty:unresolved-import]
from pyrit.scenario.foundry import FoundryComposite, FoundryTechnique # type: ignore[ty:import-not-found]


class TestFoundryComposite:
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/scenario/foundry/test_red_team_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
from pyrit.scenario import AtomicAttack, DatasetAttackConfiguration, IncompatibleTechniqueError
from pyrit.scenario.core import override_default_adversarial_target
from pyrit.scenario.core.scenario_context import ScenarioContext
from pyrit.scenario.foundry import ( # type: ignore[ty:unresolved-import]
from pyrit.scenario.foundry import ( # type: ignore[ty:import-not-found]
FoundryComposite,
FoundryTechnique,
RedTeamAgent,
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/scenario/garak/test_api_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from pyrit.scenario import BaselineAttackPolicy, DatasetAttackConfiguration, DatasetSource, ScenarioRequiredData
from pyrit.scenario.core import DatasetConstraintError, ResolvedDataset
from pyrit.scenario.core.required_data import _RequiredDatasetConfiguration
from pyrit.scenario.garak import ( # type: ignore[ty:unresolved-import]
from pyrit.scenario.garak import ( # type: ignore[ty:import-not-found]
ApiKey,
ApiKeyDatasetConfiguration,
ApiKeyTechnique,
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/scenario/garak/test_audio_achilles_heel.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from pyrit.executor.attack import PromptSendingAttack
from pyrit.models import ComponentIdentifier, SeedPrompt
from pyrit.prompt_target import PromptTarget
from pyrit.scenario.garak import AudioAchillesHeel, AudioAchillesHeelTechnique # type: ignore[ty:unresolved-import]
from pyrit.scenario.garak import AudioAchillesHeel, AudioAchillesHeelTechnique # type: ignore[ty:import-not-found]
from pyrit.scenario.scenarios.garak.audio_achilles_heel import (
DEFAULT_MAX_DATASET_SIZE,
DEFAULT_TEXT_PROMPT,
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/scenario/garak/test_doctor.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from pyrit.prompt_target import PromptTarget
from pyrit.registry import Registry
from pyrit.scenario import BaselineAttackPolicy, DatasetAttackConfiguration, ScenarioTechnique
from pyrit.scenario.garak import Doctor, DoctorTechnique # type: ignore[ty:unresolved-import]
from pyrit.scenario.garak import Doctor, DoctorTechnique # type: ignore[ty:import-not-found]
from pyrit.scenario.scenarios._dynamic_techniques import reset_dynamic_technique_caches
from pyrit.scenario.scenarios.garak.doctor import DOCTOR_FACTORIES
from pyrit.score import TrueFalseScorer
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/scenario/garak/test_encoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from pyrit.models import AttackSeedGroup, ComponentIdentifier, DatasetFetchPolicy, SeedObjective, SeedPrompt
from pyrit.prompt_target import PromptTarget
from pyrit.scenario import CompoundDatasetAttackConfiguration, DatasetAttackConfiguration, DatasetConfiguration
from pyrit.scenario.garak import Encoding, EncodingTechnique # type: ignore[ty:unresolved-import]
from pyrit.scenario.garak import Encoding, EncodingTechnique # type: ignore[ty:import-not-found]
from pyrit.scenario.scenarios.garak.encoding import EncodingDatasetConfiguration
from pyrit.score import DecodingScorer, TrueFalseScorer

Expand Down
2 changes: 1 addition & 1 deletion tests/unit/scenario/garak/test_exploitation.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from pyrit.models import AttackOutcome, Message, MessagePiece, Seed, SeedDataset
from pyrit.registry import AttackTechniqueRegistry
from pyrit.scenario import BaselineAttackPolicy
from pyrit.scenario.garak import Exploitation, ExploitationTechnique # type: ignore[ty:unresolved-import]
from pyrit.scenario.garak import Exploitation, ExploitationTechnique # type: ignore[ty:import-not-found]
from pyrit.scenario.scenarios.garak.exploitation import (
DATASET_PYTHON_PAYLOADS,
DATASET_SQL_PAYLOADS,
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/scenario/garak/test_figstep.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
)
from pyrit.registry import ScenarioRegistry
from pyrit.scenario import DatasetAttackConfiguration
from pyrit.scenario.garak import FigStep, FigStepTechnique # type: ignore[ty:unresolved-import]
from pyrit.scenario.garak import FigStep, FigStepTechnique # type: ignore[ty:import-not-found]
from pyrit.scenario.scenarios.garak.figstep import DEFAULT_MAX_DATASET_SIZE
from pyrit.score import TrueFalseScorer

Expand Down
2 changes: 1 addition & 1 deletion tests/unit/scenario/garak/test_leak_replay.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
DatasetSource,
)
from pyrit.scenario.core import DatasetConstraintError
from pyrit.scenario.garak import ( # type: ignore[ty:unresolved-import]
from pyrit.scenario.garak import ( # type: ignore[ty:import-not-found]
LeakReplay,
LeakReplayDatasetConfiguration,
LeakReplayTechnique,
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/scenario/garak/test_package_hallucination.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from pyrit.prompt_target import PromptTarget
from pyrit.scenario import BaselineAttackPolicy, DatasetConfiguration
from pyrit.scenario.core.scenario_context import ScenarioContext
from pyrit.scenario.garak import ( # type: ignore[ty:unresolved-import]
from pyrit.scenario.garak import ( # type: ignore[ty:import-not-found]
PackageHallucination,
PackageHallucinationTechnique,
WebInjectionTechnique,
Expand Down
Loading
Loading