Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable --cfg=job --resolve with ${hydra:...} resolver #1696

Merged
merged 12 commits into from
Jul 17, 2021

Conversation

Jasha10
Copy link
Collaborator

@Jasha10 Jasha10 commented Jun 24, 2021

This PR closes #1681, so that resolved references to HydraConfig can appear
in the output from the --cfg=job flag. It is now possible to call
python my_app.py --cfg job --resolve
when the user config contains the ${hydra:...} resolver.

To implement this, several changes are made to the
hydra._internal.hydra.Hydra class:

  • In the Hydra._get_cfg method, we now call
    HydraConfig.instance().set_config(cfg) on the composed cfg object,
    enabling the ${hydra:...} resolver.
  • Previously, the Hydra._get_cfg method would delete the cfg["hydra"]
    package immediately. We now delay the deletion until after
    OmegaConf.resolve can be called. This is done by factoring out a
    Hydra.get_sanitized_cfg method.
  • Since the HydraConfig.set_config method sets a 'readonly' flag, it is
    now necessary to use a read_write/flag_override context manager when
    calling OmegaConf.resolve and when deleting the cfg["hydra"] package.
  • We also call HydraConfig.instance().set_config(cfg) in the
    Hydra.app_help method. This allows for
    python my_app.py --help --resolve
    to work even if the help template references the user's $CONFIG and the
    ${hydra:...} resolver appears in that user config.

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jun 24, 2021
@lgtm-com
Copy link
Contributor

lgtm-com bot commented Jun 24, 2021

This pull request introduces 1 alert when merging ecaba57 into 8fa67de - view on LGTM.com

new alerts:

  • 1 for Unused local variable

Copy link
Collaborator

@omry omry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice. See comment.

cfg = self.compose_config(
config_name=config_name,
overrides=overrides,
run_mode=RunMode.RUN,
with_log_configuration=with_log_configuration,
)
HydraConfig.instance().set_config(cfg)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer not to introduce a side effect to a getter function.
Can the caller do this instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I inlined the _get_cfg method in 6828fcc.

Comment on lines 210 to 211
with read_write(cfg.hydra):
OmegaConf.resolve(ret)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems unrelated. What is the motivation for this? (Is there a missing test?)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The HydraConfig.set_config method sets a readonly flag on cfg.hydra, so OmegaConf.resolve fails unless the flag is turned off.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could unset the readonly flag in show_cfg and show_help.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 57452d5. I only needed to unset the flag in show_cfg. In show_help, a readonly flag is no problem because we are using OmegaConf.to_yaml(..., resolve=...) instead of OmegaConf.resolve(...).

@lgtm-com
Copy link
Contributor

lgtm-com bot commented Jun 29, 2021

This pull request introduces 1 alert when merging 6828fcc into 437e20d - view on LGTM.com

new alerts:

  • 1 for Unused local variable

hydra/_internal/hydra.py Outdated Show resolved Hide resolved
Comment on lines 210 to 211
with read_write(cfg.hydra):
OmegaConf.resolve(ret)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could unset the readonly flag in show_cfg and show_help.

tests/test_hydra.py Outdated Show resolved Hide resolved
news/1681.bugfix Outdated
@@ -0,0 +1 @@
Fix the --cfg=job --resolve flags so that the ${hydra:...} resolver now prints properly
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes --help as well?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I updated the news fragment in 751653f.

Comment on lines 7 to 9
@hydra.main(config_path=".", config_name="config")
def my_app(cfg: DictConfig) -> None:
pass
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you reuse simple_app here?
You can place the config next to it or somewhere else and override the used config like:

python tests/test_apps/simple_app/my_app.py  --config-name=config --config-dir=tests/test_apps/app_with_cfg

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 1d7bdd2.

Comment on lines 635 to 646
"examples/tutorials/basic/your_first_hydra_app/2_config_file/my_app.py",
["--help", "--resolve"],
["hydra.help.template=$CONFIG", "db.user=${hydra:job.name}"],
dedent(
"""\
db:
driver: mysql
user: my_app
password: secret
"""
),
id="overriding_help_template:$CONFIG,resolve_interp_to_hydra_config",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generally speaking, avoid testing with the tutorial apps except in tests/test_examples. (I know the code is not being consistent about it).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made the change in 27052cf.

@lgtm-com
Copy link
Contributor

lgtm-com bot commented Jun 30, 2021

This pull request introduces 1 alert when merging 1b4af22 into 437e20d - view on LGTM.com

new alerts:

  • 1 for Unused local variable

@lgtm-com
Copy link
Contributor

lgtm-com bot commented Jun 30, 2021

This pull request introduces 1 alert when merging 57452d5 into 437e20d - view on LGTM.com

new alerts:

  • 1 for Unused local variable

Comment on lines 145 to 150
def sanitize_hydra_cfg(cfg: DictConfig) -> None:
"""
Mutate the input cfg:
- delete all toplevel keys except "hydra".
- delete `hydra.help` and `hydra.hydra_help`.
"""
Copy link
Collaborator Author

@Jasha10 Jasha10 Jun 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3c87309 is a refactoring:

  • get_sanitized_hydra_cfg -> sanitize_hydra_cfg
  • get_sanitized_cfg -> sanitize_cfg

Before, these methods were making a deepcopy in some branches, and not making a deepcopy in other branches.
Now, they never make a deepcopy (i.e. they mutate their input directly). This refactoring should resolve the LGTM alerts that are posted in the PR's main thread.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like get_sanitized_hydra_cfg was always copying and get_sanitized_cfg was composing (so no need to copy).
Not sure what alerts you are referring to.

def get_sanitized_hydra_cfg(src_cfg: DictConfig) -> DictConfig:
        cfg = copy.deepcopy(src_cfg)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the warning, the refactoring sounds like way too big a hammer.

image

Copy link
Collaborator Author

@Jasha10 Jasha10 Jul 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough. I reverted the refactoring in f0fa6cd and then did a simpler fix in 06258d2.

Copy link
Collaborator

@omry omry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good.

@Jasha10 Jasha10 merged commit 27ab477 into facebookresearch:master Jul 17, 2021
@Jasha10 Jasha10 deleted the closes1681 branch September 15, 2021 20:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug] HydraConfig is not set while resolving config with --cfg job --resolve
3 participants