From 45ef5a575d411c073c551059d2701ab2b5e19598 Mon Sep 17 00:00:00 2001 From: biefan <70761325+biefan@users.noreply.github.com> Date: Mon, 16 Mar 2026 20:57:58 +0000 Subject: [PATCH 1/2] Handle empty CSV exports in remote dataset cache --- pyrit/common/csv_helper.py | 3 +++ tests/unit/datasets/test_remote_dataset_loader.py | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/pyrit/common/csv_helper.py b/pyrit/common/csv_helper.py index 48a9b9dd7e..2fb831149e 100644 --- a/pyrit/common/csv_helper.py +++ b/pyrit/common/csv_helper.py @@ -24,6 +24,9 @@ def write_csv(file: IO[Any], examples: list[dict[str, str]]) -> None: file: A file-like object opened for writing CSV data. examples (List[Dict[str, str]]): List of dictionaries to write as CSV rows. """ + if not examples: + return + writer = csv.DictWriter(file, fieldnames=examples[0].keys()) writer.writeheader() writer.writerows(examples) diff --git a/tests/unit/datasets/test_remote_dataset_loader.py b/tests/unit/datasets/test_remote_dataset_loader.py index d0052a4c78..a550fa2798 100644 --- a/tests/unit/datasets/test_remote_dataset_loader.py +++ b/tests/unit/datasets/test_remote_dataset_loader.py @@ -72,3 +72,12 @@ def test_write_cache_creates_directories(self, tmp_path): loader._write_cache(cache_file=cache_file, examples=data, file_type="json") assert cache_file.exists() + + def test_write_cache_csv_allows_empty_examples(self, tmp_path): + loader = ConcreteRemoteLoader() + cache_file = tmp_path / "empty.csv" + + loader._write_cache(cache_file=cache_file, examples=[], file_type="csv") + + assert cache_file.exists() + assert cache_file.read_text(encoding="utf-8") == "" From 645c0d7d28f7bb8e52fc311596178ceefbea2c4f Mon Sep 17 00:00:00 2001 From: Roman Lutz Date: Sat, 11 Apr 2026 17:16:34 -0700 Subject: [PATCH 2/2] Strengthen empty CSV tests: add round-trip assertion and direct write_csv tests - Add round-trip read_cache assertion to verify empty CSV can be read back as [] - Add dedicated test_csv_helper.py with direct unit tests for write_csv Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tests/unit/common/test_csv_helper.py | 20 +++++++++++++++++++ .../datasets/test_remote_dataset_loader.py | 1 + 2 files changed, 21 insertions(+) create mode 100644 tests/unit/common/test_csv_helper.py diff --git a/tests/unit/common/test_csv_helper.py b/tests/unit/common/test_csv_helper.py new file mode 100644 index 0000000000..0c1c5931a2 --- /dev/null +++ b/tests/unit/common/test_csv_helper.py @@ -0,0 +1,20 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT license. + +import io + +from pyrit.common.csv_helper import write_csv + + +def test_write_csv_empty_examples_writes_nothing(): + file = io.StringIO() + write_csv(file, []) + assert file.getvalue() == "" + + +def test_write_csv_writes_header_and_rows(): + file = io.StringIO() + write_csv(file, [{"name": "alice", "role": "admin"}]) + lines = file.getvalue().strip().splitlines() + assert lines[0] == "name,role" + assert lines[1] == "alice,admin" diff --git a/tests/unit/datasets/test_remote_dataset_loader.py b/tests/unit/datasets/test_remote_dataset_loader.py index a550fa2798..d9a2c8acfa 100644 --- a/tests/unit/datasets/test_remote_dataset_loader.py +++ b/tests/unit/datasets/test_remote_dataset_loader.py @@ -81,3 +81,4 @@ def test_write_cache_csv_allows_empty_examples(self, tmp_path): assert cache_file.exists() assert cache_file.read_text(encoding="utf-8") == "" + assert loader._read_cache(cache_file=cache_file, file_type="csv") == []