🐛 Don't mutate rebuild='env' src_trace_projects config during builds#75
Merged
Merged
Conversation
The src-trace directive populated src_dir/src_files/git_root directly on the
analyse_config object stored inside src_trace_projects. That value is registered
with rebuild="env", so the build-mutated object was pickled into
environment.pickle; on the next build Sphinx compared it against the freshly
generated (empty) config and reported [config changed ('src_trace_projects')],
forcing a full re-read of all docs on every incremental build.
Work on a per-directive dataclasses.replace() copy so the stored config value
stays equal to what generate_project_configs() yields. Add a regression test
that builds the fixture twice and asserts the second build sees CONFIG_OK.
Refs #74
502c3ee to
ef25f45
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #75 +/- ##
==========================================
+ Coverage 90.79% 90.86% +0.06%
==========================================
Files 30 30
Lines 2771 2790 +19
Branches 305 305
==========================================
+ Hits 2516 2535 +19
Misses 160 160
Partials 95 95 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
patdhlk
approved these changes
Jun 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Incremental Sphinx builds always re-read every document, logging
[config changed ('src_trace_projects')] N added, 0 changed, 0 removed, evenwhen nothing changed — incremental builds behave like full rebuilds.
src_trace_projectsis registered withrebuild="env", so Sphinx pickles itinto
environment.pickleand invalidates the environment whenever the pickled("old") value differs from the freshly computed ("new") one.
generate_project_configs()stores runtimeanalyse_config/source_discover_configdataclass objects in that value; on their own theyround-trip through pickle as
==-equal.The bug: the
src-tracedirective mutated the storedanalyse_configinplace during the build (
src_dir,src_files,git_rootset to build-time,resolved values). Those build-time values were persisted into the pickle, while
the next build's
config-initedproduced a freshanalyse_config(
src_files=[],src_dir=Path(".")), so the comparison always differed:src_dirsrc_files/abs/.../dcdc['demo_3.cpp', ...]Path('.')[]Fix
Operate on a per-directive
dataclasses.replace()copy instead of mutating theanalyse_configstored in therebuild="env"config value. The stored valuethen stays equal to what
generate_project_configs()yields, so incrementalbuilds report
0 added, 0 changed, 0 removed.Verification
test_incremental_build_keeps_src_trace_projects_unchangedbuilds the fixture twice and asserts the 2nd (incremental) build sees
CONFIG_OK— fails before the fix (CONFIG_CHANGED ('src_trace_projects')),passes after.
0 added, 0 changed, 0 removed.Fixes #74