Conversation
Adds automated testing of Python code examples in the documentation
to prevent examples from drifting out of sync with the library.
Changes:
- Add `mktestdocs` and `pytest` to the `doc` dependency group in
`pyproject.toml` so they are available alongside the other doc-build
tools without pulling in the full `dev` group.
- Add `scripts/check-docs-drift.py`: a pytest-based script that uses
`mktestdocs.grab_code_blocks()` to collect every ```python fenced
block under `docs/`, skips any block whose first line is `# skip`,
and executes the rest via `exec_python()`. A new taskipy task
`docs-check-drift` runs it with `pytest scripts/check-docs-drift.py -v`.
- Fix all ```python code blocks across `docs/` so they are correctly
picked up by mktestdocs:
- Remove the stray space in ``` python fences (changed to ```python)
so that mktestdocs can identify them (it matches on the exact string
"python" immediately after the backticks).
- Add `save_to_file=False, log_level="error"` to `EmissionsTracker`
and `OfflineEmissionsTracker` instantiations to avoid creating CSV
files or noisy output during CI runs.
- Add `# skip` as the first line of blocks that cannot run in CI
because they depend on external services or optional heavy
dependencies (TensorFlow, Prometheus, Logfire, Google Cloud,
Comet ML, live CodeCarbon API).
- Correct a `pip install` command that was incorrectly fenced as
```python in `comet.md`; changed to ```console.
- Update `.github/workflows/build-docs.yml` to run `docs-check-drift`
as a step before the docs build, triggered on changes to `docs/**`,
`mkdocs.yml`, or `scripts/check-docs-drift.py`.
- Document the drift check and the `# skip` convention in
`CONTRIBUTING.md` under the "Build Documentation" section.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1096 +/- ##
=======================================
Coverage 78.22% 78.22%
=======================================
Files 38 38
Lines 3632 3632
=======================================
Hits 2841 2841
Misses 791 791 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Hi @cianc, Thanks a lot for this PR. Do you have time to also move some of the documentation examples to docstring examples in the Python code? We would then be able to load them from here, while keeping a single source of truth directly from the Python code, while also exposing examples in the docstring :) Also, I feel that we might not need a separate script directory, but rather just keep Python file as part of the tests directory. Anywhow. Thahnks a lot for tackling this :) |
| ```python | ||
| # skip | ||
| from codecarbon import track_emissions | ||
|
|
||
| @track_emissions(save_to_api=True) | ||
| def train_model(): | ||
| # GPU intensive training code goes here | ||
| # GPU intensive training code goes here | ||
| pass | ||
|
|
||
| if __name__ =="__main__": | ||
| if __name__ == "__main__": | ||
| train_model() | ||
| ``` |
There was a problem hiding this comment.
So, as proposed, we coul add this code example to the track_emissions examples docstring and directly import it from there.
There was a problem hiding this comment.
This would mean that we don't directly test our docs but rather do that for the exmaples in our docstrings.
davidberenstein1957
left a comment
There was a problem hiding this comment.
I left some small remarks and a comment in the main thread. Happy to hear your thoughts and thanks a lot for the help :)
| ```python | ||
| # skip | ||
| from codecarbon import track_emissions | ||
|
|
||
| @track_emissions(save_to_api=True) | ||
| def train_model(): | ||
| # GPU intensive training code goes here | ||
| # GPU intensive training code goes here | ||
| pass | ||
|
|
||
| if __name__ =="__main__": | ||
| if __name__ == "__main__": | ||
| train_model() | ||
| ``` |
There was a problem hiding this comment.
This would mean that we don't directly test our docs but rather do that for the exmaples in our docstrings.
| experiment_id="your experiment id", | ||
| save_to_api=True, | ||
| save_to_file=False, | ||
| log_level="error", |
There was a problem hiding this comment.
Was this updated automatically? Or did you manually add these arguments? If so, it would be nice to explore the way proposed to do this automatically :)
There was a problem hiding this comment.
To have it all time you could add a .codecarbon.config in CI, or environment variables:
CODECARBON_LOG_LEVEL="error"
CODECARBON_SAVE_TO_FILE=False
So every will use these settings.
BTW @cianc this is awesome for the quality of the doc ! I did not know it was possible.
|
|
||
| ``` python | ||
| ```python | ||
| # skip |
There was a problem hiding this comment.
we can actually run this for a small subset of the data, right?
|
|
||
| ``` python | ||
| ```python | ||
| # skip |
There was a problem hiding this comment.
same here, we could run this with a small subset of the data, right?
| ```python | ||
| from codecarbon import EmissionsTracker | ||
| tracker = EmissionsTracker() | ||
| tracker = EmissionsTracker(save_to_file=False, log_level="error") |
There was a problem hiding this comment.
why do we add these arguments here specifically and not in all other places?
|
@cianc just following up here to see if the extended contribution fits in your time schedule, if not feel free to let us know, and we'll handle the rest :) |
|
Yes sorry, work has been quite busy. These suggestions seems reasonable and
I hope to get to them soon.
…On Mon, Mar 9, 2026 at 12:36 PM David Berenstein ***@***.***> wrote:
*davidberenstein1957* left a comment (mlco2/codecarbon#1096)
<#1096 (comment)>
@cianc <https://github.com/cianc> just following up here to see if the
extended contribution fits in your time schedule, if not feel free to let
us know, and we'll handle the rest :)
—
Reply to this email directly, view it on GitHub
<#1096 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AADD7PTBJQDHYNZWPCHSYZD4P23FVAVCNFSM6AAAAACWF6E7M2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHM2DAMRTGQ2TAOJYGU>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Description
Adds automated testing of Python code examples in the documentation to prevent examples from drifting out of sync with the library.
Add
mktestdocsandpytestto thedocdependency group inpyproject.tomlso they are available alongside the other doc-build tools without pulling in the fulldevgroup.Add
scripts/check-docs-drift.py: a pytest-based script that usesmktestdocs.grab_code_blocks()to collect every ```python fenced block underdocs/, skips any block whose first line is `# skip`, and executes the rest via `exec_python()`. A new taskipy task `docs-check-drift` runs it with `pytest scripts/check-docs-drift.py -v`.Fix all ```python code blocks across
docs/so they are correctly picked up by mktestdocs:python fences (changed topython) so that mktestdocs can identify them (it matches on the exact string "python" immediately after the backticks).save_to_file=False, log_level="error"toEmissionsTrackerandOfflineEmissionsTrackerinstantiations to avoid creating CSV files or noisy output during CI runs.# skipas the first line of blocks that cannot run in CI because they depend on external services or optional heavy dependencies (TensorFlow, Prometheus, Logfire, Google Cloud, Comet ML, live CodeCarbon API).pip installcommand that was incorrectly fenced aspython in `comet.md`; changed toconsole.Update
.github/workflows/build-docs.ymlto rundocs-check-driftas a step before the docs build, triggered on changes todocs/**,mkdocs.yml, orscripts/check-docs-drift.py.Document the drift check and the
# skipconvention inCONTRIBUTING.mdunder the "Build Documentation" section.Related Issue
Please link to the issue this PR resolves: #1083
Motivation and Context
Helps prevent drift of code blocks in documentation
How Has This Been Tested?
Ran all tests including new mktestdocs tests.
Screenshots (if appropriate):
Types of changes
What types of changes does your code introduce? Put an
xin all the boxes that apply:Checklist:
Go over all the following points, and put an
xin all the boxes that apply.