Skip to content

fix: show the save_to_* deprecation to users, attributed to their code - #1346

Merged
benoit-cty merged 7 commits into
masterfrom
fix/deprecation-warning-stacklevel
Nov 1, 2026
Merged

benoit-cty merged 7 commits into
masterfrom
fix/deprecation-warning-stacklevel

Conversation

@davidberenstein1957

@davidberenstein1957 davidberenstein1957 commented Aug 12, 2026 •

Copy link
Copy Markdown
Collaborator

Description

The save_to_* deprecation is now a FutureWarning (shown by default per PEP 565), and its stacklevel is computed by a new _caller_stacklevel() helper, which walks the stack to the first frame outside the codecarbon package (skipping the contextlib frame added by @suppress). The warning now points at the user's EmissionsTracker(...) / OfflineEmissionsTracker(...) line instead of emissions_tracker.py. In codecarbon/cli/main.py, monitor now passes output_methods= built from configuration, with OutputMethod.API added for --api and removed for --no-api, preserving save_to_api=api's add/remove behaviour and making --api work even when output_methods is set in the config; detect passes output_methods=[]. codecarbon/cli/monitor.py drops the save_to_logger=False argument, which was previously hard-coded regardless of configuration.

Related Issue

Fixes #1323

Motivation and Context

The deprecation warning was raised inside _resolve_output_methods, so it was attributed to emissions_tracker.py, and Python's default filter only shows DeprecationWarning from __main__, which dropped the warning for every user. FutureWarning is the correct category for deprecations aimed at end users that must always be shown, and it also makes stacklevel accuracy matter for pointing at the right line.

Behaviour change worth flagging: dropping save_to_logger=False from codecarbon/cli/monitor.py is not a no-op. Previously monitor always forced the logger off regardless of configuration; now, since the argument is no longer passed, the tracker falls back to reading save_to_logger from the user's config file. So running offline codecarbon monitor -- cmd with save_to_logger=true in .codecarbon.config now enables the logger output, where before it was always disabled. This matches how the tracker reads every other save_to_* key from config when the CLI doesn't override it, so the change is intended and makes monitor consistent with the rest of the config-driven output methods, but it is a behaviour change for anyone who had save_to_logger=true in their config and relied on monitor silently ignoring it.

How Has This Been Tested?

  • test_deprecation_warning_survives_the_default_filter now also asserts w.filename == __file__ for both tracker classes.
  • CLI tests assert on output_methods instead of save_to_api; a new parametrised test_monitor_api_flag_adds_to_configured_output_methods pins the add/remove behaviour against configured outputs, including a case with save_to_logger: "true" in config confirming the logger is now picked up.

Screenshots (if appropriate):

N/A

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

AI Usage Disclosure

  • 🟥 AI-vibecoded: You cannot explain the logic. Car analogy : the car drive by itself, you are outside it and just tell it where to go.
  • 🟠 AI-generated: Car analogy : the car drive by itself, you are inside and give instructions.
  • ⭐ AI-assisted. Car analogy : you drive the car, AI help you find your way.
  • ♻️ No AI used. Car analogy : you drive the car.

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the docs/how-to/contributing.md document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

@codecov

codecov Bot commented Aug 12, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.82%. Comparing base (2a92628) to head (793add0).
⚠️ Report is 8 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1346      +/-   ##
==========================================
+ Coverage   93.80%   93.82%   +0.02%     
==========================================
  Files          51       51              
  Lines        5710     5734      +24     
==========================================
+ Hits         5356     5380      +24     
  Misses        354      354              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@davidberenstein1957
davidberenstein1957 marked this pull request as ready for review August 13, 2026 05:05
@davidberenstein1957
davidberenstein1957 requested a review from a team as a code owner August 13, 2026 05:05
@davidberenstein1957
davidberenstein1957 force-pushed the fix/deprecation-warning-stacklevel branch 2 times, most recently from b5cf269 to 55855fb Compare August 19, 2026 14:21
@github-actions github-actions Bot added size/S and removed size/M labels Aug 19, 2026
@benoit-cty

Copy link
Copy Markdown
Contributor

🤖 This review comment was written and posted by Claude Opus 5.5 (AI assistant), at the request of @benoit-cty. Findings were checked by reading the code and running tests locally (merged with current master where relevant), but please double-check before acting on them.

Verdict: 🔧 Request changes

The title and description mention a dynamic stacklevel and moving the CLI to output_methods=. The single commit in this PR only changes DeprecationWarning to FutureWarning and keeps stacklevel=2.

Must fix:

  1. The CLI now shows users a warning they can't act on. FutureWarning is shown by default, but the CLI itself still passes the deprecated arguments:

    • codecarbon/cli/main.py:425 passes save_to_api= on every online monitor run
    • codecarbon/cli/main.py:476 (detect) passes save_to_file=False
    • codecarbon/cli/monitor.py:75 passes save_to_logger=False for monitor -- cmd

    I verified that codecarbon detect now prints emissions_tracker.py:572: FutureWarning: The save_to_* parameters are deprecated... on every run. Please migrate these call sites to output_methods= in this same PR.

  2. The warning still points at the library, not the caller, so save_to_* DeprecationWarning has the wrong stacklevel and never reaches users #1323 isn't fixed (emissions_tracker.py ~L223-230).

    • Both EmissionsTracker(...) and OfflineEmissionsTracker(...) report emissions_tracker.py:572.
    • Options:
      • compute the stacklevel by walking frames until you leave the codecarbon package
      • on Python 3.12+, use warnings.warn(..., skip_file_prefixes=(os.path.dirname(codecarbon.__file__),)), with the frame-walk as a fallback for older versions
    • The test only checks that a FutureWarning is raised. Please also assert w[0].filename == __file__, so the attribution is locked in.
  3. Update the title and description to match what the code does.

Switching to FutureWarning for a user-facing deprecation is reasonable (PEP 565). It just needs points 1 and 2 to go with it.

@davidberenstein1957 davidberenstein1957 changed the title fix: attribute save_to_* deprecation to caller fix: show the save_to_* deprecation to users, attributed to their code Sep 23, 2026
@github-actions github-actions Bot added size/M and removed size/S labels Sep 23, 2026
@davidberenstein1957

Copy link
Copy Markdown
Collaborator Author

Made the changes in 99b6c55: CLI moved to output_methods=, warning now points at the caller (filename asserted in the test), title and description updated.

@davidberenstein1957

Copy link
Copy Markdown
Collaborator Author

Merged master to resolve conflicts in db90765.

@benoit-cty
benoit-cty force-pushed the fix/deprecation-warning-stacklevel branch from 6f713eb to 8a7e29c Compare October 31, 2026 14:05

Copy link
Copy Markdown
Contributor

Rebased on master and fixed a few things on top, at the maintainer's request (head is now 8a7e29c).

  • Rebase: Dropped the 2 merge commits, leaving 0bc8f12 (FutureWarning) and b962b02 (caller attribution and CLI move to output_methods). Conflicts and how they were resolved:
    • cli/monitor.py: master now passes log_level through tracker_args, so both the old log_level= line and save_to_logger=False are gone.
    • emissions_tracker.py imports: kept both sys and threading.
    • tests/cli/test_cli_main.py: kept both new tests.
  • b9293f7 refactor(cli): _configured_output_methods now takes the config monitor already read with _external_config(). It no longer reads the config a second time and skipping that function's error handling.
  • 4fb48e9 docs: The save_to_* warning is now visible, so the snippets in docs/reference/output.md, docs/how-to/cloud-api.md and docs/how-to/logging.md use output_methods=[OutputMethod.CSV, ...]. CSV stays in each list because save_to_file defaulted to True. The deprecation note now mentions the FutureWarning. Note: the "requires a change to the documentation" checkbox in the PR body is out of date now.
  • 8a7e29c style: black.
  • Review: benoit-cty's three requests were all addressed in the code: migrate the CLI call sites, point the warning at the caller and assert the filename in the test, and update the title/description.
  • Tests and coverage:
    • tests/cli, test_emissions_tracker.py, test_docs_examples.py and pre-commit pass.
    • In the full package suite, only the test_logging_output and RAPL-permission tests fail, and they fail on master too in this environment.
    • Coverage of changed lines in codecarbon/ is 37/38. The only missed line is the unreachable return 2 fallback in _caller_stacklevel.
  • Left for author/maintainer:
    • examples/*.py and the notebooks still pass save_to_*, which will now show the warning. A follow-up PR could fix that.
    • The override example in docs/how-to/configuration.md still uses save_to_api. It was left as is because it shows how config layers combine.
    • Behaviour change, already flagged in the body: monitor now follows save_to_logger from the config.

Generated by Claude Code

davidberenstein1957 and others added 6 commits November 1, 2026 15:56
The warning is raised inside _resolve_output_methods, so it is attributed
to emissions_tracker.py and Python's default filter -- which only shows
DeprecationWarning from __main__ -- drops it for every user.

FutureWarning exists for exactly this: deprecations aimed at end users
that must always be shown. It makes stacklevel irrelevant to visibility.
(skip_file_prefixes= would be the stdlib answer, but it is 3.12+ and
requires-python is >=3.10.)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…tput_methods

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
_configured_output_methods re-read the hierarchical config, bypassing the
error handling of _external_config(). Pass the dict monitor already has.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JfRKgUd281URY6fMyNAQmh
The save_to_* deprecation is now a FutureWarning shown by default, so
copying these snippets would print it. Keep CSV in each list to match the
previous behaviour (save_to_file defaults to True), and mention the warning
in the deprecation note.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JfRKgUd281URY6fMyNAQmh
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JfRKgUd281URY6fMyNAQmh
@benoit-cty
benoit-cty force-pushed the fix/deprecation-warning-stacklevel branch from 8a7e29c to 6dbb9a4 Compare November 1, 2026 15:03
@github-actions github-actions Bot added size/L and removed size/M labels Nov 1, 2026

@benoit-cty benoit-cty left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, it makes our code cleaner.

Codecov flagged the 'return 2' fallback, reached only when every frame is inside codecarbon, as the one uncovered line of the patch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@benoit-cty
benoit-cty merged commit 0845984 into master Nov 1, 2026
13 checks passed
@benoit-cty
benoit-cty deleted the fix/deprecation-warning-stacklevel branch November 1, 2026 15:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

save_to_* DeprecationWarning has the wrong stacklevel and never reaches users

3 participants