sphinx-build -D needs_variant_data=x is rejected by Sphinx β WARNING: cannot override dictionary config setting 'needs_variant_data', ignoring (use -D needs_variant_data.key=val to set individual elements) β but the key stays in config.overrides, and sphinx-needs' TOML reader then treats it as an applied override: _load_variants_from_toml removes data from [variants] and variant_data from [needs] before read_variants (packages/sphinx-needs/src/sphinx_needs/needs.py, the _without_key loop keyed on legacy_key in overridden or f"needs_{legacy_key}" in overridden). The inline map declared in the TOML silently vanishes for an override Sphinx never applied.
Measured (2026-09-30, master at d0edd0e9, while reviewing #2000): a project with needs_from_toml = "ubproject.toml", [variants] data_file = "vd.json" + [variants.data] edition = "pro", built with -D needs_variant_data=x β Sphinx's "cannot override β¦ ignoring" warning, then needs_variant_data resolves from the file alone: edition is gone (rc 0, no sphinx-needs warning). The same happens for the legacy [needs.variant_data] location, and the bare spelling -D variant_data=x (an unknown config value Sphinx also ignores, and the loop also honours) does the same.
The dotted form -D needs_variant_data.k=v is unaffected: Sphinx folds it into the raw config and drops it from overrides, so nothing is stripped and the value lands on the confval (#1991 covers the separate problem that it is then lost under a TOML inline table).
Fix shape. Strip a key only for an override Sphinx actually applied: consult config.overrides for the two needs_variant_data* confval names and skip needs_variant_data when the override value is not a mapping (Sphinx never applies a non-dict override to a dict confval), or β simpler and closer to what a user means β treat only needs_variant_data_file and the dotted needs_variant_data.<k> forms as overrides of the inline table's keys. Drop the bare variant_data / variant_data_file spellings from the predicate: they are not confvals and Sphinx ignores them. One test per form (applied -D needs_variant_data_file=β¦ still strips; rejected -D needs_variant_data=x and the bare spellings do not).
sphinx-mounts (#2000) mirrors the current rule verbatim on the file sphinx-needs is pointed at, so the two tools agree; when this changes, sphinx_mounts.extension._without_overridden follows in the same release window (its docstring names the mirror).
sphinx-build -D needs_variant_data=xis rejected by Sphinx βWARNING: cannot override dictionary config setting 'needs_variant_data', ignoring (use -D needs_variant_data.key=val to set individual elements)β but the key stays inconfig.overrides, and sphinx-needs' TOML reader then treats it as an applied override:_load_variants_from_tomlremovesdatafrom[variants]andvariant_datafrom[needs]beforeread_variants(packages/sphinx-needs/src/sphinx_needs/needs.py, the_without_keyloop keyed onlegacy_key in overridden or f"needs_{legacy_key}" in overridden). The inline map declared in the TOML silently vanishes for an override Sphinx never applied.Measured (2026-09-30, master at
d0edd0e9, while reviewing #2000): a project withneeds_from_toml = "ubproject.toml",[variants] data_file = "vd.json"+[variants.data] edition = "pro", built with-D needs_variant_data=xβ Sphinx's "cannot override β¦ ignoring" warning, thenneeds_variant_dataresolves from the file alone:editionis gone (rc 0, no sphinx-needs warning). The same happens for the legacy[needs.variant_data]location, and the bare spelling-D variant_data=x(an unknown config value Sphinx also ignores, and the loop also honours) does the same.The dotted form
-D needs_variant_data.k=vis unaffected: Sphinx folds it into the raw config and drops it fromoverrides, so nothing is stripped and the value lands on the confval (#1991 covers the separate problem that it is then lost under a TOML inline table).Fix shape. Strip a key only for an override Sphinx actually applied: consult
config.overridesfor the twoneeds_variant_data*confval names and skipneeds_variant_datawhen the override value is not a mapping (Sphinx never applies a non-dict override to a dict confval), or β simpler and closer to what a user means β treat onlyneeds_variant_data_fileand the dottedneeds_variant_data.<k>forms as overrides of the inline table's keys. Drop the barevariant_data/variant_data_filespellings from the predicate: they are not confvals and Sphinx ignores them. One test per form (applied-D needs_variant_data_file=β¦still strips; rejected-D needs_variant_data=xand the bare spellings do not).sphinx-mounts (#2000) mirrors the current rule verbatim on the file sphinx-needs is pointed at, so the two tools agree; when this changes,
sphinx_mounts.extension._without_overriddenfollows in the same release window (its docstring names the mirror).