Problem
Two API-hygiene issues that bite real usage:
-
analyze() mutates the passed Config. analyze.py writes cfg.module_prefix (1066), cfg.source_roots (1114-1116), and the three df caps (1124-1125) back onto the caller's object. Reusing one Config across calls — e.g. analyzing two modules in a loop, or two repos with one strict config — leaks state: the second run inherits the first run's module prefix, detected source roots, and auto-tuned caps (and since the caps are now non-None, auto-tuning is silently skipped).
-
Config.from_file ignores unknown keys silently. A typo like "file_dfmax" or "stop_words" in a knobs JSON is a no-op with no warning. Given the documented troubleshooting flow is "tighten caps until the mega-cluster splits," a silently-ignored knob sends the user in circles.
Fix
analyze() works on a copy (dataclasses.replace / copy.copy) and never mutates its argument. Alternatively move the run-scoped fields (module_prefix, resolved roots, resolved caps) into a separate runtime object.
from_file collects unrecognized top-level keys and warns to stderr (warning: unknown config keys: file_dfmax — did you mean file_df_max?). Keep it a warning, not an error, for forward-compat.
Acceptance
- Calling
analyze() twice with the same Config object yields identical results to two fresh Configs.
- Unknown config key produces a stderr warning; valid keys produce none.
Problem
Two API-hygiene issues that bite real usage:
analyze()mutates the passed Config. analyze.py writescfg.module_prefix(1066),cfg.source_roots(1114-1116), and the three df caps (1124-1125) back onto the caller's object. Reusing oneConfigacross calls — e.g. analyzing two modules in a loop, or two repos with one strict config — leaks state: the second run inherits the first run's module prefix, detected source roots, and auto-tuned caps (and since the caps are now non-None, auto-tuning is silently skipped).Config.from_fileignores unknown keys silently. A typo like"file_dfmax"or"stop_words"in a knobs JSON is a no-op with no warning. Given the documented troubleshooting flow is "tighten caps until the mega-cluster splits," a silently-ignored knob sends the user in circles.Fix
analyze()works on a copy (dataclasses.replace/copy.copy) and never mutates its argument. Alternatively move the run-scoped fields (module_prefix, resolved roots, resolved caps) into a separate runtime object.from_filecollects unrecognized top-level keys and warns to stderr (warning: unknown config keys: file_dfmax — did you mean file_df_max?). Keep it a warning, not an error, for forward-compat.Acceptance
analyze()twice with the same Config object yields identical results to two fresh Configs.