prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Add TOML support for metrics
  Right now, there is only TOML file support for params files. We need to add TOML support for metrics as well.
  
  Here's a [link to the Discord question](https://discord.com/channels/485586884165107732/485596304961962003/865974923079319563) that brought this up.
  
  </issue>
  <code>
  [start of dvc/repo/metrics/show.py]
  1 import logging
  2 import os
  3 from typing import List
  4 
  5 from scmrepo.exceptions import SCMError
  6 
  7 from dvc.fs.dvc import DvcFileSystem
  8 from dvc.output import Output
  9 from dvc.repo import locked
  10 from dvc.repo.collect import StrPaths, collect
  11 from dvc.repo.live import summary_fs_path
  12 from dvc.scm import NoSCMError
  13 from dvc.utils import error_handler, errored_revisions, onerror_collect
  14 from dvc.utils.collections import ensure_list
  15 from dvc.utils.serialize import load_yaml
  16 
  17 logger = logging.getLogger(__name__)
  18 
  19 
  20 def _is_metric(out: Output) -> bool:
  21     return bool(out.metric) or bool(out.live)
  22 
  23 
  24 def _to_fs_paths(metrics: List[Output]) -> StrPaths:
  25     result = []
  26     for out in metrics:
  27         if out.metric:
  28             result.append(out.repo.dvcfs.from_os_path(out.fs_path))
  29         elif out.live:
  30             fs_path = summary_fs_path(out)
  31             if fs_path:
  32                 result.append(out.repo.dvcfs.from_os_path(fs_path))
  33     return result
  34 
  35 
  36 def _collect_metrics(repo, targets, revision, recursive):
  37     metrics, fs_paths = collect(
  38         repo,
  39         targets=targets,
  40         output_filter=_is_metric,
  41         recursive=recursive,
  42         rev=revision,
  43     )
  44     return _to_fs_paths(metrics) + list(fs_paths)
  45 
  46 
  47 def _extract_metrics(metrics, path, rev):
  48     if isinstance(metrics, (int, float)):
  49         return metrics
  50 
  51     if not isinstance(metrics, dict):
  52         return None
  53 
  54     ret = {}
  55     for key, val in metrics.items():
  56         m = _extract_metrics(val, path, rev)
  57         if m not in (None, {}):
  58             ret[key] = m
  59         else:
  60             logger.debug(
  61                 "Could not parse '%s' metric from '%s' at '%s' "
  62                 "due to its unsupported type: '%s'",
  63                 key,
  64                 path,
  65                 rev,
  66                 type(val).__name__,
  67             )
  68 
  69     return ret
  70 
  71 
  72 @error_handler
  73 def _read_metric(path, fs, rev, **kwargs):
  74     val = load_yaml(path, fs=fs)
  75     val = _extract_metrics(val, path, rev)
  76     return val or {}
  77 
  78 
  79 def _read_metrics(repo, metrics, rev, onerror=None):
  80     fs = DvcFileSystem(repo=repo)
  81 
  82     relpath = ""
  83     if repo.root_dir != repo.fs.path.getcwd():
  84         relpath = repo.fs.path.relpath(repo.root_dir, repo.fs.path.getcwd())
  85 
  86     res = {}
  87     for metric in metrics:
  88         if not fs.isfile(metric):
  89             continue
  90 
  91         res[os.path.join(relpath, *fs.path.parts(metric))] = _read_metric(
  92             metric, fs, rev, onerror=onerror
  93         )
  94 
  95     return res
  96 
  97 
  98 def _gather_metrics(repo, targets, rev, recursive, onerror=None):
  99     metrics = _collect_metrics(repo, targets, rev, recursive)
  100     return _read_metrics(repo, metrics, rev, onerror=onerror)
  101 
  102 
  103 @locked
  104 def show(
  105     repo,
  106     targets=None,
  107     all_branches=False,
  108     all_tags=False,
  109     recursive=False,
  110     revs=None,
  111     all_commits=False,
  112     onerror=None,
  113 ):
  114     if onerror is None:
  115         onerror = onerror_collect
  116 
  117     targets = ensure_list(targets)
  118     targets = [repo.dvcfs.from_os_path(target) for target in targets]
  119 
  120     res = {}
  121     for rev in repo.brancher(
  122         revs=revs,
  123         all_branches=all_branches,
  124         all_tags=all_tags,
  125         all_commits=all_commits,
  126     ):
  127         res[rev] = error_handler(_gather_metrics)(
  128             repo, targets, rev, recursive, onerror=onerror
  129         )
  130 
  131     # Hide workspace metrics if they are the same as in the active branch
  132     try:
  133         active_branch = repo.scm.active_branch()
  134     except (SCMError, NoSCMError):
  135         # SCMError - detached head
  136         # NoSCMError - no repo case
  137         pass
  138     else:
  139         if res.get("workspace") == res.get(active_branch):
  140             res.pop("workspace", None)
  141 
  142     errored = errored_revisions(res)
  143     if errored:
  144         from dvc.ui import ui
  145 
  146         ui.error_write(
  147             "DVC failed to load some metrics for following revisions:"
  148             f" '{', '.join(errored)}'."
  149         )
  150 
  151     return res
  152
  [end of dvc/repo/metrics/show.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/dvc/repo/metrics/show.py b/dvc/repo/metrics/show.py
  --- a/dvc/repo/metrics/show.py
  +++ b/dvc/repo/metrics/show.py
  @@ -12,7 +12,7 @@
   from dvc.scm import NoSCMError
   from dvc.utils import error_handler, errored_revisions, onerror_collect
   from dvc.utils.collections import ensure_list
  -from dvc.utils.serialize import load_yaml
  +from dvc.utils.serialize import LOADERS
   
   logger = logging.getLogger(__name__)
   
  @@ -71,7 +71,9 @@
   
   @error_handler
   def _read_metric(path, fs, rev, **kwargs):
  -    val = load_yaml(path, fs=fs)
  +    suffix = fs.path.suffix(path).lower()
  +    loader = LOADERS[suffix]
  +    val = loader(path, fs=fs)
       val = _extract_metrics(val, path, rev)
       return val or {}
  
verification_info: {"golden_diff": "diff --git a/dvc/repo/metrics/show.py b/dvc/repo/metrics/show.py\n--- a/dvc/repo/metrics/show.py\n+++ b/dvc/repo/metrics/show.py\n@@ -12,7 +12,7 @@\n from dvc.scm import NoSCMError\n from dvc.utils import error_handler, errored_revisions, onerror_collect\n from dvc.utils.collections import ensure_list\n-from dvc.utils.serialize import load_yaml\n+from dvc.utils.serialize import LOADERS\n \n logger = logging.getLogger(__name__)\n \n@@ -71,7 +71,9 @@\n \n @error_handler\n def _read_metric(path, fs, rev, **kwargs):\n-    val = load_yaml(path, fs=fs)\n+    suffix = fs.path.suffix(path).lower()\n+    loader = LOADERS[suffix]\n+    val = loader(path, fs=fs)\n     val = _extract_metrics(val, path, rev)\n     return val or {}\n", "issue": "Add TOML support for metrics\nRight now, there is only TOML file support for params files. We need to add TOML support for metrics as well.\r\n\r\nHere's a [link to the Discord question](https://discord.com/channels/485586884165107732/485596304961962003/865974923079319563) that brought this up.\n", "before_files": [{"content": "import logging\nimport os\nfrom typing import List\n\nfrom scmrepo.exceptions import SCMError\n\nfrom dvc.fs.dvc import DvcFileSystem\nfrom dvc.output import Output\nfrom dvc.repo import locked\nfrom dvc.repo.collect import StrPaths, collect\nfrom dvc.repo.live import summary_fs_path\nfrom dvc.scm import NoSCMError\nfrom dvc.utils import error_handler, errored_revisions, onerror_collect\nfrom dvc.utils.collections import ensure_list\nfrom dvc.utils.serialize import load_yaml\n\nlogger = logging.getLogger(__name__)\n\n\ndef _is_metric(out: Output) -> bool:\n    return bool(out.metric) or bool(out.live)\n\n\ndef _to_fs_paths(metrics: List[Output]) -> StrPaths:\n    result = []\n    for out in metrics:\n        if out.metric:\n            result.append(out.repo.dvcfs.from_os_path(out.fs_path))\n        elif out.live:\n            fs_path = summary_fs_path(out)\n            if fs_path:\n                result.append(out.repo.dvcfs.from_os_path(fs_path))\n    return result\n\n\ndef _collect_metrics(repo, targets, revision, recursive):\n    metrics, fs_paths = collect(\n        repo,\n        targets=targets,\n        output_filter=_is_metric,\n        recursive=recursive,\n        rev=revision,\n    )\n    return _to_fs_paths(metrics) + list(fs_paths)\n\n\ndef _extract_metrics(metrics, path, rev):\n    if isinstance(metrics, (int, float)):\n        return metrics\n\n    if not isinstance(metrics, dict):\n        return None\n\n    ret = {}\n    for key, val in metrics.items():\n        m = _extract_metrics(val, path, rev)\n        if m not in (None, {}):\n            ret[key] = m\n        else:\n            logger.debug(\n                \"Could not parse '%s' metric from '%s' at '%s' \"\n                \"due to its unsupported type: '%s'\",\n                key,\n                path,\n                rev,\n                type(val).__name__,\n            )\n\n    return ret\n\n\n@error_handler\ndef _read_metric(path, fs, rev, **kwargs):\n    val = load_yaml(path, fs=fs)\n    val = _extract_metrics(val, path, rev)\n    return val or {}\n\n\ndef _read_metrics(repo, metrics, rev, onerror=None):\n    fs = DvcFileSystem(repo=repo)\n\n    relpath = \"\"\n    if repo.root_dir != repo.fs.path.getcwd():\n        relpath = repo.fs.path.relpath(repo.root_dir, repo.fs.path.getcwd())\n\n    res = {}\n    for metric in metrics:\n        if not fs.isfile(metric):\n            continue\n\n        res[os.path.join(relpath, *fs.path.parts(metric))] = _read_metric(\n            metric, fs, rev, onerror=onerror\n        )\n\n    return res\n\n\ndef _gather_metrics(repo, targets, rev, recursive, onerror=None):\n    metrics = _collect_metrics(repo, targets, rev, recursive)\n    return _read_metrics(repo, metrics, rev, onerror=onerror)\n\n\n@locked\ndef show(\n    repo,\n    targets=None,\n    all_branches=False,\n    all_tags=False,\n    recursive=False,\n    revs=None,\n    all_commits=False,\n    onerror=None,\n):\n    if onerror is None:\n        onerror = onerror_collect\n\n    targets = ensure_list(targets)\n    targets = [repo.dvcfs.from_os_path(target) for target in targets]\n\n    res = {}\n    for rev in repo.brancher(\n        revs=revs,\n        all_branches=all_branches,\n        all_tags=all_tags,\n        all_commits=all_commits,\n    ):\n        res[rev] = error_handler(_gather_metrics)(\n            repo, targets, rev, recursive, onerror=onerror\n        )\n\n    # Hide workspace metrics if they are the same as in the active branch\n    try:\n        active_branch = repo.scm.active_branch()\n    except (SCMError, NoSCMError):\n        # SCMError - detached head\n        # NoSCMError - no repo case\n        pass\n    else:\n        if res.get(\"workspace\") == res.get(active_branch):\n            res.pop(\"workspace\", None)\n\n    errored = errored_revisions(res)\n    if errored:\n        from dvc.ui import ui\n\n        ui.error_write(\n            \"DVC failed to load some metrics for following revisions:\"\n            f\" '{', '.join(errored)}'.\"\n        )\n\n    return res\n", "path": "dvc/repo/metrics/show.py"}]}