[core] Only snapshot the user config when esphome config --no-defaults asks for it - #18113
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## dev #18113 +/- ##
=======================================
Coverage 87.28% 87.28%
=======================================
Files 64 64
Lines 14696 14697 +1
Branches 2216 2217 +1
=======================================
+ Hits 12827 12828 +1
Misses 1560 1560
Partials 309 309
🚀 New features to boost your workflow:
|
PR Review — [core] Only snapshot the user config when esphome config --no-defaults asks for itCorrect, minimal opt-in for an expensive deep copy. Merge-ready; one test-coverage nit. Specific things done well:
Key issue:
🟢 Suggestions
1. The one wiring line that keeps `--no-defaults` working is untested
|
There was a problem hiding this comment.
Tip
No blocking issues found — ready to merge.
|
👋 Hi there! This PR modifies 2 file(s) with codeowners. @esphome/core - As codeowner(s) of the affected files, your review would be appreciated! 🙏 Note: Automatic review request may have failed, but you're still welcome to review. |
There was a problem hiding this comment.
Pull request overview
Reduces configuration load overhead by avoiding an unconditional deep-copy of the raw user config during validation, while preserving esphome config --no-defaults behavior by taking the snapshot only when that command requests it.
Changes:
- Add a
snapshot_user_configflag tovalidate_config()and thread it throughload_config()/read_config()so the user-config snapshot is optional. - Update CLI invocation to enable snapshotting only for
esphome config --no-defaults. - Extend unit tests to cover the opt-in snapshot behavior and the default “no snapshot” path.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
esphome/config.py |
Makes user-config snapshot deep-copy conditional via snapshot_user_config and propagates the flag through config-loading helpers. |
esphome/__main__.py |
Passes snapshot_user_config to read_config() only when --no-defaults is set for the config command. |
tests/unit_tests/test_substitutions.py |
Updates existing snapshot tests to opt in, and adds coverage for “no substitutions” and default snapshot skipping. |
tests/unit_tests/test_main.py |
Verifies run_esphome only requests snapshotting for config --no-defaults. |
Merging this PR will improve performance by 53.42%
Performance Changes
Tip Curious why this is faster? Comment Comparing |
|
thanks |
What does this implement/fix?
Since #16718 every config load deep copies the whole raw config into
result.user_configsoesphome config --no-defaultscan dump exactly what the user wrote, but it was never noticed because our CI failed to run the benchmarks on that PR; the benchmarks job is not triggered by top-levelesphome/*.pychanges, so the author never got a signal, which is fixed in #18114. Profiling shows the copy takes about a third ofread_configtime; the config tree is full of dynamically generated node classes carrying source location metadata, socopy.deepcopygoes through the slow generic reconstruct path for every node.Only the
configcommand with--no-defaultsever reads that snapshot, so take it only when asked: asnapshot_user_configflag is threaded from theread_configcall site down tovalidate_config, defaulting to off. Compile, upload, logs, dashboard and the vscode language server all skip the copy entirely;--no-defaultsbehaves exactly as before, and the existing fallback incommand_configstill covers any path without a snapshot.CodSpeed measured the win on #18115, a test PR combining this change with the #18114 gating fix:
test_read_config_uncachedwent from 111.9 ms to 73 ms, a 53% improvement, with all other benchmarks untouched; full report at #18115 (comment).Types of changes
Related issue or feature (if applicable):
Pull request in esphome.io with documentation (if applicable):
Pull request in developers.esphome.io with developer documentation (if applicable):
Test Environment
Example entry for
config.yaml:# Example config.yamlChecklist:
tests/folder).If user exposed functionality or configuration variables are added/changed: