From 68b9fc7f88065cfbfc56d4bcec2e064a63b261ef Mon Sep 17 00:00:00 2001 From: Bhoomi Date: Sat, 19 Sep 2026 16:13:43 +0530 Subject: [PATCH 1/2] fix: resolve crash when on_csv_write='update' encounters empty column (#1367) --- codecarbon/output_methods/file.py | 11 ++++++----- tests/output_methods/test_file.py | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/codecarbon/output_methods/file.py b/codecarbon/output_methods/file.py index 6bbf19a72..1ae45542f 100644 --- a/codecarbon/output_methods/file.py +++ b/codecarbon/output_methods/file.py @@ -118,12 +118,13 @@ def out(self, total: EmissionsData, _): ) df = pd.concat([df, new_df]) else: - update_values = {} for col, val in dict(total.values).items(): - update_values[col] = df[col].dtype.type(val) - df.loc[df.run_id == total.run_id, update_values.keys()] = ( - update_values.values() - ) + if col in df.columns: + try: + df.loc[df.run_id == total.run_id, col] = val + except (TypeError, ValueError): + df[col] = df[col].astype(object) + df.loc[df.run_id == total.run_id, col] = val df.to_csv(self.save_file_path, index=False) def task_out(self, data: List[TaskEmissionsData], experiment_name: str): diff --git a/tests/output_methods/test_file.py b/tests/output_methods/test_file.py index ec65cc3f0..659b5658a 100644 --- a/tests/output_methods/test_file.py +++ b/tests/output_methods/test_file.py @@ -169,6 +169,25 @@ def test_file_output_out_update_file_exists_one_matchingrows(self): df = pd.read_csv(os.path.join(self.temp_dir, "test.csv")) self.assertEqual(df["cpu_power"].iloc[0], 2) + def test_file_output_out_update_empty_column_second_write(self): + file_output = FileOutput("test.csv", self.temp_dir, on_csv_write="update") + # First write: gpu_model is None (written as empty string/NaN) + first_data = self.emissions_data + first_data.gpu_model = None + file_output.out(first_data, None) + + df = pd.read_csv(os.path.join(self.temp_dir, "test.csv")) + self.assertTrue(pd.isna(df["gpu_model"].iloc[0])) + + # Second write: update with a non-null string for gpu_model + second_data = self.emissions_data + second_data.gpu_model = "NVIDIA RTX 3080" + file_output.out(second_data, None) + + df_updated = pd.read_csv(os.path.join(self.temp_dir, "test.csv")) + self.assertEqual(df_updated["gpu_model"].iloc[0], "NVIDIA RTX 3080") + + # def test_file_output_out_consistent_column_ordering(self): # file_output = FileOutput("test.csv", self.temp_dir, on_csv_write="append") # file_output.out(self.emissions_data, None) From 55dd452c9f9b2efa7f2375e2bc7b051c3f3259f8 Mon Sep 17 00:00:00 2001 From: Bhoomi Date: Sat, 19 Sep 2026 16:16:02 +0530 Subject: [PATCH 2/2] style: format test_file.py with black --- tests/output_methods/test_file.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/output_methods/test_file.py b/tests/output_methods/test_file.py index 659b5658a..4aee08f6c 100644 --- a/tests/output_methods/test_file.py +++ b/tests/output_methods/test_file.py @@ -187,7 +187,6 @@ def test_file_output_out_update_empty_column_second_write(self): df_updated = pd.read_csv(os.path.join(self.temp_dir, "test.csv")) self.assertEqual(df_updated["gpu_model"].iloc[0], "NVIDIA RTX 3080") - # def test_file_output_out_consistent_column_ordering(self): # file_output = FileOutput("test.csv", self.temp_dir, on_csv_write="append") # file_output.out(self.emissions_data, None)