We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Option to access hydra configs from interpolation
The hydra config node is removed from the tree before the program stats, which makes it impossible to rely on it at runtime.
The reason it's removed is that otherwise the user config would be very large even for a simple program.
That config however is still available at runtime through the HydraConfig singleston.

The idea here is to simply register a resolver function by the name of hydra, which would provide access to hydra config.

User usage would look like:
```yaml
gpu_id: ${hydra:job.num}
```

This can be useful for accessing everything inside the hydra config, including parameters only available at runtime.

In addition, provide an option to call to_absolute_dir from interpolations.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `hydra/core/utils.py`
Content:
```
1 # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
2 import copy
3 import logging
4 import os
5 import re
6 import sys
7 import warnings
8 from contextlib import contextmanager
9 from dataclasses import dataclass
10 from os.path import basename, dirname, splitext
11 from pathlib import Path
12 from time import localtime, strftime
13 from typing import Any, Dict, Optional, Sequence, Tuple, Union
14 
15 from omegaconf import DictConfig, OmegaConf, open_dict
16 
17 from hydra.core.hydra_config import HydraConfig
18 from hydra.core.singleton import Singleton
19 from hydra.types import TaskFunction
20 
21 log = logging.getLogger(__name__)
22 
23 
24 def configure_log(
25     log_config: DictConfig, verbose_config: Union[bool, str, Sequence[str]]
26 ) -> None:
27     assert isinstance(verbose_config, (bool, str)) or OmegaConf.is_list(verbose_config)
28     if log_config is not None:
29         conf: Dict[str, Any] = OmegaConf.to_container(  # type: ignore
30             log_config, resolve=True
31         )
32         logging.config.dictConfig(conf)
33     else:
34         # default logging to stdout
35         root = logging.getLogger()
36         root.setLevel(logging.INFO)
37         handler = logging.StreamHandler(sys.stdout)
38         formatter = logging.Formatter(
39             "[%(asctime)s][%(name)s][%(levelname)s] - %(message)s"
40         )
41         handler.setFormatter(formatter)
42         root.addHandler(handler)
43     if isinstance(verbose_config, bool):
44         if verbose_config:
45             logging.getLogger().setLevel(logging.DEBUG)
46     else:
47         if isinstance(verbose_config, str):
48             verbose_list = OmegaConf.create([verbose_config])
49         elif OmegaConf.is_list(verbose_config):
50             verbose_list = verbose_config  # type: ignore
51         else:
52             assert False
53 
54         for logger in verbose_list:
55             logging.getLogger(logger).setLevel(logging.DEBUG)
56 
57 
58 def _save_config(cfg: DictConfig, filename: str, output_dir: Path) -> None:
59     output_dir.mkdir(parents=True, exist_ok=True)
60     with open(str(output_dir / filename), "w") as file:
61         file.write(cfg.pretty())
62 
63 
64 def filter_overrides(overrides: Sequence[str]) -> Sequence[str]:
65     """
66     :param overrides: overrides list
67     :return: returning a new overrides list with all the keys starting with hydra. filtered.
68     """
69     return [x for x in overrides if not x.startswith("hydra.")]
70 
71 
72 def run_job(
73     config: DictConfig,
74     task_function: TaskFunction,
75     job_dir_key: str,
76     job_subdir_key: Optional[str],
77 ) -> "JobReturn":
78     old_cwd = os.getcwd()
79     working_dir = str(OmegaConf.select(config, job_dir_key))
80     if job_subdir_key is not None:
81         # evaluate job_subdir_key lazily.
82         # this is running on the client side in sweep and contains things such as job:id which
83         # are only available there.
84         subdir = str(OmegaConf.select(config, job_subdir_key))
85         working_dir = os.path.join(working_dir, subdir)
86     try:
87         ret = JobReturn()
88         ret.working_dir = working_dir
89         task_cfg = copy.deepcopy(config)
90         with open_dict(task_cfg):
91             del task_cfg["hydra"]
92         ret.cfg = task_cfg
93         ret.hydra_cfg = OmegaConf.create({"hydra": HydraConfig.get()})
94         overrides = OmegaConf.to_container(config.hydra.overrides.task)
95         assert isinstance(overrides, list)
96         ret.overrides = overrides
97         # handle output directories here
98         Path(str(working_dir)).mkdir(parents=True, exist_ok=True)
99         os.chdir(working_dir)
100         hydra_output = Path(config.hydra.output_subdir)
101 
102         configure_log(config.hydra.job_logging, config.hydra.verbose)
103 
104         hydra_cfg = OmegaConf.masked_copy(config, "hydra")
105         assert isinstance(hydra_cfg, DictConfig)
106 
107         _save_config(task_cfg, "config.yaml", hydra_output)
108         _save_config(hydra_cfg, "hydra.yaml", hydra_output)
109         _save_config(config.hydra.overrides.task, "overrides.yaml", hydra_output)
110         with env_override(hydra_cfg.hydra.job.env_set):
111             ret.return_value = task_function(task_cfg)
112         ret.task_name = JobRuntime.instance().get("name")
113 
114         # shut down logging to ensure job log files are closed.
115         # If logging is still required after run_job caller is responsible to re-initialize it.
116         logging.shutdown()
117 
118         return ret
119     finally:
120         os.chdir(old_cwd)
121 
122 
123 def get_valid_filename(s: str) -> str:
124     s = str(s).strip().replace(" ", "_")
125     return re.sub(r"(?u)[^-\w.]", "", s)
126 
127 
128 def setup_globals() -> None:
129     try:
130         OmegaConf.register_resolver(
131             "now", lambda pattern: strftime(pattern, localtime())
132         )
133     except AssertionError:
134         # calling it again in no_workers mode will throw. safe to ignore.
135         pass
136 
137 
138 @dataclass
139 class JobReturn:
140     overrides: Optional[Sequence[str]] = None
141     return_value: Any = None
142     cfg: Optional[DictConfig] = None
143     hydra_cfg: Optional[DictConfig] = None
144     working_dir: Optional[str] = None
145     task_name: Optional[str] = None
146 
147 
148 class JobRuntime(metaclass=Singleton):
149     def __init__(self) -> None:
150         self.conf: DictConfig = OmegaConf.create()
151         self.set("name", "UNKNOWN_NAME")
152 
153     def get(self, key: str) -> Any:
154         ret = OmegaConf.select(self.conf, key)
155         if ret is None:
156             raise KeyError(f"Key not found in {type(self).__name__}: {key}")
157         return ret
158 
159     def set(self, key: str, value: Any) -> None:
160         log.debug(f"Setting {type(self).__name__}:{key}={value}")
161         self.conf[key] = value
162 
163 
164 def split_config_path(
165     config_path: Optional[str], config_name: Optional[str]
166 ) -> Tuple[Optional[str], Optional[str]]:
167     if config_path is None or config_path == "":
168         return None, config_name
169     split_file = splitext(config_path)
170     if split_file[1] in (".yaml", ".yml"):
171         # assuming dir/config.yaml form
172         config_file: Optional[str] = basename(config_path)
173         config_dir: Optional[str] = dirname(config_path)
174         msg = (
175             "\nUsing config_path to specify the config name is deprecated, specify the config name via config_name"
176             "\nSee https://hydra.cc/next/upgrades/0.11_to_1.0/config_path_changes"
177         )
178         warnings.warn(
179             category=UserWarning, message=msg,
180         )
181     else:
182         # assuming dir form without a config file.
183         config_file = None
184         config_dir = config_path
185 
186     if config_dir == "":
187         config_dir = None
188 
189     if config_file == "":
190         config_file = None
191 
192     if config_file is not None:
193         if config_name is not None:
194             raise ValueError(
195                 "Config name should be specified in either normalized_config_path or config_name, but not both"
196             )
197         config_name = config_file
198 
199     return config_dir, config_name
200 
201 
202 @contextmanager
203 def env_override(env: Dict[str, str]) -> Any:
204     """Temporarily set environment variables inside the context manager and
205     fully restore previous environment afterwards
206     """
207     original_env = {key: os.getenv(key) for key in env}
208     os.environ.update(env)
209     try:
210         yield
211     finally:
212         for key, value in original_env.items():
213             if value is None:
214                 del os.environ[key]
215             else:
216                 os.environ[key] = value
217
```

Path: `hydra/core/hydra_config.py`
Content:
```
1 # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
2 from typing import Any, Optional
3 
4 from omegaconf import DictConfig, OmegaConf
5 
6 from hydra.conf import HydraConf
7 from hydra.core.singleton import Singleton
8 
9 
10 class HydraConfig(metaclass=Singleton):
11     def __init__(self) -> None:
12         self.cfg: Optional[HydraConf] = None
13 
14     def set_config(self, cfg: DictConfig) -> None:
15         assert cfg is not None
16         OmegaConf.set_readonly(cfg.hydra, True)
17         assert OmegaConf.get_type(cfg, "hydra") == HydraConf
18         self.cfg = cfg  # type: ignore
19 
20     @staticmethod
21     def get() -> HydraConf:
22         instance = HydraConfig.instance()
23         if instance.cfg is None:
24             raise ValueError("HydraConfig was not set")
25         return instance.cfg.hydra  # type: ignore
26 
27     @staticmethod
28     def initialized() -> bool:
29         instance = HydraConfig.instance()
30         return instance.cfg is not None
31 
32     @staticmethod
33     def instance(*args: Any, **kwargs: Any) -> "HydraConfig":
34         return Singleton.instance(HydraConfig, *args, **kwargs)  # type: ignore
35
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/hydra/core/hydra_config.py b/hydra/core/hydra_config.py
--- a/hydra/core/hydra_config.py
+++ b/hydra/core/hydra_config.py
@@ -15,7 +15,7 @@
         assert cfg is not None
         OmegaConf.set_readonly(cfg.hydra, True)
         assert OmegaConf.get_type(cfg, "hydra") == HydraConf
-        self.cfg = cfg  # type: ignore
+        self.cfg = OmegaConf.masked_copy(cfg, "hydra")  # type: ignore
 
     @staticmethod
     def get() -> HydraConf:
diff --git a/hydra/core/utils.py b/hydra/core/utils.py
--- a/hydra/core/utils.py
+++ b/hydra/core/utils.py
@@ -10,7 +10,7 @@
 from os.path import basename, dirname, splitext
 from pathlib import Path
 from time import localtime, strftime
-from typing import Any, Dict, Optional, Sequence, Tuple, Union
+from typing import Any, Dict, Optional, Sequence, Tuple, Union, cast
 
 from omegaconf import DictConfig, OmegaConf, open_dict
 
@@ -126,13 +126,18 @@
 
 
 def setup_globals() -> None:
-    try:
-        OmegaConf.register_resolver(
-            "now", lambda pattern: strftime(pattern, localtime())
-        )
-    except AssertionError:
-        # calling it again in no_workers mode will throw. safe to ignore.
-        pass
+    def register(name: str, f: Any) -> None:
+        try:
+            OmegaConf.register_resolver(name, f)
+        except AssertionError:
+            # calling it again in no_workers mode will throw. safe to ignore.
+            pass
+
+    register("now", lambda pattern: strftime(pattern, localtime()))
+    register(
+        "hydra",
+        lambda path: OmegaConf.select(cast(DictConfig, HydraConfig.get()), path),
+    )
 
 
 @dataclass

{"golden_diff": "diff --git a/hydra/core/hydra_config.py b/hydra/core/hydra_config.py\n--- a/hydra/core/hydra_config.py\n+++ b/hydra/core/hydra_config.py\n@@ -15,7 +15,7 @@\n         assert cfg is not None\n         OmegaConf.set_readonly(cfg.hydra, True)\n         assert OmegaConf.get_type(cfg, \"hydra\") == HydraConf\n-        self.cfg = cfg  # type: ignore\n+        self.cfg = OmegaConf.masked_copy(cfg, \"hydra\")  # type: ignore\n \n     @staticmethod\n     def get() -> HydraConf:\ndiff --git a/hydra/core/utils.py b/hydra/core/utils.py\n--- a/hydra/core/utils.py\n+++ b/hydra/core/utils.py\n@@ -10,7 +10,7 @@\n from os.path import basename, dirname, splitext\n from pathlib import Path\n from time import localtime, strftime\n-from typing import Any, Dict, Optional, Sequence, Tuple, Union\n+from typing import Any, Dict, Optional, Sequence, Tuple, Union, cast\n \n from omegaconf import DictConfig, OmegaConf, open_dict\n \n@@ -126,13 +126,18 @@\n \n \n def setup_globals() -> None:\n-    try:\n-        OmegaConf.register_resolver(\n-            \"now\", lambda pattern: strftime(pattern, localtime())\n-        )\n-    except AssertionError:\n-        # calling it again in no_workers mode will throw. safe to ignore.\n-        pass\n+    def register(name: str, f: Any) -> None:\n+        try:\n+            OmegaConf.register_resolver(name, f)\n+        except AssertionError:\n+            # calling it again in no_workers mode will throw. safe to ignore.\n+            pass\n+\n+    register(\"now\", lambda pattern: strftime(pattern, localtime()))\n+    register(\n+        \"hydra\",\n+        lambda path: OmegaConf.select(cast(DictConfig, HydraConfig.get()), path),\n+    )\n \n \n @dataclass\n", "issue": "Option to access hydra configs from interpolation\nThe hydra config node is removed from the tree before the program stats, which makes it impossible to rely on it at runtime.\r\nThe reason it's removed is that otherwise the user config would be very large even for a simple program.\r\nThat config however is still available at runtime through the HydraConfig singleston.\r\n\r\nThe idea here is to simply register a resolver function by the name of hydra, which would provide access to hydra config.\r\n\r\nUser usage would look like:\r\n```yaml\r\ngpu_id: ${hydra:job.num}\r\n```\r\n\r\nThis can be useful for accessing everything inside the hydra config, including parameters only available at runtime.\r\n\r\nIn addition, provide an option to call to_absolute_dir from interpolations.\n", "before_files": [{"content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nimport copy\nimport logging\nimport os\nimport re\nimport sys\nimport warnings\nfrom contextlib import contextmanager\nfrom dataclasses import dataclass\nfrom os.path import basename, dirname, splitext\nfrom pathlib import Path\nfrom time import localtime, strftime\nfrom typing import Any, Dict, Optional, Sequence, Tuple, Union\n\nfrom omegaconf import DictConfig, OmegaConf, open_dict\n\nfrom hydra.core.hydra_config import HydraConfig\nfrom hydra.core.singleton import Singleton\nfrom hydra.types import TaskFunction\n\nlog = logging.getLogger(__name__)\n\n\ndef configure_log(\n    log_config: DictConfig, verbose_config: Union[bool, str, Sequence[str]]\n) -> None:\n    assert isinstance(verbose_config, (bool, str)) or OmegaConf.is_list(verbose_config)\n    if log_config is not None:\n        conf: Dict[str, Any] = OmegaConf.to_container(  # type: ignore\n            log_config, resolve=True\n        )\n        logging.config.dictConfig(conf)\n    else:\n        # default logging to stdout\n        root = logging.getLogger()\n        root.setLevel(logging.INFO)\n        handler = logging.StreamHandler(sys.stdout)\n        formatter = logging.Formatter(\n            \"[%(asctime)s][%(name)s][%(levelname)s] - %(message)s\"\n        )\n        handler.setFormatter(formatter)\n        root.addHandler(handler)\n    if isinstance(verbose_config, bool):\n        if verbose_config:\n            logging.getLogger().setLevel(logging.DEBUG)\n    else:\n        if isinstance(verbose_config, str):\n            verbose_list = OmegaConf.create([verbose_config])\n        elif OmegaConf.is_list(verbose_config):\n            verbose_list = verbose_config  # type: ignore\n        else:\n            assert False\n\n        for logger in verbose_list:\n            logging.getLogger(logger).setLevel(logging.DEBUG)\n\n\ndef _save_config(cfg: DictConfig, filename: str, output_dir: Path) -> None:\n    output_dir.mkdir(parents=True, exist_ok=True)\n    with open(str(output_dir / filename), \"w\") as file:\n        file.write(cfg.pretty())\n\n\ndef filter_overrides(overrides: Sequence[str]) -> Sequence[str]:\n    \"\"\"\n    :param overrides: overrides list\n    :return: returning a new overrides list with all the keys starting with hydra. filtered.\n    \"\"\"\n    return [x for x in overrides if not x.startswith(\"hydra.\")]\n\n\ndef run_job(\n    config: DictConfig,\n    task_function: TaskFunction,\n    job_dir_key: str,\n    job_subdir_key: Optional[str],\n) -> \"JobReturn\":\n    old_cwd = os.getcwd()\n    working_dir = str(OmegaConf.select(config, job_dir_key))\n    if job_subdir_key is not None:\n        # evaluate job_subdir_key lazily.\n        # this is running on the client side in sweep and contains things such as job:id which\n        # are only available there.\n        subdir = str(OmegaConf.select(config, job_subdir_key))\n        working_dir = os.path.join(working_dir, subdir)\n    try:\n        ret = JobReturn()\n        ret.working_dir = working_dir\n        task_cfg = copy.deepcopy(config)\n        with open_dict(task_cfg):\n            del task_cfg[\"hydra\"]\n        ret.cfg = task_cfg\n        ret.hydra_cfg = OmegaConf.create({\"hydra\": HydraConfig.get()})\n        overrides = OmegaConf.to_container(config.hydra.overrides.task)\n        assert isinstance(overrides, list)\n        ret.overrides = overrides\n        # handle output directories here\n        Path(str(working_dir)).mkdir(parents=True, exist_ok=True)\n        os.chdir(working_dir)\n        hydra_output = Path(config.hydra.output_subdir)\n\n        configure_log(config.hydra.job_logging, config.hydra.verbose)\n\n        hydra_cfg = OmegaConf.masked_copy(config, \"hydra\")\n        assert isinstance(hydra_cfg, DictConfig)\n\n        _save_config(task_cfg, \"config.yaml\", hydra_output)\n        _save_config(hydra_cfg, \"hydra.yaml\", hydra_output)\n        _save_config(config.hydra.overrides.task, \"overrides.yaml\", hydra_output)\n        with env_override(hydra_cfg.hydra.job.env_set):\n            ret.return_value = task_function(task_cfg)\n        ret.task_name = JobRuntime.instance().get(\"name\")\n\n        # shut down logging to ensure job log files are closed.\n        # If logging is still required after run_job caller is responsible to re-initialize it.\n        logging.shutdown()\n\n        return ret\n    finally:\n        os.chdir(old_cwd)\n\n\ndef get_valid_filename(s: str) -> str:\n    s = str(s).strip().replace(\" \", \"_\")\n    return re.sub(r\"(?u)[^-\\w.]\", \"\", s)\n\n\ndef setup_globals() -> None:\n    try:\n        OmegaConf.register_resolver(\n            \"now\", lambda pattern: strftime(pattern, localtime())\n        )\n    except AssertionError:\n        # calling it again in no_workers mode will throw. safe to ignore.\n        pass\n\n\n@dataclass\nclass JobReturn:\n    overrides: Optional[Sequence[str]] = None\n    return_value: Any = None\n    cfg: Optional[DictConfig] = None\n    hydra_cfg: Optional[DictConfig] = None\n    working_dir: Optional[str] = None\n    task_name: Optional[str] = None\n\n\nclass JobRuntime(metaclass=Singleton):\n    def __init__(self) -> None:\n        self.conf: DictConfig = OmegaConf.create()\n        self.set(\"name\", \"UNKNOWN_NAME\")\n\n    def get(self, key: str) -> Any:\n        ret = OmegaConf.select(self.conf, key)\n        if ret is None:\n            raise KeyError(f\"Key not found in {type(self).__name__}: {key}\")\n        return ret\n\n    def set(self, key: str, value: Any) -> None:\n        log.debug(f\"Setting {type(self).__name__}:{key}={value}\")\n        self.conf[key] = value\n\n\ndef split_config_path(\n    config_path: Optional[str], config_name: Optional[str]\n) -> Tuple[Optional[str], Optional[str]]:\n    if config_path is None or config_path == \"\":\n        return None, config_name\n    split_file = splitext(config_path)\n    if split_file[1] in (\".yaml\", \".yml\"):\n        # assuming dir/config.yaml form\n        config_file: Optional[str] = basename(config_path)\n        config_dir: Optional[str] = dirname(config_path)\n        msg = (\n            \"\\nUsing config_path to specify the config name is deprecated, specify the config name via config_name\"\n            \"\\nSee https://hydra.cc/next/upgrades/0.11_to_1.0/config_path_changes\"\n        )\n        warnings.warn(\n            category=UserWarning, message=msg,\n        )\n    else:\n        # assuming dir form without a config file.\n        config_file = None\n        config_dir = config_path\n\n    if config_dir == \"\":\n        config_dir = None\n\n    if config_file == \"\":\n        config_file = None\n\n    if config_file is not None:\n        if config_name is not None:\n            raise ValueError(\n                \"Config name should be specified in either normalized_config_path or config_name, but not both\"\n            )\n        config_name = config_file\n\n    return config_dir, config_name\n\n\n@contextmanager\ndef env_override(env: Dict[str, str]) -> Any:\n    \"\"\"Temporarily set environment variables inside the context manager and\n    fully restore previous environment afterwards\n    \"\"\"\n    original_env = {key: os.getenv(key) for key in env}\n    os.environ.update(env)\n    try:\n        yield\n    finally:\n        for key, value in original_env.items():\n            if value is None:\n                del os.environ[key]\n            else:\n                os.environ[key] = value\n", "path": "hydra/core/utils.py"}, {"content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nfrom typing import Any, Optional\n\nfrom omegaconf import DictConfig, OmegaConf\n\nfrom hydra.conf import HydraConf\nfrom hydra.core.singleton import Singleton\n\n\nclass HydraConfig(metaclass=Singleton):\n    def __init__(self) -> None:\n        self.cfg: Optional[HydraConf] = None\n\n    def set_config(self, cfg: DictConfig) -> None:\n        assert cfg is not None\n        OmegaConf.set_readonly(cfg.hydra, True)\n        assert OmegaConf.get_type(cfg, \"hydra\") == HydraConf\n        self.cfg = cfg  # type: ignore\n\n    @staticmethod\n    def get() -> HydraConf:\n        instance = HydraConfig.instance()\n        if instance.cfg is None:\n            raise ValueError(\"HydraConfig was not set\")\n        return instance.cfg.hydra  # type: ignore\n\n    @staticmethod\n    def initialized() -> bool:\n        instance = HydraConfig.instance()\n        return instance.cfg is not None\n\n    @staticmethod\n    def instance(*args: Any, **kwargs: Any) -> \"HydraConfig\":\n        return Singleton.instance(HydraConfig, *args, **kwargs)  # type: ignore\n", "path": "hydra/core/hydra_config.py"}], "after_files": [{"content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nimport copy\nimport logging\nimport os\nimport re\nimport sys\nimport warnings\nfrom contextlib import contextmanager\nfrom dataclasses import dataclass\nfrom os.path import basename, dirname, splitext\nfrom pathlib import Path\nfrom time import localtime, strftime\nfrom typing import Any, Dict, Optional, Sequence, Tuple, Union, cast\n\nfrom omegaconf import DictConfig, OmegaConf, open_dict\n\nfrom hydra.core.hydra_config import HydraConfig\nfrom hydra.core.singleton import Singleton\nfrom hydra.types import TaskFunction\n\nlog = logging.getLogger(__name__)\n\n\ndef configure_log(\n    log_config: DictConfig, verbose_config: Union[bool, str, Sequence[str]]\n) -> None:\n    assert isinstance(verbose_config, (bool, str)) or OmegaConf.is_list(verbose_config)\n    if log_config is not None:\n        conf: Dict[str, Any] = OmegaConf.to_container(  # type: ignore\n            log_config, resolve=True\n        )\n        logging.config.dictConfig(conf)\n    else:\n        # default logging to stdout\n        root = logging.getLogger()\n        root.setLevel(logging.INFO)\n        handler = logging.StreamHandler(sys.stdout)\n        formatter = logging.Formatter(\n            \"[%(asctime)s][%(name)s][%(levelname)s] - %(message)s\"\n        )\n        handler.setFormatter(formatter)\n        root.addHandler(handler)\n    if isinstance(verbose_config, bool):\n        if verbose_config:\n            logging.getLogger().setLevel(logging.DEBUG)\n    else:\n        if isinstance(verbose_config, str):\n            verbose_list = OmegaConf.create([verbose_config])\n        elif OmegaConf.is_list(verbose_config):\n            verbose_list = verbose_config  # type: ignore\n        else:\n            assert False\n\n        for logger in verbose_list:\n            logging.getLogger(logger).setLevel(logging.DEBUG)\n\n\ndef _save_config(cfg: DictConfig, filename: str, output_dir: Path) -> None:\n    output_dir.mkdir(parents=True, exist_ok=True)\n    with open(str(output_dir / filename), \"w\") as file:\n        file.write(cfg.pretty())\n\n\ndef filter_overrides(overrides: Sequence[str]) -> Sequence[str]:\n    \"\"\"\n    :param overrides: overrides list\n    :return: returning a new overrides list with all the keys starting with hydra. filtered.\n    \"\"\"\n    return [x for x in overrides if not x.startswith(\"hydra.\")]\n\n\ndef run_job(\n    config: DictConfig,\n    task_function: TaskFunction,\n    job_dir_key: str,\n    job_subdir_key: Optional[str],\n) -> \"JobReturn\":\n    old_cwd = os.getcwd()\n    working_dir = str(OmegaConf.select(config, job_dir_key))\n    if job_subdir_key is not None:\n        # evaluate job_subdir_key lazily.\n        # this is running on the client side in sweep and contains things such as job:id which\n        # are only available there.\n        subdir = str(OmegaConf.select(config, job_subdir_key))\n        working_dir = os.path.join(working_dir, subdir)\n    try:\n        ret = JobReturn()\n        ret.working_dir = working_dir\n        task_cfg = copy.deepcopy(config)\n        with open_dict(task_cfg):\n            del task_cfg[\"hydra\"]\n        ret.cfg = task_cfg\n        ret.hydra_cfg = OmegaConf.create({\"hydra\": HydraConfig.get()})\n        overrides = OmegaConf.to_container(config.hydra.overrides.task)\n        assert isinstance(overrides, list)\n        ret.overrides = overrides\n        # handle output directories here\n        Path(str(working_dir)).mkdir(parents=True, exist_ok=True)\n        os.chdir(working_dir)\n        hydra_output = Path(config.hydra.output_subdir)\n\n        configure_log(config.hydra.job_logging, config.hydra.verbose)\n\n        hydra_cfg = OmegaConf.masked_copy(config, \"hydra\")\n        assert isinstance(hydra_cfg, DictConfig)\n\n        _save_config(task_cfg, \"config.yaml\", hydra_output)\n        _save_config(hydra_cfg, \"hydra.yaml\", hydra_output)\n        _save_config(config.hydra.overrides.task, \"overrides.yaml\", hydra_output)\n        with env_override(hydra_cfg.hydra.job.env_set):\n            ret.return_value = task_function(task_cfg)\n        ret.task_name = JobRuntime.instance().get(\"name\")\n\n        # shut down logging to ensure job log files are closed.\n        # If logging is still required after run_job caller is responsible to re-initialize it.\n        logging.shutdown()\n\n        return ret\n    finally:\n        os.chdir(old_cwd)\n\n\ndef get_valid_filename(s: str) -> str:\n    s = str(s).strip().replace(\" \", \"_\")\n    return re.sub(r\"(?u)[^-\\w.]\", \"\", s)\n\n\ndef setup_globals() -> None:\n    def register(name: str, f: Any) -> None:\n        try:\n            OmegaConf.register_resolver(name, f)\n        except AssertionError:\n            # calling it again in no_workers mode will throw. safe to ignore.\n            pass\n\n    register(\"now\", lambda pattern: strftime(pattern, localtime()))\n    register(\n        \"hydra\",\n        lambda path: OmegaConf.select(cast(DictConfig, HydraConfig.get()), path),\n    )\n\n\n@dataclass\nclass JobReturn:\n    overrides: Optional[Sequence[str]] = None\n    return_value: Any = None\n    cfg: Optional[DictConfig] = None\n    hydra_cfg: Optional[DictConfig] = None\n    working_dir: Optional[str] = None\n    task_name: Optional[str] = None\n\n\nclass JobRuntime(metaclass=Singleton):\n    def __init__(self) -> None:\n        self.conf: DictConfig = OmegaConf.create()\n        self.set(\"name\", \"UNKNOWN_NAME\")\n\n    def get(self, key: str) -> Any:\n        ret = OmegaConf.select(self.conf, key)\n        if ret is None:\n            raise KeyError(f\"Key not found in {type(self).__name__}: {key}\")\n        return ret\n\n    def set(self, key: str, value: Any) -> None:\n        log.debug(f\"Setting {type(self).__name__}:{key}={value}\")\n        self.conf[key] = value\n\n\ndef split_config_path(\n    config_path: Optional[str], config_name: Optional[str]\n) -> Tuple[Optional[str], Optional[str]]:\n    if config_path is None or config_path == \"\":\n        return None, config_name\n    split_file = splitext(config_path)\n    if split_file[1] in (\".yaml\", \".yml\"):\n        # assuming dir/config.yaml form\n        config_file: Optional[str] = basename(config_path)\n        config_dir: Optional[str] = dirname(config_path)\n        msg = (\n            \"\\nUsing config_path to specify the config name is deprecated, specify the config name via config_name\"\n            \"\\nSee https://hydra.cc/next/upgrades/0.11_to_1.0/config_path_changes\"\n        )\n        warnings.warn(\n            category=UserWarning, message=msg,\n        )\n    else:\n        # assuming dir form without a config file.\n        config_file = None\n        config_dir = config_path\n\n    if config_dir == \"\":\n        config_dir = None\n\n    if config_file == \"\":\n        config_file = None\n\n    if config_file is not None:\n        if config_name is not None:\n            raise ValueError(\n                \"Config name should be specified in either normalized_config_path or config_name, but not both\"\n            )\n        config_name = config_file\n\n    return config_dir, config_name\n\n\n@contextmanager\ndef env_override(env: Dict[str, str]) -> Any:\n    \"\"\"Temporarily set environment variables inside the context manager and\n    fully restore previous environment afterwards\n    \"\"\"\n    original_env = {key: os.getenv(key) for key in env}\n    os.environ.update(env)\n    try:\n        yield\n    finally:\n        for key, value in original_env.items():\n            if value is None:\n                del os.environ[key]\n            else:\n                os.environ[key] = value\n", "path": "hydra/core/utils.py"}, {"content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nfrom typing import Any, Optional\n\nfrom omegaconf import DictConfig, OmegaConf\n\nfrom hydra.conf import HydraConf\nfrom hydra.core.singleton import Singleton\n\n\nclass HydraConfig(metaclass=Singleton):\n    def __init__(self) -> None:\n        self.cfg: Optional[HydraConf] = None\n\n    def set_config(self, cfg: DictConfig) -> None:\n        assert cfg is not None\n        OmegaConf.set_readonly(cfg.hydra, True)\n        assert OmegaConf.get_type(cfg, \"hydra\") == HydraConf\n        self.cfg = OmegaConf.masked_copy(cfg, \"hydra\")  # type: ignore\n\n    @staticmethod\n    def get() -> HydraConf:\n        instance = HydraConfig.instance()\n        if instance.cfg is None:\n            raise ValueError(\"HydraConfig was not set\")\n        return instance.cfg.hydra  # type: ignore\n\n    @staticmethod\n    def initialized() -> bool:\n        instance = HydraConfig.instance()\n        return instance.cfg is not None\n\n    @staticmethod\n    def instance(*args: Any, **kwargs: Any) -> \"HydraConfig\":\n        return Singleton.instance(HydraConfig, *args, **kwargs)  # type: ignore\n", "path": "hydra/core/hydra_config.py"}]}