Add config tooling to check for orphan keys - #705
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #705 +/- ##
==========================================
+ Coverage 91.36% 91.45% +0.09%
==========================================
Files 109 110 +1
Lines 14723 14772 +49
Branches 2630 2642 +12
==========================================
+ Hits 13451 13510 +59
+ Misses 1272 1260 -12
- Partials 0 2 +2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
timlichtenberg
left a comment
There was a problem hiding this comment.
Thanks for adding this. Orphan keys have caught me out before, so I'm glad to have a guard for them.
I ran the validator against every bundled TOML using the installed Config schema. Good news first: zero false positives across the full option surface. input/all_options.toml (which contains every valid key) and all of the standard, tutorial, and intercomp configs parse clean, which is strong evidence that the schema mapping is complete. The grid and inference files use a different top-level schema and do get flagged by the raw function, but they never reach read_config_object (grid reads the resolved ref_config, inference loads the .infer.toml separately), so no real workflow regresses.
Two things to fix before merge:
-
auto/statusis committed by accident. Its contents are byte-for-byte whatcheck_for_unknown_keyswrites on the orphan path (status 20), so it was produced by a local validator run and slipped in. Pleasegit rm auto/status. -
The status-file write resolves to the wrong place, and it is what created that stray file.
read_config_objectpassesoutdir=obj.params.out.path, which is the bare run name (default"auto", still an unresolved sentinel at parse time).UpdateStatusfilerunsos.path.abspathon it, so the file lands at<cwd>/auto/statusrather than the canonicaloutput/<name>/statusthat the rest of the code builds inSetDirectories. I reproduced<cwd>/auto/statuswith identical contents in a sandbox. Beyond the wrong path,read_config_objectis called from three sites and is otherwise a pure read/validate, so writing files and creating directories at parse time is a surprising side effect. Simplest fix: drop the status write fromcheck_for_unknown_keysand let the caller report status once the directories are set up.
Smaller points are inline. Once the artifact and the status write are sorted out, this is good to go.
…aturely. Update tests. Remove temp file from git repo
|
Thanks for the constructive review, @timlichtenberg. I have adjusted the functionality in a few ways:
|
timlichtenberg
left a comment
There was a problem hiding this comment.
Thanks for the rework, this addresses everything from my earlier pass and the result is cleaner than the first version.
The key change is the right one: check_config_orphan_free is now a pure predicate (no I/O, no directory creation), and the status-20 write plus the raise moved into Proteus.__init__, where the resolved self.directories['output'] is available. That is why the status file now lands in output/<name>/ instead of the working directory, and it removes the surprising side effect from config parsing. I re-checked the path resolution and ordering (read_config_object drops orphans silently, init_directories resolves the output dir, then the gate fires and writes status 20 before raising) and it is correct.
Also confirmed:
auto/statusis gone.- Zero false positives across the full option surface (
all_options.tomland every standard/tutorial/intercomp config parse clean). - The three integration TOMLs are now orphan-free; nice to see the tool flush real dead keys (
author,condensation) out of our own fixtures. - The new
Proteus.__init__tests exercise the real path and the status-file write, which is what the previous test could not do.
Approving. A couple of optional follow-ups inline, neither blocking.
|
Very nice! |
A key the schema does not define was discarded in silence, so a typo left the parameter sitting at its default with nothing reported. The orphan-key walk added in #705 now runs wherever a configuration is loaded rather than only in `Proteus.__init__`, which brings the grid script, the CLI and the rest of the entry points under it. It also reports the one fault a name comparison cannot see. A section written as `[[name]]` rather than `[name]` leaves a correctly spelled name in place, so nothing notices, while structuring discards the whole section and every parameter inside it falls back to its default. The entry point is `read_config_object`, composing `read_config`, `find_key_problems` and `structure_config`, and it always refuses a configuration it cannot account for.
Description
Currently, it is possible to include "orphan" keys in the config file which don't map to any thing in the Config object of PROTEUS. This module provides helpers that recursively compare the raw dict, read from the PROTEUS toml-formatted config files, against the Config schema.
E.g. if you were to pass
atmos_clim.agni.spectral_group="Honeyside"it will do nothing to warn you, at the moment, but you could then write a paper saying you used these opacities.These are important to identify because a user could set these with intent, but they
will be ignored if not mapped by the parser. I have been caught out by this before, so am making this PR to prevent it happening in the future.
Closes #666
Validation of changes
validate.pyfile which checks for orphaned keysTested on Fedora 44, Python 3.13
Checklist