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
1 change: 0 additions & 1 deletion codecarbon/emissions_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -1309,7 +1309,6 @@ class OfflineEmissionsTracker(BaseEmissionsTracker):
_country_iso_code = None
_country_name, _region, country_2letter_iso_code = None, None, None

@suppress(Exception)
def __init__(
self,
*args,
Expand Down
7 changes: 7 additions & 0 deletions docs/reference/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ Parameters can be set via `EmissionsTracker()`, `OfflineEmissionsTracker()`, the
PUE is a multiplication factor provided by the user. Old datacenters have PUE
up to 2.2, new greener ones as low as 1.1.

!!! warning "Constructor errors (changed in v3.4.0)"
`OfflineEmissionsTracker(...)` used to swallow every exception raised while
building the tracker, returning a half-initialised object that silently
recorded nothing. It now propagates those errors, like `EmissionsTracker`
always did — for example an `output_dir` that does not exist raises instead of
logging. Code that relied on the constructor never raising needs a `try`/`except`.

!!! note "GPU selection"
If you use `CUDA_VISIBLE_DEVICES` or `ROCR_VISIBLE_DEVICES` to set GPUs, CodeCarbon will automatically
populate `gpu_ids`. Manual `gpu_ids` overrides this.
Expand Down
20 changes: 19 additions & 1 deletion tests/test_offline_emissions_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import pandas as pd

from codecarbon.emissions_tracker import OfflineEmissionsTracker
from codecarbon.emissions_tracker import EmissionsTracker, OfflineEmissionsTracker
from tests.testutils import get_custom_mock_open, get_test_data_source


Expand Down Expand Up @@ -68,6 +68,24 @@ def test_offline_tracker_task(self):
self.assertGreater(task_emission_data.emissions, 0.0)
self.assertEqual(task_emission_data.country_name, None)

def test_offline_tracker_raises_on_invalid_output_dir(self):
# Configuration errors must not be swallowed by the constructor,
# otherwise the user gets a half-built tracker that silently does
# nothing. Same semantics as the online EmissionsTracker.
with self.assertRaises(OSError):
OfflineEmissionsTracker(
country_iso_code="FRA",
output_dir=str(self.temp_path / "does_not_exist"),
)
with self.assertRaises(OSError):
EmissionsTracker(output_dir=str(self.temp_path / "does_not_exist"))

def test_offline_tracker_raises_on_invalid_region(self):
# A second, offline-specific constructor path: the region check runs
# before `super().__init__`, so it also has to reach the caller.
with self.assertRaises(AssertionError):
OfflineEmissionsTracker(country_iso_code="FRA", region=123)

def test_resolve_offline_country_name_logs_on_invalid_iso(self):
tracker = OfflineEmissionsTracker(
country_iso_code="INVALID",
Expand Down
Loading