exp show: show metrics that include separator (#9819)

* exp show: show metrics that include separator

* sort using partition instead of lpartition

* handle ':' in file and metric names

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix sorting with leading :

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Dave Berenbaum
2023-08-24 10:31:56 -04:00
committed by GitHub
co-authored by pre-commit-ci[bot]
parent 88431b1c0a
commit ef260eaf2e
2 changed files with 27 additions and 8 deletions
+13 -8
View File
@@ -177,26 +177,31 @@ def _build_rows(
) )
def _sort_column( def _sort_column( # noqa: C901
sort_by: str, sort_by: str,
metric_names: Mapping[str, Iterable[str]], metric_names: Mapping[str, Iterable[str]],
param_names: Mapping[str, Iterable[str]], param_names: Mapping[str, Iterable[str]],
) -> Tuple[str, str, str]: ) -> Tuple[str, str, str]:
path, _, sort_name = sort_by.rpartition(":") sep = ":"
parts = sort_by.split(sep)
matches: Set[Tuple[str, str, str]] = set() matches: Set[Tuple[str, str, str]] = set()
if path: for split_num in range(len(parts)):
path = sep.join(parts[:split_num])
sort_name = sep.join(parts[split_num:])
if not path: # handles ':metric_name' case
sort_by = sort_name
if path in metric_names and sort_name in metric_names[path]: if path in metric_names and sort_name in metric_names[path]:
matches.add((path, sort_name, "metrics")) matches.add((path, sort_name, "metrics"))
if path in param_names and sort_name in param_names[path]: if path in param_names and sort_name in param_names[path]:
matches.add((path, sort_name, "params")) matches.add((path, sort_name, "params"))
else: if not matches:
for path in metric_names: for path in metric_names:
if sort_name in metric_names[path]: if sort_by in metric_names[path]:
matches.add((path, sort_name, "metrics")) matches.add((path, sort_by, "metrics"))
for path in param_names: for path in param_names:
if sort_name in param_names[path]: if sort_by in param_names[path]:
matches.add((path, sort_name, "params")) matches.add((path, sort_by, "params"))
if len(matches) == 1: if len(matches) == 1:
return matches.pop() return matches.pop()
+14
View File
@@ -352,6 +352,20 @@ def test_show_sort(tmp_dir, scm, dvc, exp_stage, caplog):
assert main(["exp", "show", "--no-pager", "--sort-by=metrics.yaml:foo"]) == 0 assert main(["exp", "show", "--no-pager", "--sort-by=metrics.yaml:foo"]) == 0
def test_show_sort_metric_sep(tmp_dir, scm, dvc, caplog):
metrics_path = tmp_dir / "metrics:1.json"
metrics_path.write_text('{"my::metric": 1, "other_metric": 0.5}')
metrics_path = tmp_dir / "metrics:2.json"
metrics_path.write_text('{"my::metric": 2}')
dvcyaml_path = tmp_dir / "dvc.yaml"
dvcyaml_path.write_text("metrics: ['metrics:1.json', 'metrics:2.json']")
dvc.experiments.save()
assert (
main(["exp", "show", "--no-pager", "--sort-by=metrics:1.json:my::metric"]) == 0
)
assert main(["exp", "show", "--no-pager", "--sort-by=:other_metric"]) == 0
@pytest.mark.vscode @pytest.mark.vscode
@pytest.mark.parametrize( @pytest.mark.parametrize(
"status, pid_exists", "status, pid_exists",