facebookresearch / hydra

Hydra is a framework for elegantly configuring complex applications
https://hydra.cc
MIT License
8.78k stars 630 forks source link

[Bug] Unexpected behavior of tilde (~) when removing from default list of multiple choices #2843

Open Northo opened 9 months ago

Northo commented 9 months ago

πŸ› Bug

Description

Following the pattern of Selecting multiple configs from a Config Group, the behavior of tilde (~) is unexpected; I am not able to evaluate if this is a bug or a lack in the documentation.

When having multiple choices selected in the Defaults List, we cannot remove them with the ~db, ~db=mysql, ~server/db, ~server/db=mysql syntax, described here.

Checklist

To reproduce

Minimal Code/Config snippet to reproduce

Consider a config layout (where fb.yaml and google.yaml are as described in the docs)

.
β”œβ”€β”€ config.yaml
└── site
    β”œβ”€β”€ fb.yaml
    └── google.yaml

and

# config.yaml
defaults:
  - site: fb

When running with CLI overrides ~site=fb, defaults list is cleared and config is an empty dict.

However, consider

# config.yaml
defaults:
  - site:
    - fb

When running with CLI overrides ~site=fb, we get hydra.errors.ConfigCompositionException: Could not delete 'site=fb'. No match in the defaults list.

Full stacktrace ``` Traceback (most recent call last): File "/wd/src/main.py", line 9, in my_app() File "/venv/site-packages/hydra/main.py", line 94, in decorated_main _run_hydra( File "/venv/site-packages/hydra/_internal/utils.py", line 420, in _run_hydra hydra.show_info( File "/venv/site-packages/hydra/_internal/hydra.py", line 701, in show_info options[info]( File "/venv/site-packages/hydra/_internal/hydra.py", line 627, in _print_all_info self._print_config_info(config_name, overrides, run_mode) File "/venv/site-packages/hydra/_internal/hydra.py", line 492, in _print_config_info self._print_search_path( File "/venv/site-packages/hydra/_internal/hydra.py", line 420, in _print_search_path cfg = self.compose_config( ^^^^^^^^^^^^^^^^^^^^ File "/venv/site-packages/hydra/_internal/hydra.py", line 594, in compose_config cfg = self.config_loader.load_configuration( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/venv/site-packages/hydra/_internal/config_loader_impl.py", line 142, in load_configuration return self._load_configuration_impl( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/venv/site-packages/hydra/_internal/config_loader_impl.py", line 253, in _load_configuration_impl defaults_list = create_defaults_list( ^^^^^^^^^^^^^^^^^^^^^ File "/venv/site-packages/hydra/_internal/defaults_list.py", line 753, in create_defaults_list overrides.ensure_deletions_used() File "/venv/site-packages/hydra/_internal/defaults_list.py", line 175, in ensure_deletions_used raise ConfigCompositionException(msg) hydra.errors.ConfigCompositionException: Could not delete 'site=fb'. No match in the defaults list ```

Similarly, ~site/fb gives hydra.errors.ConfigCompositionException: Could not delete from config. 'site/fb' does not exist. and ~site gives hydra.errors.ConfigCompositionException: Could not delete 'site'. No match in the defaults list.

I am able to clear the defaults list for it by site=[], however, I'd like to also understand the ~ operator in this situation.

Expected Behavior

Appropriate application of the tilde operator should clear one element of the site group or all the entries of the site group. If this is not intended behavior, this should be documented explicitly either on the Selecting multiple configs from a Config Group page or override grammar page.

System information

Let me know if you require further clarifications.

Additional context

For convenience, output of --info all for the two scenarios are here:

Defaults with choice as list (`site: [fb]`) ```yaml # config.yaml defaults: - site: - fb - _self_ ``` gives ``` Hydra 1.3.2 =========== Installed Hydra Plugins *********************** ConfigSource: ------------- FileConfigSource ImportlibResourcesConfigSource StructuredConfigSource CompletionPlugin: ----------------- BashCompletion FishCompletion ZshCompletion Launcher: --------- BasicLauncher Sweeper: -------- BasicSweeper Config search path ****************** | Provider | Search path | ------------------------------------------------------------------------------------ | hydra | pkg://hydra.conf | | main | file:///cwd/conf | | schema | structured:// | ------------------------------------------------------------------------------------ Defaults Tree ************* : hydra/config: hydra/output: default hydra/launcher: basic hydra/sweeper: basic hydra/help: default hydra/hydra_help: default hydra/hydra_logging: default hydra/job_logging: default hydra/callbacks: null hydra/env: default _self_ config: site/fb _self_ Defaults List ************* | Config path | Package | _self_ | Parent | ------------------------------------------------------------------------------ | hydra/output/default | hydra | False | hydra/config | | hydra/launcher/basic | hydra.launcher | False | hydra/config | | hydra/sweeper/basic | hydra.sweeper | False | hydra/config | | hydra/help/default | hydra.help | False | hydra/config | | hydra/hydra_help/default | hydra.hydra_help | False | hydra/config | | hydra/hydra_logging/default | hydra.hydra_logging | False | hydra/config | | hydra/job_logging/default | hydra.job_logging | False | hydra/config | | hydra/env/default | hydra.env | False | hydra/config | | hydra/config | hydra | True | | | site/fb | site | False | config | | config | | True | | ------------------------------------------------------------------------------ Config ****** site: fb: domain: fb.com ```
Defaults with choice as object (`site: fb`) ```yaml # config.yaml defaults: - site: fb - _self_ ``` gives ``` Hydra 1.3.2 =========== Installed Hydra Plugins *********************** ConfigSource: ------------- FileConfigSource ImportlibResourcesConfigSource StructuredConfigSource CompletionPlugin: ----------------- BashCompletion FishCompletion ZshCompletion Launcher: --------- BasicLauncher Sweeper: -------- BasicSweeper Config search path ****************** | Provider | Search path | ------------------------------------------------------------------------------------ | hydra | pkg://hydra.conf | | main | file:///cwd/conf | | schema | structured:// | ------------------------------------------------------------------------------------ Defaults Tree ************* : hydra/config: hydra/output: default hydra/launcher: basic hydra/sweeper: basic hydra/help: default hydra/hydra_help: default hydra/hydra_logging: default hydra/job_logging: default hydra/callbacks: null hydra/env: default _self_ config: site: fb _self_ Defaults List ************* | Config path | Package | _self_ | Parent | ------------------------------------------------------------------------------ | hydra/output/default | hydra | False | hydra/config | | hydra/launcher/basic | hydra.launcher | False | hydra/config | | hydra/sweeper/basic | hydra.sweeper | False | hydra/config | | hydra/help/default | hydra.help | False | hydra/config | | hydra/hydra_help/default | hydra.hydra_help | False | hydra/config | | hydra/hydra_logging/default | hydra.hydra_logging | False | hydra/config | | hydra/job_logging/default | hydra.job_logging | False | hydra/config | | hydra/env/default | hydra.env | False | hydra/config | | hydra/config | hydra | True | | | site/fb | site | False | config | | config | | True | | ------------------------------------------------------------------------------ Config ****** site: fb: domain: fb.com ```
Defaults with multiple choices (`site: [fb, google]`) ```yaml # config.yaml defaults: - site: - fb - google - _self_ ``` gives ``` Hydra 1.3.2 =========== Installed Hydra Plugins *********************** ConfigSource: ------------- FileConfigSource ImportlibResourcesConfigSource StructuredConfigSource CompletionPlugin: ----------------- BashCompletion FishCompletion ZshCompletion Launcher: --------- BasicLauncher Sweeper: -------- BasicSweeper Config search path ****************** | Provider | Search path | ------------------------------------------------------------------------------------ | hydra | pkg://hydra.conf | | main | file:///cwd/conf | | schema | structured:// | ------------------------------------------------------------------------------------ Defaults Tree ************* : hydra/config: hydra/output: default hydra/launcher: basic hydra/sweeper: basic hydra/help: default hydra/hydra_help: default hydra/hydra_logging: default hydra/job_logging: default hydra/callbacks: null hydra/env: default _self_ config: site/fb site/google _self_ Defaults List ************* | Config path | Package | _self_ | Parent | ------------------------------------------------------------------------------ | hydra/output/default | hydra | False | hydra/config | | hydra/launcher/basic | hydra.launcher | False | hydra/config | | hydra/sweeper/basic | hydra.sweeper | False | hydra/config | | hydra/help/default | hydra.help | False | hydra/config | | hydra/hydra_help/default | hydra.hydra_help | False | hydra/config | | hydra/hydra_logging/default | hydra.hydra_logging | False | hydra/config | | hydra/job_logging/default | hydra.job_logging | False | hydra/config | | hydra/env/default | hydra.env | False | hydra/config | | hydra/config | hydra | True | | | site/fb | site | False | config | | site/google | site | False | config | | config | | True | | ------------------------------------------------------------------------------ Config ****** site: fb: domain: fb.com google: domain: google ```
Defaults with choice as object and override (`site: fb` and `~site=fb`) ```yaml # config.yaml defaults: - site: fb - _self_ ``` gives ``` Hydra 1.3.2 =========== Installed Hydra Plugins *********************** ConfigSource: ------------- FileConfigSource ImportlibResourcesConfigSource StructuredConfigSource CompletionPlugin: ----------------- BashCompletion FishCompletion ZshCompletion Launcher: --------- BasicLauncher Sweeper: -------- BasicSweeper Config search path ****************** | Provider | Search path | ------------------------------------------------------------------------------------ | hydra | pkg://hydra.conf | | main | file:///cwd/conf | | schema | structured:// | ------------------------------------------------------------------------------------ Defaults Tree ************* : hydra/config: hydra/output: default hydra/launcher: basic hydra/sweeper: basic hydra/help: default hydra/hydra_help: default hydra/hydra_logging: default hydra/job_logging: default hydra/callbacks: null hydra/env: default _self_ config: site: fb _self_ Defaults List ************* | Config path | Package | _self_ | Parent | ------------------------------------------------------------------------------ | hydra/output/default | hydra | False | hydra/config | | hydra/launcher/basic | hydra.launcher | False | hydra/config | | hydra/sweeper/basic | hydra.sweeper | False | hydra/config | | hydra/help/default | hydra.help | False | hydra/config | | hydra/hydra_help/default | hydra.hydra_help | False | hydra/config | | hydra/hydra_logging/default | hydra.hydra_logging | False | hydra/config | | hydra/job_logging/default | hydra.job_logging | False | hydra/config | | hydra/env/default | hydra.env | False | hydra/config | | hydra/config | hydra | True | | | config | | True | | ------------------------------------------------------------------------------ Config ****** {} ```
odelalleau commented 9 months ago

I suspect this is indeed a bug / unsupported case, thanks for reporting it.

FrenkT commented 1 month ago

Found the same issue, thanks for raising.