From 1d7f99875540a0905010e9ee2bff3a8c095df9fe Mon Sep 17 00:00:00 2001 From: Brian Greunke Date: Tue, 19 Aug 2025 14:16:57 -0500 Subject: [PATCH 1/4] chore: updated dev deps --- poetry.lock | 41 +++++++++++++++++++++-------------------- pyproject.toml | 8 ++++---- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/poetry.lock b/poetry.lock index b2453709..015a0bd3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -4618,30 +4618,31 @@ files = [ [[package]] name = "ruff" -version = "0.11.13" +version = "0.12.9" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" groups = ["dev"] files = [ - {file = "ruff-0.11.13-py3-none-linux_armv6l.whl", hash = "sha256:4bdfbf1240533f40042ec00c9e09a3aade6f8c10b6414cf11b519488d2635d46"}, - {file = "ruff-0.11.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:aef9c9ed1b5ca28bb15c7eac83b8670cf3b20b478195bd49c8d756ba0a36cf48"}, - {file = "ruff-0.11.13-py3-none-macosx_11_0_arm64.whl", hash = "sha256:53b15a9dfdce029c842e9a5aebc3855e9ab7771395979ff85b7c1dedb53ddc2b"}, - {file = "ruff-0.11.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab153241400789138d13f362c43f7edecc0edfffce2afa6a68434000ecd8f69a"}, - {file = "ruff-0.11.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c51f93029d54a910d3d24f7dd0bb909e31b6cd989a5e4ac513f4eb41629f0dc"}, - {file = "ruff-0.11.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1808b3ed53e1a777c2ef733aca9051dc9bf7c99b26ece15cb59a0320fbdbd629"}, - {file = "ruff-0.11.13-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d28ce58b5ecf0f43c1b71edffabe6ed7f245d5336b17805803312ec9bc665933"}, - {file = "ruff-0.11.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55e4bc3a77842da33c16d55b32c6cac1ec5fb0fbec9c8c513bdce76c4f922165"}, - {file = "ruff-0.11.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:633bf2c6f35678c56ec73189ba6fa19ff1c5e4807a78bf60ef487b9dd272cc71"}, - {file = "ruff-0.11.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ffbc82d70424b275b089166310448051afdc6e914fdab90e08df66c43bb5ca9"}, - {file = "ruff-0.11.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4a9ddd3ec62a9a89578c85842b836e4ac832d4a2e0bfaad3b02243f930ceafcc"}, - {file = "ruff-0.11.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d237a496e0778d719efb05058c64d28b757c77824e04ffe8796c7436e26712b7"}, - {file = "ruff-0.11.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:26816a218ca6ef02142343fd24c70f7cd8c5aa6c203bca284407adf675984432"}, - {file = "ruff-0.11.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:51c3f95abd9331dc5b87c47ac7f376db5616041173826dfd556cfe3d4977f492"}, - {file = "ruff-0.11.13-py3-none-win32.whl", hash = "sha256:96c27935418e4e8e77a26bb05962817f28b8ef3843a6c6cc49d8783b5507f250"}, - {file = "ruff-0.11.13-py3-none-win_amd64.whl", hash = "sha256:29c3189895a8a6a657b7af4e97d330c8a3afd2c9c8f46c81e2fc5a31866517e3"}, - {file = "ruff-0.11.13-py3-none-win_arm64.whl", hash = "sha256:b4385285e9179d608ff1d2fb9922062663c658605819a6876d8beef0c30b7f3b"}, - {file = "ruff-0.11.13.tar.gz", hash = "sha256:26fa247dc68d1d4e72c179e08889a25ac0c7ba4d78aecfc835d49cbfd60bf514"}, + {file = "ruff-0.12.9-py3-none-linux_armv6l.whl", hash = "sha256:fcebc6c79fcae3f220d05585229463621f5dbf24d79fdc4936d9302e177cfa3e"}, + {file = "ruff-0.12.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:aed9d15f8c5755c0e74467731a007fcad41f19bcce41cd75f768bbd687f8535f"}, + {file = "ruff-0.12.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:5b15ea354c6ff0d7423814ba6d44be2807644d0c05e9ed60caca87e963e93f70"}, + {file = "ruff-0.12.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d596c2d0393c2502eaabfef723bd74ca35348a8dac4267d18a94910087807c53"}, + {file = "ruff-0.12.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1b15599931a1a7a03c388b9c5df1bfa62be7ede6eb7ef753b272381f39c3d0ff"}, + {file = "ruff-0.12.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3d02faa2977fb6f3f32ddb7828e212b7dd499c59eb896ae6c03ea5c303575756"}, + {file = "ruff-0.12.9-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:17d5b6b0b3a25259b69ebcba87908496e6830e03acfb929ef9fd4c58675fa2ea"}, + {file = "ruff-0.12.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:72db7521860e246adbb43f6ef464dd2a532ef2ef1f5dd0d470455b8d9f1773e0"}, + {file = "ruff-0.12.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a03242c1522b4e0885af63320ad754d53983c9599157ee33e77d748363c561ce"}, + {file = "ruff-0.12.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fc83e4e9751e6c13b5046d7162f205d0a7bac5840183c5beebf824b08a27340"}, + {file = "ruff-0.12.9-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:881465ed56ba4dd26a691954650de6ad389a2d1fdb130fe51ff18a25639fe4bb"}, + {file = "ruff-0.12.9-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:43f07a3ccfc62cdb4d3a3348bf0588358a66da756aa113e071b8ca8c3b9826af"}, + {file = "ruff-0.12.9-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:07adb221c54b6bba24387911e5734357f042e5669fa5718920ee728aba3cbadc"}, + {file = "ruff-0.12.9-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f5cd34fabfdea3933ab85d72359f118035882a01bff15bd1d2b15261d85d5f66"}, + {file = "ruff-0.12.9-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:f6be1d2ca0686c54564da8e7ee9e25f93bdd6868263805f8c0b8fc6a449db6d7"}, + {file = "ruff-0.12.9-py3-none-win32.whl", hash = "sha256:cc7a37bd2509974379d0115cc5608a1a4a6c4bff1b452ea69db83c8855d53f93"}, + {file = "ruff-0.12.9-py3-none-win_amd64.whl", hash = "sha256:6fb15b1977309741d7d098c8a3cb7a30bc112760a00fb6efb7abc85f00ba5908"}, + {file = "ruff-0.12.9-py3-none-win_arm64.whl", hash = "sha256:63c8c819739d86b96d500cce885956a1a48ab056bbcbc61b747ad494b2485089"}, + {file = "ruff-0.12.9.tar.gz", hash = "sha256:fbd94b2e3c623f659962934e52c2bea6fc6da11f667a427a368adaf3af2c866a"}, ] [[package]] @@ -6082,4 +6083,4 @@ training = ["transformers"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<3.14" -content-hash = "2ffd917048e564c5c72be8bb210031b9f7ad05793dea6e7a127b99eefd67add6" +content-hash = "608bdd485f2f8fb2d4390f37791f6fdd484c4ca4aa5ef661346c68dd3038f726" diff --git a/pyproject.toml b/pyproject.toml index fc8c6e26..caaba069 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,9 +40,9 @@ multimodal = ["pillow", "soundfile", "moviepy"] all = ["multimodal", "training"] [tool.poetry.group.dev.dependencies] -mypy = "^1.8.0" -ruff = "^0.11.6" -pre-commit = "^4.0.0" +mypy = "^1.17.0" +ruff = "^0.12.0" +pre-commit = "^4.3.0" pytest = "^8.3.3" pytest-asyncio = "^0.26.0" types-protobuf = "^5.29.1.20250208" @@ -53,7 +53,7 @@ datasets = "^3.5.0" pyarrow = "^19.0.1" markdown = "^3.8.2" markdownify = "^1.1.0" -mkdocstrings-python = "^1.16.12" +mkdocstrings-python = "^1.17.0" ipykernel = "^6.29.5" [build-system] From 4e8a2f7af91e178e3fb8517036d8e9af2cbb6fe8 Mon Sep 17 00:00:00 2001 From: Brian Greunke Date: Tue, 19 Aug 2025 19:41:28 -0500 Subject: [PATCH 2/4] fix: updated linting w/ new ruff reqs --- dreadnode/agent/agent.py | 2 +- dreadnode/agent/events.py | 8 ++++---- dreadnode/agent/hooks/summarize.py | 2 +- dreadnode/api/client.py | 8 ++++---- dreadnode/cli/agent/cli.py | 2 +- dreadnode/cli/main.py | 6 +++--- dreadnode/cli/profile/cli.py | 2 +- dreadnode/convert.py | 2 +- dreadnode/data_types/audio.py | 14 +++++++------- dreadnode/data_types/image.py | 26 +++++++++++++------------- dreadnode/data_types/table.py | 8 ++++---- dreadnode/data_types/video.py | 20 +++++++++++++------- dreadnode/main.py | 9 +++------ dreadnode/scorers/classification.py | 2 +- dreadnode/scorers/harm.py | 2 +- dreadnode/scorers/pii.py | 6 +++--- dreadnode/scorers/rigging.py | 2 +- dreadnode/scorers/similarity.py | 2 +- dreadnode/serialization.py | 20 ++++++++++---------- dreadnode/tracing/span.py | 8 ++++---- 20 files changed, 77 insertions(+), 74 deletions(-) diff --git a/dreadnode/agent/agent.py b/dreadnode/agent/agent.py index 1a5b91d1..1f9ba613 100644 --- a/dreadnode/agent/agent.py +++ b/dreadnode/agent/agent.py @@ -259,7 +259,7 @@ class TaskAgent(Agent): """ def model_post_init(self, _: t.Any) -> None: - from dreadnode.agent.tools import finish_task, update_todo + from dreadnode.agent.tools import finish_task, update_todo # noqa: PLC0415 if not any(tool for tool in self.tools if tool.name == "finish_task"): self.tools.append(finish_task) diff --git a/dreadnode/agent/events.py b/dreadnode/agent/events.py index 29f95be8..c2ed7816 100644 --- a/dreadnode/agent/events.py +++ b/dreadnode/agent/events.py @@ -108,10 +108,10 @@ class AgentEnd(Event): def rebuild_event_models() -> None: - from dreadnode.agent.agent import Agent # noqa: F401 - from dreadnode.agent.reactions import Reaction # noqa: F401 - from dreadnode.agent.result import AgentResult # noqa: F401 - from dreadnode.agent.thread import Thread # noqa: F401 + from dreadnode.agent.agent import Agent # noqa: F401,PLC0415 + from dreadnode.agent.reactions import Reaction # noqa: F401,PLC0415 + from dreadnode.agent.result import AgentResult # noqa: F401,PLC0415 + from dreadnode.agent.thread import Thread # noqa: F401,PLC0415 rebuild_dataclass(Event) # type: ignore[arg-type] rebuild_dataclass(AgentStart) # type: ignore[arg-type] diff --git a/dreadnode/agent/hooks/summarize.py b/dreadnode/agent/hooks/summarize.py index c11dffe2..8aac489c 100644 --- a/dreadnode/agent/hooks/summarize.py +++ b/dreadnode/agent/hooks/summarize.py @@ -23,7 +23,7 @@ def _is_context_length_error(error: Exception) -> bool: """Checks if an exception is likely due to exceeding the context window.""" with contextlib.suppress(ImportError): - from litellm.exceptions import ContextWindowExceededError + from litellm.exceptions import ContextWindowExceededError # noqa: PLC0415 if isinstance(error, ContextWindowExceededError): return True diff --git a/dreadnode/api/client.py b/dreadnode/api/client.py index 5d77eb98..12243907 100644 --- a/dreadnode/api/client.py +++ b/dreadnode/api/client.py @@ -393,7 +393,7 @@ def export_runs( Returns: A DataFrame containing the exported run data. """ - import pandas as pd + import pandas as pd # noqa: PLC0415 response = self.request( "GET", @@ -430,7 +430,7 @@ def export_metrics( Returns: A DataFrame containing the exported metric data. """ - import pandas as pd + import pandas as pd # noqa: PLC0415 response = self.request( "GET", @@ -470,7 +470,7 @@ def export_parameters( Returns: A DataFrame containing the exported parameter data. """ - import pandas as pd + import pandas as pd # noqa: PLC0415 response = self.request( "GET", @@ -511,7 +511,7 @@ def export_timeseries( Returns: A DataFrame containing the exported timeseries data. """ - import pandas as pd + import pandas as pd # noqa: PLC0415 response = self.request( "GET", diff --git a/dreadnode/cli/agent/cli.py b/dreadnode/cli/agent/cli.py index 6cbf717b..133acbb9 100644 --- a/dreadnode/cli/agent/cli.py +++ b/dreadnode/cli/agent/cli.py @@ -99,7 +99,7 @@ async def run( config_default = None with contextlib.suppress(Exception): config_default = config_model() - config_parameter = t.Optional[config_parameter] # type: ignore [assignment] # noqa: UP007 + config_parameter = config_parameter | None # type: ignore [assignment] async def agent_cli(*, config: t.Any = config_default) -> None: agent = hydrate_agent(agent_blueprint, config) diff --git a/dreadnode/cli/main.py b/dreadnode/cli/main.py index a6975263..ccb732e3 100644 --- a/dreadnode/cli/main.py +++ b/dreadnode/cli/main.py @@ -202,9 +202,9 @@ def clone( @cli.command(help="Show versions and exit.", group="Meta") def version() -> None: - import importlib.metadata - import platform - import sys + import importlib.metadata # noqa: PLC0415 + import platform # noqa: PLC0415 + import sys # noqa: PLC0415 version = importlib.metadata.version("dreadnode") python_version = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}" diff --git a/dreadnode/cli/profile/cli.py b/dreadnode/cli/profile/cli.py index 64e36dea..6b54f2d8 100644 --- a/dreadnode/cli/profile/cli.py +++ b/dreadnode/cli/profile/cli.py @@ -59,7 +59,7 @@ def switch( # If no profile provided, prompt user to choose if profile is None: - from rich.prompt import Prompt + from rich.prompt import Prompt # noqa: PLC0415 profiles = list(config.servers.keys()) rich.print("\nAvailable profiles:") diff --git a/dreadnode/convert.py b/dreadnode/convert.py index 2d7f9e48..4039268d 100644 --- a/dreadnode/convert.py +++ b/dreadnode/convert.py @@ -8,7 +8,7 @@ def run_span_to_graph(run: "RunSpan") -> "nx.DiGraph": try: - import networkx as nx + import networkx as nx # noqa: PLC0415 # pyright: ignore[reportMissingModuleSource] except ImportError as e: raise RuntimeError("The `networkx` package is required for graph conversion") from e diff --git a/dreadnode/data_types/audio.py b/dreadnode/data_types/audio.py index d177ea4a..ca23353c 100644 --- a/dreadnode/data_types/audio.py +++ b/dreadnode/data_types/audio.py @@ -10,14 +10,14 @@ def check_imports() -> None: try: - import soundfile as sf # type: ignore[import-untyped,unused-ignore] # noqa: F401 + import soundfile as sf # type: ignore[import-untyped,unused-ignore] # noqa: F401,PLC0415 except ImportError as e: raise ImportError( "Audio processing requires `soundfile`. Install with: pip install dreadnode[multimodal]" ) from e try: - import numpy as np # type: ignore[import-untyped,unused-ignore] # noqa: F401 + import numpy as np # type: ignore[import-untyped,unused-ignore] # noqa: F401,PLC0415 except ImportError as e: raise ImportError( "Audio processing requires `numpy`. Install with: pip install dreadnode[multimodal]" @@ -78,7 +78,7 @@ def _process_audio_data(self) -> tuple[bytes, str, int | None, float | None]: Returns: A tuple of (audio_bytes, format_name, sample_rate, duration) """ - import numpy as np + import numpy as np # noqa: PLC0415 if isinstance(self._data, str | Path) and Path(self._data).exists(): return self._process_file_path() @@ -94,7 +94,7 @@ def _process_file_path(self) -> tuple[bytes, str, int | None, float | None]: Returns: A tuple of (audio_bytes, format_name, sample_rate, duration) """ - import soundfile as sf # type: ignore[import-not-found,unused-ignore] + import soundfile as sf # type: ignore[import-not-found,unused-ignore] # noqa: PLC0415 path_str = str(self._data) audio_bytes = Path(path_str).read_bytes() @@ -113,8 +113,8 @@ def _process_numpy_array(self) -> tuple[bytes, str, int | None, float | None]: Returns: A tuple of (audio_bytes, format_name, sample_rate, duration) """ - import numpy as np # type: ignore[import-not-found,unused-ignore] - import soundfile as sf # type: ignore[import-not-found,unused-ignore] + import numpy as np # type: ignore[import-not-found,unused-ignore] # noqa: PLC0415 + import soundfile as sf # type: ignore[import-not-found,unused-ignore] # noqa: PLC0415 if self._sample_rate is None: raise ValueError('Argument "sample_rate" is required when using numpy arrays.') @@ -151,7 +151,7 @@ def _generate_metadata( Returns: A dictionary of metadata """ - import numpy as np # type: ignore[import-not-found,unused-ignore] + import numpy as np # type: ignore[import-not-found,unused-ignore] # noqa: PLC0415 metadata: dict[str, str | int | float | None] = { "extension": format_name.lower(), diff --git a/dreadnode/data_types/image.py b/dreadnode/data_types/image.py index a92f81b8..9383d85c 100644 --- a/dreadnode/data_types/image.py +++ b/dreadnode/data_types/image.py @@ -11,14 +11,14 @@ def check_imports() -> None: try: - import PIL # type: ignore[import,unused-ignore] # noqa: F401 + import PIL # type: ignore[import,unused-ignore] # noqa: F401,PLC0415 except ImportError as e: raise ImportError( "Image processing requires `pillow`. Install with: pip install dreadnode[multimodal]" ) from e try: - import numpy as np # type: ignore[import,unused-ignore] # noqa: F401 + import numpy as np # type: ignore[import,unused-ignore] # noqa: F401,PLC0415 except ImportError as e: raise ImportError( "Image processing requires `numpy`. Install with: pip install dreadnode[multimodal]" @@ -83,8 +83,8 @@ def _process_image_data(self) -> tuple[bytes, str, str | None, int | None, int | Returns: A tuple of (image_bytes, image_format, mode, width, height) """ - import numpy as np # type: ignore[import,unused-ignore] - import PIL.Image # type: ignore[import,unused-ignore] + import numpy as np # type: ignore[import,unused-ignore] # noqa: PLC0415 + import PIL.Image # type: ignore[import,unused-ignore] # noqa: PLC0415 if isinstance(self._data, (str, Path)) and Path(self._data).exists(): return self._process_file_path() @@ -104,7 +104,7 @@ def _process_file_path(self) -> tuple[bytes, str, str | None, int | None, int | Returns: A tuple of (image_bytes, image_format, mode, width, height) """ - import PIL.Image # type: ignore[import,unused-ignore] + import PIL.Image # type: ignore[import,unused-ignore] # noqa: PLC0415 path_str = str(self._data) image_bytes = Path(path_str).read_bytes() @@ -122,7 +122,7 @@ def _process_pil_image(self) -> tuple[bytes, str, str | None, int | None, int | Returns: A tuple of (image_bytes, image_format, mode, width, height) """ - import PIL.Image # type: ignore[import,unused-ignore] + import PIL.Image # type: ignore[import,unused-ignore] # noqa: PLC0415 if not isinstance(self._data, PIL.Image.Image): raise TypeError(f"Expected PIL.Image, got {type(self._data)}") @@ -160,8 +160,8 @@ def _process_numpy_array(self) -> tuple[bytes, str, str | None, int | None, int Returns: A tuple of (image_bytes, image_format, mode, width, height) """ - import numpy as np # type: ignore[import,unused-ignore] - import PIL.Image # type: ignore[import,unused-ignore] + import numpy as np # type: ignore[import,unused-ignore] # noqa: PLC0415 + import PIL.Image # type: ignore[import,unused-ignore] # noqa: PLC0415 buffer = io.BytesIO() image_format = self._format or "png" @@ -191,7 +191,7 @@ def _process_raw_bytes(self) -> tuple[bytes, str, str | None, int | None, int | Returns: A tuple of (image_bytes, image_format, mode, width, height) """ - import PIL.Image # type: ignore[import,unused-ignore] + import PIL.Image # type: ignore[import,unused-ignore] # noqa: PLC0415 if not isinstance(self._data, bytes): raise TypeError(f"Expected bytes, got {type(self._data)}") @@ -216,7 +216,7 @@ def _process_base64_string(self) -> tuple[bytes, str, str | None, int | None, in Returns: A tuple of (image_bytes, image_format, mode, width, height) """ - import PIL.Image # type: ignore[import,unused-ignore] + import PIL.Image # type: ignore[import,unused-ignore] # noqa: PLC0415 if not isinstance(self._data, str): raise TypeError(f"Expected str, got {type(self._data)}") @@ -253,8 +253,8 @@ def _generate_metadata( self, image_format: str, mode: str | None, width: int | None, height: int | None ) -> dict[str, str | int | None]: """Generate metadata for the image.""" - import numpy as np # type: ignore[import,unused-ignore] - import PIL.Image # type: ignore[import,unused-ignore] + import numpy as np # type: ignore[import,unused-ignore] # noqa: PLC0415 + import PIL.Image # type: ignore[import,unused-ignore] # noqa: PLC0415 metadata: dict[str, str | int | None] = { "extension": image_format.lower(), @@ -313,7 +313,7 @@ def _ensure_valid_image_array( self, array: "np.ndarray[t.Any, np.dtype[t.Any]]" ) -> "np.ndarray[t.Any, np.dtype[t.Any]]": """Convert numpy array to a format suitable for PIL.""" - import numpy as np # type: ignore[import,unused-ignore] + import numpy as np # type: ignore[import,unused-ignore] # noqa: PLC0415 grayscale_dim = 2 rgb_dim = 3 diff --git a/dreadnode/data_types/table.py b/dreadnode/data_types/table.py index 2b4c7dcb..b1d9b216 100644 --- a/dreadnode/data_types/table.py +++ b/dreadnode/data_types/table.py @@ -78,8 +78,8 @@ def _to_dataframe(self) -> "pd.DataFrame": Returns: A pandas DataFrame representation of the input data """ - import numpy as np - import pandas as pd + import numpy as np # noqa: PLC0415 + import pandas as pd # noqa: PLC0415 if isinstance(self._data, pd.DataFrame): return self._data @@ -134,8 +134,8 @@ def _generate_metadata(self, data_frame: "pd.DataFrame") -> dict[str, t.Any]: Returns: A dictionary of metadata """ - import numpy as np - import pandas as pd + import numpy as np # noqa: PLC0415 + import pandas as pd # noqa: PLC0415 metadata = { "extension": self._format, diff --git a/dreadnode/data_types/video.py b/dreadnode/data_types/video.py index aab4dc3b..0106d5b6 100644 --- a/dreadnode/data_types/video.py +++ b/dreadnode/data_types/video.py @@ -62,10 +62,12 @@ def to_serializable(self) -> tuple[bytes, dict[str, t.Any]]: Returns: A tuple of (video_bytes, metadata_dict) """ - import numpy as np # type: ignore[import,unused-ignore] + import numpy as np # type: ignore[import,unused-ignore] # noqa: PLC0415 try: - from moviepy.video.VideoClip import VideoClip # type: ignore[import,unused-ignore] + from moviepy.video.VideoClip import ( # noqa: PLC0415 + VideoClip, # type: ignore[import,unused-ignore] + ) except ImportError: VideoClip = None # noqa: N806 @@ -120,7 +122,7 @@ def _process_numpy_array(self) -> tuple[bytes, dict[str, t.Any]]: Returns: A tuple of (video_bytes, metadata_dict) """ - import numpy as np # type: ignore[import,unused-ignore] + import numpy as np # type: ignore[import,unused-ignore] # noqa: PLC0415 if not self._fps: raise ValueError("fps is required for numpy array video frames") @@ -135,7 +137,7 @@ def _process_numpy_array(self) -> tuple[bytes, dict[str, t.Any]]: def _extract_frames_from_data(self) -> "list[NDArray[t.Any]]": """Extract frames from numpy array or list data.""" - import numpy as np # type: ignore[import,unused-ignore] + import numpy as np # type: ignore[import,unused-ignore] # noqa: PLC0415 frames = [] rgb_dim = 3 @@ -157,10 +159,12 @@ def _create_video_from_frames_data( self, frames: "list[NDArray[t.Any]]" ) -> tuple[bytes, dict[str, t.Any]]: """Create video file from frames.""" - import numpy as np # type: ignore[import,unused-ignore] + import numpy as np # type: ignore[import,unused-ignore] # noqa: PLC0415 try: - from moviepy.video.io import ImageSequenceClip # type: ignore[import,unused-ignore] + from moviepy.video.io import ( # noqa: PLC0415 + ImageSequenceClip, # type: ignore[import,unused-ignore] + ) except ImportError as e: raise ImportError( "Video processing from numpy arrays requires moviepy. " @@ -207,7 +211,9 @@ def _process_moviepy_clip(self) -> tuple[bytes, dict[str, t.Any]]: Returns: A tuple of (video_bytes, metadata_dict) """ - from moviepy.video.VideoClip import VideoClip # type: ignore[import,unused-ignore] + from moviepy.video.VideoClip import ( # noqa: PLC0415 + VideoClip, # type: ignore[import,unused-ignore] + ) if not isinstance(self._data, VideoClip): raise TypeError("data must be a MoviePy VideoClip object") diff --git a/dreadnode/main.py b/dreadnode/main.py index 228ba9d1..759b1b16 100644 --- a/dreadnode/main.py +++ b/dreadnode/main.py @@ -224,10 +224,7 @@ def configure( with contextlib.suppress(Exception): user_config = UserConfig.read() profile_name = profile or os.environ.get(ENV_PROFILE) - if profile_name: - active_profile = profile_name - else: - active_profile = user_config.active_profile_name + active_profile = profile_name or user_config.active_profile_name if active_profile: config_source = f"profile: {active_profile}" @@ -945,7 +942,7 @@ def log_params(self, **params: JsonValue) -> None: def log_metric( self, name: str, - value: float | bool, + value: float | bool, # noqa: FBT001 *, step: int = 0, origin: t.Any | None = None, @@ -1036,7 +1033,7 @@ def log_metric( def log_metric( self, name: str, - value: float | bool | Metric, + value: float | bool | Metric, # noqa: FBT001 *, step: int = 0, origin: t.Any | None = None, diff --git a/dreadnode/scorers/classification.py b/dreadnode/scorers/classification.py index 418081b6..c90a6a4b 100644 --- a/dreadnode/scorers/classification.py +++ b/dreadnode/scorers/classification.py @@ -33,7 +33,7 @@ def zero_shot_classification( ) try: - from transformers import ( # type: ignore [attr-defined,import-not-found,unused-ignore] + from transformers import ( # type: ignore [attr-defined,import-not-found,unused-ignore] # noqa: PLC0415 pipeline, ) except ImportError: diff --git a/dreadnode/scorers/harm.py b/dreadnode/scorers/harm.py index 371e558c..744d6360 100644 --- a/dreadnode/scorers/harm.py +++ b/dreadnode/scorers/harm.py @@ -31,7 +31,7 @@ def detect_harm_with_openai( model: The moderation model to use. name: Name of the scorer. """ - import openai + import openai # noqa: PLC0415 async def evaluate(data: t.Any) -> Metric: text = str(data) diff --git a/dreadnode/scorers/pii.py b/dreadnode/scorers/pii.py index fb3d1acd..7ce781aa 100644 --- a/dreadnode/scorers/pii.py +++ b/dreadnode/scorers/pii.py @@ -64,8 +64,8 @@ def _get_presidio_analyzer() -> "AnalyzerEngine": """Lazily initializes and returns a singleton Presidio AnalyzerEngine instance.""" global g_analyzer_engine # noqa: PLW0603 - from presidio_analyzer import AnalyzerEngine - from presidio_analyzer.nlp_engine import NlpEngineProvider + from presidio_analyzer import AnalyzerEngine # noqa: PLC0415 + from presidio_analyzer.nlp_engine import NlpEngineProvider # noqa: PLC0415 if g_analyzer_engine is None: provider = NlpEngineProvider( @@ -108,7 +108,7 @@ def detect_pii_with_presidio( ) try: - import presidio_analyzer # type: ignore[import-not-found,unused-ignore] # noqa: F401 + import presidio_analyzer # type: ignore[import-not-found,unused-ignore] # noqa: F401, PLC0415 except ImportError: warn_at_user_stacklevel(presidio_import_error_msg, UserWarning) diff --git a/dreadnode/scorers/rigging.py b/dreadnode/scorers/rigging.py index dc9a6851..c3cd0b6d 100644 --- a/dreadnode/scorers/rigging.py +++ b/dreadnode/scorers/rigging.py @@ -43,7 +43,7 @@ def wrap_chat( """ async def evaluate(chat: "Chat") -> Metric: - from rigging.chat import Chat + from rigging.chat import Chat # noqa: PLC0415 # Fall through to the inner scorer if chat is not a Chat instance if not isinstance(chat, Chat): diff --git a/dreadnode/scorers/similarity.py b/dreadnode/scorers/similarity.py index 0eb53864..116c5067 100644 --- a/dreadnode/scorers/similarity.py +++ b/dreadnode/scorers/similarity.py @@ -217,7 +217,7 @@ def similarity_with_litellm( or self-hosted models. name: Name of the scorer. """ - import litellm + import litellm # noqa: PLC0415 async def evaluate(data: t.Any) -> Metric: nonlocal reference, model diff --git a/dreadnode/serialization.py b/dreadnode/serialization.py index c71b2d01..a91b327e 100644 --- a/dreadnode/serialization.py +++ b/dreadnode/serialization.py @@ -317,14 +317,14 @@ def _handle_dataclass(obj: t.Any, seen: set[int]) -> tuple[JsonValue, JsonDict]: def _handle_attrs(obj: t.Any, seen: set[int]) -> tuple[JsonValue, JsonDict]: - import attrs + import attrs # noqa: PLC0415 keys = [f.name for f in attrs.fields(obj.__class__)] return _handle_custom_object(obj, keys, seen, "attrs") def _handle_pydantic_model(obj: t.Any, _seen: set[int]) -> tuple[JsonValue, JsonDict]: - import pydantic + import pydantic # noqa: PLC0415 if not isinstance(obj, pydantic.BaseModel): return safe_repr(obj), UNKNOWN_OBJECT_SCHEMA @@ -345,7 +345,7 @@ def _handle_numpy_array( obj: t.Any, seen: set[int], ) -> tuple[JsonValue, JsonDict]: - import numpy # noqa: ICN001 + import numpy # noqa: ICN001, PLC0415 if not isinstance(obj, numpy.ndarray): return safe_repr(obj), UNKNOWN_OBJECT_SCHEMA @@ -363,7 +363,7 @@ def _handle_pandas_dataframe( obj: t.Any, seen: set[int], ) -> tuple[JsonValue, JsonDict]: - import pandas as pd + import pandas as pd # noqa: PLC0415 if not isinstance(obj, pd.DataFrame): return safe_repr(obj), UNKNOWN_OBJECT_SCHEMA @@ -378,7 +378,7 @@ def _handle_pandas_series( obj: t.Any, seen: set[int], ) -> tuple[JsonValue, JsonDict]: - import pandas as pd + import pandas as pd # noqa: PLC0415 if not isinstance(obj, pd.Series): return safe_repr(obj), UNKNOWN_OBJECT_SCHEMA @@ -390,7 +390,7 @@ def _handle_pandas_series( def _handle_dataset(obj: t.Any, _seen: set[int]) -> tuple[JsonValue, JsonDict]: - import datasets # type: ignore[import-untyped] + import datasets # type: ignore[import-untyped] # noqa: PLC0415 if not isinstance(obj, datasets.Dataset): return safe_repr(obj), UNKNOWN_OBJECT_SCHEMA @@ -453,7 +453,7 @@ def _get_handlers() -> dict[type, HandlerFunc]: # Pydantic with contextlib.suppress(Exception): - import pydantic + import pydantic # noqa: PLC0415 handlers[pydantic.NameEmail] = lambda o, s: _handle_str_based( o, @@ -478,7 +478,7 @@ def _get_handlers() -> dict[type, HandlerFunc]: handlers[pydantic.BaseModel] = _handle_pydantic_model with contextlib.suppress(Exception): - import numpy as np + import numpy as np # noqa: PLC0415 handlers[np.ndarray] = _handle_numpy_array handlers[np.floating] = lambda o, s: _serialize(float(o), s) @@ -496,13 +496,13 @@ def _get_handlers() -> dict[type, HandlerFunc]: ) with contextlib.suppress(Exception): - import pandas as pd + import pandas as pd # noqa: PLC0415 handlers[pd.DataFrame] = _handle_pandas_dataframe handlers[pd.Series] = _handle_pandas_series with contextlib.suppress(Exception): - import datasets + import datasets # noqa: PLC0415 handlers[datasets.Dataset] = _handle_dataset diff --git a/dreadnode/tracing/span.py b/dreadnode/tracing/span.py index 7d605e7e..7dc086b2 100644 --- a/dreadnode/tracing/span.py +++ b/dreadnode/tracing/span.py @@ -735,7 +735,7 @@ def metrics(self) -> MetricsDict: def log_metric( self, name: str, - value: float | bool, + value: float | bool, # noqa: FBT001 *, step: int = 0, origin: t.Any | None = None, @@ -759,7 +759,7 @@ def log_metric( def log_metric( self, name: str, - value: float | bool | Metric, + value: float | bool | Metric, # noqa: FBT001 *, step: int = 0, origin: t.Any | None = None, @@ -1011,7 +1011,7 @@ def metrics(self) -> dict[str, list[Metric]]: def log_metric( self, name: str, - value: float | bool, + value: float | bool, # noqa: FBT001 *, step: int = 0, origin: t.Any | None = None, @@ -1033,7 +1033,7 @@ def log_metric( def log_metric( self, name: str, - value: float | bool | Metric, + value: float | bool | Metric, # noqa: FBT001 *, step: int = 0, origin: t.Any | None = None, From 39c6b0c62e79e069e840778e3713e1d6c0c9b82a Mon Sep 17 00:00:00 2001 From: Brian Greunke Date: Tue, 19 Aug 2025 19:48:08 -0500 Subject: [PATCH 3/4] fix: removed extra noqa --- .hooks/generate_docs.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/.hooks/generate_docs.py b/.hooks/generate_docs.py index 17535206..1ab5b499 100644 --- a/.hooks/generate_docs.py +++ b/.hooks/generate_docs.py @@ -11,8 +11,6 @@ PythonHandler, ) -# ruff: noqa: T201 - class CustomMarkdownConverter(MarkdownConverter): # type: ignore[misc] # Strip extra whitespace from code blocks From 525fed882dd13754ab4a430d408a2692a3b33b8c Mon Sep 17 00:00:00 2001 From: Brian Greunke Date: Wed, 20 Aug 2025 08:22:25 -0500 Subject: [PATCH 4/4] fix: untyped-import typing suppress --- dreadnode/data_types/video.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dreadnode/data_types/video.py b/dreadnode/data_types/video.py index 0106d5b6..7b46ee59 100644 --- a/dreadnode/data_types/video.py +++ b/dreadnode/data_types/video.py @@ -65,8 +65,8 @@ def to_serializable(self) -> tuple[bytes, dict[str, t.Any]]: import numpy as np # type: ignore[import,unused-ignore] # noqa: PLC0415 try: - from moviepy.video.VideoClip import ( # noqa: PLC0415 - VideoClip, # type: ignore[import,unused-ignore] + from moviepy.video.VideoClip import ( # type: ignore[import,unused-ignore,import-untyped] # noqa: PLC0415 + VideoClip, ) except ImportError: VideoClip = None # noqa: N806 @@ -162,8 +162,8 @@ def _create_video_from_frames_data( import numpy as np # type: ignore[import,unused-ignore] # noqa: PLC0415 try: - from moviepy.video.io import ( # noqa: PLC0415 - ImageSequenceClip, # type: ignore[import,unused-ignore] + from moviepy.video.io import ( # type: ignore[import,unused-ignore,import-untyped] # noqa: PLC0415 + ImageSequenceClip, ) except ImportError as e: raise ImportError(