We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[Bug] Link to upgrade guide crashes documentation site
In `hydra-core==1.2.0dev5`, `basic_launcher` produces the following warning:
```    
/home/runner/work/hydra-zen/hydra-zen/.tox/pre-release/lib/python3.8/site-packages/hydra/_internal/core_plugins
/basic_launcher.py:74: 

UserWarning: Future Hydra versions will no longer change working directory at job runtime by default.
    See https://hydra.cc/docs/upgrades/1.1_to_1.2/changes_to_job_working_dir for more information.
```

But following the provided URL, https://hydra.cc/docs/upgrades/1.1_to_1.2/changes_to_job_working_dir , leads to a crash in the docs site:

![image](https://user-images.githubusercontent.com/29104956/164014834-2884356a-bca0-4f37-a787-d4a8829dcbf9.png)

--- 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 from contextlib import contextmanager
8 from dataclasses import dataclass
9 from datetime import datetime
10 from enum import Enum
11 from os.path import splitext
12 from pathlib import Path
13 from textwrap import dedent
14 from typing import Any, Dict, Optional, Sequence, Union, cast
15 
16 from omegaconf import DictConfig, OmegaConf, open_dict, read_write
17 
18 from hydra import version
19 from hydra._internal.deprecation_warning import deprecation_warning
20 from hydra.core.hydra_config import HydraConfig
21 from hydra.core.singleton import Singleton
22 from hydra.types import HydraContext, TaskFunction
23 
24 log = logging.getLogger(__name__)
25 
26 
27 def simple_stdout_log_config(level: int = logging.INFO) -> None:
28     root = logging.getLogger()
29     root.setLevel(level)
30     handler = logging.StreamHandler(sys.stdout)
31     formatter = logging.Formatter("%(message)s")
32     handler.setFormatter(formatter)
33     root.addHandler(handler)
34 
35 
36 def configure_log(
37     log_config: DictConfig,
38     verbose_config: Union[bool, str, Sequence[str]] = False,
39 ) -> None:
40     assert isinstance(verbose_config, (bool, str)) or OmegaConf.is_list(verbose_config)
41     if log_config is not None:
42         conf: Dict[str, Any] = OmegaConf.to_container(  # type: ignore
43             log_config, resolve=True
44         )
45         if conf["root"] is not None:
46             logging.config.dictConfig(conf)
47     else:
48         # default logging to stdout
49         root = logging.getLogger()
50         root.setLevel(logging.INFO)
51         handler = logging.StreamHandler(sys.stdout)
52         formatter = logging.Formatter(
53             "[%(asctime)s][%(name)s][%(levelname)s] - %(message)s"
54         )
55         handler.setFormatter(formatter)
56         root.addHandler(handler)
57     if isinstance(verbose_config, bool):
58         if verbose_config:
59             logging.getLogger().setLevel(logging.DEBUG)
60     else:
61         if isinstance(verbose_config, str):
62             verbose_list = OmegaConf.create([verbose_config])
63         elif OmegaConf.is_list(verbose_config):
64             verbose_list = verbose_config  # type: ignore
65         else:
66             assert False
67 
68         for logger in verbose_list:
69             logging.getLogger(logger).setLevel(logging.DEBUG)
70 
71 
72 def _save_config(cfg: DictConfig, filename: str, output_dir: Path) -> None:
73     output_dir.mkdir(parents=True, exist_ok=True)
74     with open(str(output_dir / filename), "w", encoding="utf-8") as file:
75         file.write(OmegaConf.to_yaml(cfg))
76 
77 
78 def filter_overrides(overrides: Sequence[str]) -> Sequence[str]:
79     """
80     :param overrides: overrides list
81     :return: returning a new overrides list with all the keys starting with hydra. filtered.
82     """
83     return [x for x in overrides if not x.startswith("hydra.")]
84 
85 
86 def _check_hydra_context(hydra_context: Optional[HydraContext]) -> None:
87     if hydra_context is None:
88         # hydra_context is required as of Hydra 1.2.
89         # We can remove this check in Hydra 1.3.
90         raise TypeError(
91             dedent(
92                 """
93                 run_job's signature has changed: the `hydra_context` arg is now required.
94                 For more info, check https://github.com/facebookresearch/hydra/pull/1581."""
95             ),
96         )
97 
98 
99 def run_job(
100     task_function: TaskFunction,
101     config: DictConfig,
102     job_dir_key: str,
103     job_subdir_key: Optional[str],
104     hydra_context: HydraContext,
105     configure_logging: bool = True,
106 ) -> "JobReturn":
107     _check_hydra_context(hydra_context)
108     callbacks = hydra_context.callbacks
109 
110     old_cwd = os.getcwd()
111     orig_hydra_cfg = HydraConfig.instance().cfg
112 
113     # init Hydra config for config evaluation
114     HydraConfig.instance().set_config(config)
115 
116     output_dir = str(OmegaConf.select(config, job_dir_key))
117     if job_subdir_key is not None:
118         # evaluate job_subdir_key lazily.
119         # this is running on the client side in sweep and contains things such as job:id which
120         # are only available there.
121         subdir = str(OmegaConf.select(config, job_subdir_key))
122         output_dir = os.path.join(output_dir, subdir)
123 
124     with read_write(config.hydra.runtime):
125         with open_dict(config.hydra.runtime):
126             config.hydra.runtime.output_dir = os.path.abspath(output_dir)
127 
128     # update Hydra config
129     HydraConfig.instance().set_config(config)
130     _chdir = None
131     try:
132         ret = JobReturn()
133         task_cfg = copy.deepcopy(config)
134         with read_write(task_cfg):
135             with open_dict(task_cfg):
136                 del task_cfg["hydra"]
137 
138         ret.cfg = task_cfg
139         hydra_cfg = copy.deepcopy(HydraConfig.instance().cfg)
140         assert isinstance(hydra_cfg, DictConfig)
141         ret.hydra_cfg = hydra_cfg
142         overrides = OmegaConf.to_container(config.hydra.overrides.task)
143         assert isinstance(overrides, list)
144         ret.overrides = overrides
145         # handle output directories here
146         Path(str(output_dir)).mkdir(parents=True, exist_ok=True)
147 
148         _chdir = hydra_cfg.hydra.job.chdir
149 
150         if _chdir is None:
151             if version.base_at_least("1.2"):
152                 _chdir = False
153 
154         if _chdir is None:
155             url = "https://hydra.cc/docs/upgrades/1.1_to_1.2/changes_to_job_working_dir"
156             deprecation_warning(
157                 message=dedent(
158                     f"""\
159                     Future Hydra versions will no longer change working directory at job runtime by default.
160                     See {url} for more information."""
161                 ),
162                 stacklevel=2,
163             )
164             _chdir = True
165 
166         if _chdir:
167             os.chdir(output_dir)
168             ret.working_dir = output_dir
169         else:
170             ret.working_dir = os.getcwd()
171 
172         if configure_logging:
173             configure_log(config.hydra.job_logging, config.hydra.verbose)
174 
175         if config.hydra.output_subdir is not None:
176             hydra_output = Path(config.hydra.runtime.output_dir) / Path(
177                 config.hydra.output_subdir
178             )
179             _save_config(task_cfg, "config.yaml", hydra_output)
180             _save_config(hydra_cfg, "hydra.yaml", hydra_output)
181             _save_config(config.hydra.overrides.task, "overrides.yaml", hydra_output)
182 
183         with env_override(hydra_cfg.hydra.job.env_set):
184             callbacks.on_job_start(config=config)
185             try:
186                 ret.return_value = task_function(task_cfg)
187                 ret.status = JobStatus.COMPLETED
188             except Exception as e:
189                 ret.return_value = e
190                 ret.status = JobStatus.FAILED
191 
192         ret.task_name = JobRuntime.instance().get("name")
193 
194         _flush_loggers()
195 
196         callbacks.on_job_end(config=config, job_return=ret)
197 
198         return ret
199     finally:
200         HydraConfig.instance().cfg = orig_hydra_cfg
201         if _chdir:
202             os.chdir(old_cwd)
203 
204 
205 def get_valid_filename(s: str) -> str:
206     s = str(s).strip().replace(" ", "_")
207     return re.sub(r"(?u)[^-\w.]", "", s)
208 
209 
210 def setup_globals() -> None:
211     # please add documentation when you add a new resolver
212     OmegaConf.register_new_resolver(
213         "now",
214         lambda pattern: datetime.now().strftime(pattern),
215         use_cache=True,
216         replace=True,
217     )
218     OmegaConf.register_new_resolver(
219         "hydra",
220         lambda path: OmegaConf.select(cast(DictConfig, HydraConfig.get()), path),
221         replace=True,
222     )
223 
224     vi = sys.version_info
225     version_dict = {
226         "major": f"{vi[0]}",
227         "minor": f"{vi[0]}.{vi[1]}",
228         "micro": f"{vi[0]}.{vi[1]}.{vi[2]}",
229     }
230     OmegaConf.register_new_resolver(
231         "python_version", lambda level="minor": version_dict.get(level), replace=True
232     )
233 
234 
235 class JobStatus(Enum):
236     UNKNOWN = 0
237     COMPLETED = 1
238     FAILED = 2
239 
240 
241 @dataclass
242 class JobReturn:
243     overrides: Optional[Sequence[str]] = None
244     cfg: Optional[DictConfig] = None
245     hydra_cfg: Optional[DictConfig] = None
246     working_dir: Optional[str] = None
247     task_name: Optional[str] = None
248     status: JobStatus = JobStatus.UNKNOWN
249     _return_value: Any = None
250 
251     @property
252     def return_value(self) -> Any:
253         assert self.status != JobStatus.UNKNOWN, "return_value not yet available"
254         if self.status == JobStatus.COMPLETED:
255             return self._return_value
256         else:
257             sys.stderr.write(
258                 f"Error executing job with overrides: {self.overrides}" + os.linesep
259             )
260             raise self._return_value
261 
262     @return_value.setter
263     def return_value(self, value: Any) -> None:
264         self._return_value = value
265 
266 
267 class JobRuntime(metaclass=Singleton):
268     def __init__(self) -> None:
269         self.conf: DictConfig = OmegaConf.create()
270         self.set("name", "UNKNOWN_NAME")
271 
272     def get(self, key: str) -> Any:
273         ret = OmegaConf.select(self.conf, key)
274         if ret is None:
275             raise KeyError(f"Key not found in {type(self).__name__}: {key}")
276         return ret
277 
278     def set(self, key: str, value: Any) -> None:
279         log.debug(f"Setting {type(self).__name__}:{key}={value}")
280         self.conf[key] = value
281 
282 
283 def validate_config_path(config_path: Optional[str]) -> None:
284     if config_path is not None:
285         split_file = splitext(config_path)
286         if split_file[1] in (".yaml", ".yml"):
287             msg = dedent(
288                 """\
289             Using config_path to specify the config name is not supported, specify the config name via config_name.
290             See https://hydra.cc/docs/next/upgrades/0.11_to_1.0/config_path_changes
291             """
292             )
293             raise ValueError(msg)
294 
295 
296 @contextmanager
297 def env_override(env: Dict[str, str]) -> Any:
298     """Temporarily set environment variables inside the context manager and
299     fully restore previous environment afterwards
300     """
301     original_env = {key: os.getenv(key) for key in env}
302     os.environ.update(env)
303     try:
304         yield
305     finally:
306         for key, value in original_env.items():
307             if value is None:
308                 del os.environ[key]
309             else:
310                 os.environ[key] = value
311 
312 
313 def _flush_loggers() -> None:
314     # Python logging does not have an official API to flush all loggers.
315     # This will have to do.
316     for h_weak_ref in logging._handlerList:  # type: ignore
317         try:
318             h_weak_ref().flush()
319         except Exception:
320             # ignore exceptions thrown during flushing
321             pass
322
```
--- 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/utils.py b/hydra/core/utils.py
--- a/hydra/core/utils.py
+++ b/hydra/core/utils.py
@@ -152,7 +152,7 @@
                 _chdir = False
 
         if _chdir is None:
-            url = "https://hydra.cc/docs/upgrades/1.1_to_1.2/changes_to_job_working_dir"
+            url = "https://hydra.cc/docs/next/upgrades/1.1_to_1.2/changes_to_job_working_dir/"
             deprecation_warning(
                 message=dedent(
                     f"""\

{"golden_diff": "diff --git a/hydra/core/utils.py b/hydra/core/utils.py\n--- a/hydra/core/utils.py\n+++ b/hydra/core/utils.py\n@@ -152,7 +152,7 @@\n                 _chdir = False\n \n         if _chdir is None:\n-            url = \"https://hydra.cc/docs/upgrades/1.1_to_1.2/changes_to_job_working_dir\"\n+            url = \"https://hydra.cc/docs/next/upgrades/1.1_to_1.2/changes_to_job_working_dir/\"\n             deprecation_warning(\n                 message=dedent(\n                     f\"\"\"\\\n", "issue": "[Bug] Link to upgrade guide crashes documentation site\nIn `hydra-core==1.2.0dev5`, `basic_launcher` produces the following warning:\r\n```    \r\n/home/runner/work/hydra-zen/hydra-zen/.tox/pre-release/lib/python3.8/site-packages/hydra/_internal/core_plugins\r\n/basic_launcher.py:74: \r\n\r\nUserWarning: Future Hydra versions will no longer change working directory at job runtime by default.\r\n    See https://hydra.cc/docs/upgrades/1.1_to_1.2/changes_to_job_working_dir for more information.\r\n```\r\n\r\nBut following the provided URL, https://hydra.cc/docs/upgrades/1.1_to_1.2/changes_to_job_working_dir , leads to a crash in the docs site:\r\n\r\n![image](https://user-images.githubusercontent.com/29104956/164014834-2884356a-bca0-4f37-a787-d4a8829dcbf9.png)\n", "before_files": [{"content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nimport copy\nimport logging\nimport os\nimport re\nimport sys\nfrom contextlib import contextmanager\nfrom dataclasses import dataclass\nfrom datetime import datetime\nfrom enum import Enum\nfrom os.path import splitext\nfrom pathlib import Path\nfrom textwrap import dedent\nfrom typing import Any, Dict, Optional, Sequence, Union, cast\n\nfrom omegaconf import DictConfig, OmegaConf, open_dict, read_write\n\nfrom hydra import version\nfrom hydra._internal.deprecation_warning import deprecation_warning\nfrom hydra.core.hydra_config import HydraConfig\nfrom hydra.core.singleton import Singleton\nfrom hydra.types import HydraContext, TaskFunction\n\nlog = logging.getLogger(__name__)\n\n\ndef simple_stdout_log_config(level: int = logging.INFO) -> None:\n    root = logging.getLogger()\n    root.setLevel(level)\n    handler = logging.StreamHandler(sys.stdout)\n    formatter = logging.Formatter(\"%(message)s\")\n    handler.setFormatter(formatter)\n    root.addHandler(handler)\n\n\ndef configure_log(\n    log_config: DictConfig,\n    verbose_config: Union[bool, str, Sequence[str]] = False,\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        if conf[\"root\"] is not None:\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\", encoding=\"utf-8\") as file:\n        file.write(OmegaConf.to_yaml(cfg))\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 _check_hydra_context(hydra_context: Optional[HydraContext]) -> None:\n    if hydra_context is None:\n        # hydra_context is required as of Hydra 1.2.\n        # We can remove this check in Hydra 1.3.\n        raise TypeError(\n            dedent(\n                \"\"\"\n                run_job's signature has changed: the `hydra_context` arg is now required.\n                For more info, check https://github.com/facebookresearch/hydra/pull/1581.\"\"\"\n            ),\n        )\n\n\ndef run_job(\n    task_function: TaskFunction,\n    config: DictConfig,\n    job_dir_key: str,\n    job_subdir_key: Optional[str],\n    hydra_context: HydraContext,\n    configure_logging: bool = True,\n) -> \"JobReturn\":\n    _check_hydra_context(hydra_context)\n    callbacks = hydra_context.callbacks\n\n    old_cwd = os.getcwd()\n    orig_hydra_cfg = HydraConfig.instance().cfg\n\n    # init Hydra config for config evaluation\n    HydraConfig.instance().set_config(config)\n\n    output_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        output_dir = os.path.join(output_dir, subdir)\n\n    with read_write(config.hydra.runtime):\n        with open_dict(config.hydra.runtime):\n            config.hydra.runtime.output_dir = os.path.abspath(output_dir)\n\n    # update Hydra config\n    HydraConfig.instance().set_config(config)\n    _chdir = None\n    try:\n        ret = JobReturn()\n        task_cfg = copy.deepcopy(config)\n        with read_write(task_cfg):\n            with open_dict(task_cfg):\n                del task_cfg[\"hydra\"]\n\n        ret.cfg = task_cfg\n        hydra_cfg = copy.deepcopy(HydraConfig.instance().cfg)\n        assert isinstance(hydra_cfg, DictConfig)\n        ret.hydra_cfg = hydra_cfg\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(output_dir)).mkdir(parents=True, exist_ok=True)\n\n        _chdir = hydra_cfg.hydra.job.chdir\n\n        if _chdir is None:\n            if version.base_at_least(\"1.2\"):\n                _chdir = False\n\n        if _chdir is None:\n            url = \"https://hydra.cc/docs/upgrades/1.1_to_1.2/changes_to_job_working_dir\"\n            deprecation_warning(\n                message=dedent(\n                    f\"\"\"\\\n                    Future Hydra versions will no longer change working directory at job runtime by default.\n                    See {url} for more information.\"\"\"\n                ),\n                stacklevel=2,\n            )\n            _chdir = True\n\n        if _chdir:\n            os.chdir(output_dir)\n            ret.working_dir = output_dir\n        else:\n            ret.working_dir = os.getcwd()\n\n        if configure_logging:\n            configure_log(config.hydra.job_logging, config.hydra.verbose)\n\n        if config.hydra.output_subdir is not None:\n            hydra_output = Path(config.hydra.runtime.output_dir) / Path(\n                config.hydra.output_subdir\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\n        with env_override(hydra_cfg.hydra.job.env_set):\n            callbacks.on_job_start(config=config)\n            try:\n                ret.return_value = task_function(task_cfg)\n                ret.status = JobStatus.COMPLETED\n            except Exception as e:\n                ret.return_value = e\n                ret.status = JobStatus.FAILED\n\n        ret.task_name = JobRuntime.instance().get(\"name\")\n\n        _flush_loggers()\n\n        callbacks.on_job_end(config=config, job_return=ret)\n\n        return ret\n    finally:\n        HydraConfig.instance().cfg = orig_hydra_cfg\n        if _chdir:\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    # please add documentation when you add a new resolver\n    OmegaConf.register_new_resolver(\n        \"now\",\n        lambda pattern: datetime.now().strftime(pattern),\n        use_cache=True,\n        replace=True,\n    )\n    OmegaConf.register_new_resolver(\n        \"hydra\",\n        lambda path: OmegaConf.select(cast(DictConfig, HydraConfig.get()), path),\n        replace=True,\n    )\n\n    vi = sys.version_info\n    version_dict = {\n        \"major\": f\"{vi[0]}\",\n        \"minor\": f\"{vi[0]}.{vi[1]}\",\n        \"micro\": f\"{vi[0]}.{vi[1]}.{vi[2]}\",\n    }\n    OmegaConf.register_new_resolver(\n        \"python_version\", lambda level=\"minor\": version_dict.get(level), replace=True\n    )\n\n\nclass JobStatus(Enum):\n    UNKNOWN = 0\n    COMPLETED = 1\n    FAILED = 2\n\n\n@dataclass\nclass JobReturn:\n    overrides: Optional[Sequence[str]] = 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    status: JobStatus = JobStatus.UNKNOWN\n    _return_value: Any = None\n\n    @property\n    def return_value(self) -> Any:\n        assert self.status != JobStatus.UNKNOWN, \"return_value not yet available\"\n        if self.status == JobStatus.COMPLETED:\n            return self._return_value\n        else:\n            sys.stderr.write(\n                f\"Error executing job with overrides: {self.overrides}\" + os.linesep\n            )\n            raise self._return_value\n\n    @return_value.setter\n    def return_value(self, value: Any) -> None:\n        self._return_value = value\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 validate_config_path(config_path: Optional[str]) -> None:\n    if config_path is not None:\n        split_file = splitext(config_path)\n        if split_file[1] in (\".yaml\", \".yml\"):\n            msg = dedent(\n                \"\"\"\\\n            Using config_path to specify the config name is not supported, specify the config name via config_name.\n            See https://hydra.cc/docs/next/upgrades/0.11_to_1.0/config_path_changes\n            \"\"\"\n            )\n            raise ValueError(msg)\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\n\ndef _flush_loggers() -> None:\n    # Python logging does not have an official API to flush all loggers.\n    # This will have to do.\n    for h_weak_ref in logging._handlerList:  # type: ignore\n        try:\n            h_weak_ref().flush()\n        except Exception:\n            # ignore exceptions thrown during flushing\n            pass\n", "path": "hydra/core/utils.py"}], "after_files": [{"content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nimport copy\nimport logging\nimport os\nimport re\nimport sys\nfrom contextlib import contextmanager\nfrom dataclasses import dataclass\nfrom datetime import datetime\nfrom enum import Enum\nfrom os.path import splitext\nfrom pathlib import Path\nfrom textwrap import dedent\nfrom typing import Any, Dict, Optional, Sequence, Union, cast\n\nfrom omegaconf import DictConfig, OmegaConf, open_dict, read_write\n\nfrom hydra import version\nfrom hydra._internal.deprecation_warning import deprecation_warning\nfrom hydra.core.hydra_config import HydraConfig\nfrom hydra.core.singleton import Singleton\nfrom hydra.types import HydraContext, TaskFunction\n\nlog = logging.getLogger(__name__)\n\n\ndef simple_stdout_log_config(level: int = logging.INFO) -> None:\n    root = logging.getLogger()\n    root.setLevel(level)\n    handler = logging.StreamHandler(sys.stdout)\n    formatter = logging.Formatter(\"%(message)s\")\n    handler.setFormatter(formatter)\n    root.addHandler(handler)\n\n\ndef configure_log(\n    log_config: DictConfig,\n    verbose_config: Union[bool, str, Sequence[str]] = False,\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        if conf[\"root\"] is not None:\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\", encoding=\"utf-8\") as file:\n        file.write(OmegaConf.to_yaml(cfg))\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 _check_hydra_context(hydra_context: Optional[HydraContext]) -> None:\n    if hydra_context is None:\n        # hydra_context is required as of Hydra 1.2.\n        # We can remove this check in Hydra 1.3.\n        raise TypeError(\n            dedent(\n                \"\"\"\n                run_job's signature has changed: the `hydra_context` arg is now required.\n                For more info, check https://github.com/facebookresearch/hydra/pull/1581.\"\"\"\n            ),\n        )\n\n\ndef run_job(\n    task_function: TaskFunction,\n    config: DictConfig,\n    job_dir_key: str,\n    job_subdir_key: Optional[str],\n    hydra_context: HydraContext,\n    configure_logging: bool = True,\n) -> \"JobReturn\":\n    _check_hydra_context(hydra_context)\n    callbacks = hydra_context.callbacks\n\n    old_cwd = os.getcwd()\n    orig_hydra_cfg = HydraConfig.instance().cfg\n\n    # init Hydra config for config evaluation\n    HydraConfig.instance().set_config(config)\n\n    output_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        output_dir = os.path.join(output_dir, subdir)\n\n    with read_write(config.hydra.runtime):\n        with open_dict(config.hydra.runtime):\n            config.hydra.runtime.output_dir = os.path.abspath(output_dir)\n\n    # update Hydra config\n    HydraConfig.instance().set_config(config)\n    _chdir = None\n    try:\n        ret = JobReturn()\n        task_cfg = copy.deepcopy(config)\n        with read_write(task_cfg):\n            with open_dict(task_cfg):\n                del task_cfg[\"hydra\"]\n\n        ret.cfg = task_cfg\n        hydra_cfg = copy.deepcopy(HydraConfig.instance().cfg)\n        assert isinstance(hydra_cfg, DictConfig)\n        ret.hydra_cfg = hydra_cfg\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(output_dir)).mkdir(parents=True, exist_ok=True)\n\n        _chdir = hydra_cfg.hydra.job.chdir\n\n        if _chdir is None:\n            if version.base_at_least(\"1.2\"):\n                _chdir = False\n\n        if _chdir is None:\n            url = \"https://hydra.cc/docs/next/upgrades/1.1_to_1.2/changes_to_job_working_dir/\"\n            deprecation_warning(\n                message=dedent(\n                    f\"\"\"\\\n                    Future Hydra versions will no longer change working directory at job runtime by default.\n                    See {url} for more information.\"\"\"\n                ),\n                stacklevel=2,\n            )\n            _chdir = True\n\n        if _chdir:\n            os.chdir(output_dir)\n            ret.working_dir = output_dir\n        else:\n            ret.working_dir = os.getcwd()\n\n        if configure_logging:\n            configure_log(config.hydra.job_logging, config.hydra.verbose)\n\n        if config.hydra.output_subdir is not None:\n            hydra_output = Path(config.hydra.runtime.output_dir) / Path(\n                config.hydra.output_subdir\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\n        with env_override(hydra_cfg.hydra.job.env_set):\n            callbacks.on_job_start(config=config)\n            try:\n                ret.return_value = task_function(task_cfg)\n                ret.status = JobStatus.COMPLETED\n            except Exception as e:\n                ret.return_value = e\n                ret.status = JobStatus.FAILED\n\n        ret.task_name = JobRuntime.instance().get(\"name\")\n\n        _flush_loggers()\n\n        callbacks.on_job_end(config=config, job_return=ret)\n\n        return ret\n    finally:\n        HydraConfig.instance().cfg = orig_hydra_cfg\n        if _chdir:\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    # please add documentation when you add a new resolver\n    OmegaConf.register_new_resolver(\n        \"now\",\n        lambda pattern: datetime.now().strftime(pattern),\n        use_cache=True,\n        replace=True,\n    )\n    OmegaConf.register_new_resolver(\n        \"hydra\",\n        lambda path: OmegaConf.select(cast(DictConfig, HydraConfig.get()), path),\n        replace=True,\n    )\n\n    vi = sys.version_info\n    version_dict = {\n        \"major\": f\"{vi[0]}\",\n        \"minor\": f\"{vi[0]}.{vi[1]}\",\n        \"micro\": f\"{vi[0]}.{vi[1]}.{vi[2]}\",\n    }\n    OmegaConf.register_new_resolver(\n        \"python_version\", lambda level=\"minor\": version_dict.get(level), replace=True\n    )\n\n\nclass JobStatus(Enum):\n    UNKNOWN = 0\n    COMPLETED = 1\n    FAILED = 2\n\n\n@dataclass\nclass JobReturn:\n    overrides: Optional[Sequence[str]] = 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    status: JobStatus = JobStatus.UNKNOWN\n    _return_value: Any = None\n\n    @property\n    def return_value(self) -> Any:\n        assert self.status != JobStatus.UNKNOWN, \"return_value not yet available\"\n        if self.status == JobStatus.COMPLETED:\n            return self._return_value\n        else:\n            sys.stderr.write(\n                f\"Error executing job with overrides: {self.overrides}\" + os.linesep\n            )\n            raise self._return_value\n\n    @return_value.setter\n    def return_value(self, value: Any) -> None:\n        self._return_value = value\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 validate_config_path(config_path: Optional[str]) -> None:\n    if config_path is not None:\n        split_file = splitext(config_path)\n        if split_file[1] in (\".yaml\", \".yml\"):\n            msg = dedent(\n                \"\"\"\\\n            Using config_path to specify the config name is not supported, specify the config name via config_name.\n            See https://hydra.cc/docs/next/upgrades/0.11_to_1.0/config_path_changes\n            \"\"\"\n            )\n            raise ValueError(msg)\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\n\ndef _flush_loggers() -> None:\n    # Python logging does not have an official API to flush all loggers.\n    # This will have to do.\n    for h_weak_ref in logging._handlerList:  # type: ignore\n        try:\n            h_weak_ref().flush()\n        except Exception:\n            # ignore exceptions thrown during flushing\n            pass\n", "path": "hydra/core/utils.py"}]}