nebius/SWE-bench-extra huggingface dataset:
Repository: iterative/dvc

Issue:
`labels`/`type`/`desc` support in `dvc.yaml` file.



Comments:

Patch:
diff --git a/dvc/output.py b/dvc/output.py
--- a/dvc/output.py
+++ b/dvc/output.py
@@ -188,7 +188,7 @@ def load_from_pipeline(stage, data, typ="outs"):
                 Output.PARAM_PERSIST,
                 Output.PARAM_CHECKPOINT,
                 Output.PARAM_REMOTE,
-                Annotation.PARAM_DESC,
+                *ANNOTATION_FIELDS,
             ],
         )
 
diff --git a/dvc/schema.py b/dvc/schema.py
--- a/dvc/schema.py
+++ b/dvc/schema.py
@@ -3,7 +3,7 @@
 from voluptuous import Any, Optional, Required, Schema
 
 from dvc import dependency, output
-from dvc.annotations import Annotation
+from dvc.annotations import ANNOTATION_SCHEMA
 from dvc.output import CHECKSUMS_SCHEMA, Output
 from dvc.parsing import DO_KWD, FOREACH_KWD, VARS_KWD
 from dvc.parsing.versions import SCHEMA_KWD, lockfile_version_schema
@@ -48,10 +48,10 @@
 
 OUT_PSTAGE_DETAILED_SCHEMA = {
     str: {
+        **ANNOTATION_SCHEMA,  # type: ignore
         Output.PARAM_CACHE: bool,
         Output.PARAM_PERSIST: bool,
         Output.PARAM_CHECKPOINT: bool,
-        Annotation.PARAM_DESC: str,
         Output.PARAM_REMOTE: str,
     }
 }
diff --git a/dvc/stage/serialize.py b/dvc/stage/serialize.py
--- a/dvc/stage/serialize.py
+++ b/dvc/stage/serialize.py
@@ -38,8 +38,9 @@
 
 @post_processing(OrderedDict)
 def _get_flags(out):
-    if out.annot.desc:
-        yield PARAM_DESC, out.annot.desc
+    annot = out.annot.to_dict()
+    yield from annot.items()
+
     if not out.use_cache:
         yield PARAM_CACHE, False
     if out.checkpoint:


Test patch:
diff --git a/tests/func/test_dvcfile.py b/tests/func/test_dvcfile.py
--- a/tests/func/test_dvcfile.py
+++ b/tests/func/test_dvcfile.py
@@ -3,6 +3,7 @@
 
 import pytest
 
+from dvc.annotations import Annotation
 from dvc.dvcfile import (
     PIPELINE_FILE,
     PIPELINE_LOCK,
@@ -392,7 +393,9 @@ def test_dvcfile_load_dump_stage_with_desc_meta(tmp_dir, dvc):
                 "desc": "stage desc",
                 "meta": {"key1": "value1", "key2": "value2"},
                 "deps": ["foo"],
-                "outs": [{"bar": {"desc": "bar desc"}}],
+                "outs": [
+                    {"bar": {"desc": "bar desc", "meta": {"key": "value"}}}
+                ],
             }
         }
     }
@@ -401,7 +404,9 @@ def test_dvcfile_load_dump_stage_with_desc_meta(tmp_dir, dvc):
     stage = dvc.stage.load_one(name="stage1")
     assert stage.meta == {"key1": "value1", "key2": "value2"}
     assert stage.desc == "stage desc"
-    assert stage.outs[0].annot.desc == "bar desc"
+    assert stage.outs[0].annot == Annotation(
+        desc="bar desc", meta={"key": "value"}
+    )
 
     # sanity check
     stage.dump()
Repository: iterative/dvc

Issue:
plots: expand supported images extensions
After #6431 we support rendering of JPEG, GIF, PNG images.
We could expand this list by other images types that browsers support.

Related:
https://github.com/iterative/dvc.org/pull/2839#discussion_r716327710


Comments:
I think we can expand as needed by users.
SVG? Maybe TIFF? Uncompressed bitmaps? I'd ask CV people.
I think that SVG is perhaps a good first addition, as plotting libraries can output that and they are often a bit smaller than PNGs. Having at least one vector format and one raster format would be a good goal. Probably not a first priority, but it would be nice!
Unless I am missing something, this would only need to update:

https://github.com/iterative/dvc/blob/d7152e360e4770c54645e84ca9b690389d60dd07/dvc/repo/plots/__init__.py#L556

Patch:
diff --git a/dvc/repo/plots/__init__.py b/dvc/repo/plots/__init__.py
--- a/dvc/repo/plots/__init__.py
+++ b/dvc/repo/plots/__init__.py
@@ -553,7 +553,7 @@ def parse(fs, path, props=None, **kwargs):
         return _load_sv(path=path, fs=fs, delimiter="\t", header=header)
     if extension in LOADERS or extension in (".yml", ".yaml"):
         return LOADERS[extension](path=path, fs=fs)
-    if extension in (".jpeg", ".jpg", ".gif", ".png"):
+    if extension in (".jpeg", ".jpg", ".gif", ".png", ".svg"):
         with fs.open(path, "rb") as fd:
             return fd.read()
     raise PlotMetricTypeError(path)


Test patch:
diff --git a/tests/func/plots/test_show.py b/tests/func/plots/test_show.py
--- a/tests/func/plots/test_show.py
+++ b/tests/func/plots/test_show.py
@@ -257,16 +257,21 @@ def test_log_errors(
     )
 
 
-def test_plots_binary(tmp_dir, scm, dvc, run_copy_metrics, custom_template):
-    with open("image.jpg", "wb") as fd:
+@pytest.mark.parametrize("ext", ["jpg", "svg"])
+def test_plots_binary(
+    tmp_dir, scm, dvc, run_copy_metrics, custom_template, ext
+):
+    file1 = f"image.{ext}"
+    file2 = f"plot.{ext}"
+    with open(file1, "wb") as fd:
         fd.write(b"content")
 
-    dvc.add(["image.jpg"])
+    dvc.add([file1])
     run_copy_metrics(
-        "image.jpg",
-        "plot.jpg",
+        file1,
+        file2,
         commit="run training",
-        plots=["plot.jpg"],
+        plots=[file2],
         name="s2",
         single_stage=False,
     )
@@ -276,12 +281,12 @@ def test_plots_binary(tmp_dir, scm, dvc, run_copy_metrics, custom_template):
 
     scm.tag("v1")
 
-    with open("plot.jpg", "wb") as fd:
+    with open(file2, "wb") as fd:
         fd.write(b"content2")
 
     result = dvc.plots.show(revs=["v1", "workspace"])
-    assert get_plot(result, "v1", file="plot.jpg") == b"content"
-    assert get_plot(result, "workspace", file="plot.jpg") == b"content2"
+    assert get_plot(result, "v1", file=file2) == b"content"
+    assert get_plot(result, "workspace", file=file2) == b"content2"
 
 
 def test_collect_non_existing_dir(tmp_dir, dvc, run_copy_metrics):
Repository: iterative/dvc

Issue:
dvc repro: Tuples in parameters are always marked as modified
# Bug Report

<!--
## Issue name

Issue names must follow the pattern `command: description` where the command is the dvc command that you are trying to run. The description should describe the consequence of the bug.

Example: `repro: doesn't detect input changes`
-->

## Description

<!--
A clear and concise description of what the bug is.
-->
When tuples are used in parameters, dvc always marks them as modified.

```sh
dvc status
```
outputs
```yaml
train_model:
  changed deps:
    model/parameters.py:    
      modified: NGRAM_VECTORIZER_RANGE
```

regardless of whether `NGRAM_VECTORIZER_RANGE` has been changed



Comments:
Can reproduce. Taking a look
When serializing the ParamsDependency to the lock file (`dvc.lock`), the tuple gets converted to a list (because `dvc.lock` is in YAML format).

On the subsequent `dvc repro` execution, the value in the params file gets correctly loaded as a tuple but compared against the serialized list (https://github.com/iterative/dvc/blob/main/dvc/dependency/param.py#L127), always reporting it as modified.

Patch:
diff --git a/dvc/dependency/param.py b/dvc/dependency/param.py
--- a/dvc/dependency/param.py
+++ b/dvc/dependency/param.py
@@ -125,9 +125,14 @@ def workspace_status(self):
             elif param not in info:
                 st = "new"
             elif actual[param] != info[param]:
-                st = "modified"
+                if (
+                    isinstance(actual[param], tuple)
+                    and list(actual[param]) == info[param]
+                ):
+                    continue
+                else:
+                    st = "modified"
             else:
-                assert actual[param] == info[param]
                 continue
 
             status[str(self)][param] = st


Test patch:
diff --git a/tests/unit/dependency/test_params.py b/tests/unit/dependency/test_params.py
--- a/tests/unit/dependency/test_params.py
+++ b/tests/unit/dependency/test_params.py
@@ -207,6 +207,22 @@ def test_read_params_py(tmp_dir, dvc):
     assert dep.read_params() == {"x": 4, "Klass.a": "val1"}
 
 
+def test_params_py_tuple_status(tmp_dir, dvc):
+    """https://github.com/iterative/dvc/issues/8803"""
+    parameters_file = "parameters.py"
+    tmp_dir.gen(parameters_file, "TUPLE = (10, 100)\n")
+    dep = ParamsDependency(Stage(dvc), parameters_file, ["TUPLE"])
+    # lock file uses YAML so the tuple will be loaded as a list
+    dep.fill_values({"TUPLE": [10, 100]})
+    assert dep.status() == {}
+    dep.fill_values({"TUPLE": [11, 100]})
+    assert dep.status() == {"parameters.py": {"TUPLE": "modified"}}
+    dep.fill_values({"TUPLE": [10]})
+    assert dep.status() == {"parameters.py": {"TUPLE": "modified"}}
+    dep.fill_values({"TUPLE": {10: "foo", 100: "bar"}})
+    assert dep.status() == {"parameters.py": {"TUPLE": "modified"}}
+
+
 def test_get_hash_missing_config(dvc):
     dep = ParamsDependency(Stage(dvc), None, ["foo"])
     with pytest.raises(MissingParamsError):
Repository: iterative/dvc

Issue:
Being able to call  `exp show` with multiple branches (`--rev`) and a number of commits (`-n`)
In the VS Code extension, we would like to show multiple branches at the same time in the table. Each with its own number of commits. We're currently doing this by calling `exp show` once per branch (`dvc exp show --rev main -n 5`, `dvc exp show --rev other-branch -n 3`...). We'd like to be able to do this in one call only (something like `dvc exp show --rev main -n 5 --rev other-branch -n 3...`). Would it be possible?


Comments:
> Would it be possible?

The internal API already supports multiple `revs`.

This should be a simple change to make for the CLI (TBH I thought the CLI already supported it)

Patch:
diff --git a/dvc/commands/experiments/__init__.py b/dvc/commands/experiments/__init__.py
--- a/dvc/commands/experiments/__init__.py
+++ b/dvc/commands/experiments/__init__.py
@@ -82,6 +82,7 @@ def add_rev_selection_flags(
     experiments_subcmd_parser.add_argument(
         "--rev",
         type=str,
+        action="append",
         default=None,
         help=msg,
         metavar="<commit>",


Test patch:
diff --git a/tests/unit/command/test_experiments.py b/tests/unit/command/test_experiments.py
--- a/tests/unit/command/test_experiments.py
+++ b/tests/unit/command/test_experiments.py
@@ -116,7 +116,7 @@ def test_experiments_show(dvc, scm, mocker):
         hide_queued=True,
         hide_failed=True,
         num=1,
-        revs="foo",
+        revs=["foo"],
         sha_only=True,
         param_deps=True,
         fetch_running=True,
@@ -226,7 +226,7 @@ def test_experiments_list(dvc, scm, mocker):
     m.assert_called_once_with(
         cmd.repo,
         git_remote="origin",
-        rev="foo",
+        rev=["foo"],
         all_commits=True,
         num=-1,
     )
@@ -265,7 +265,7 @@ def test_experiments_push(dvc, scm, mocker):
         cmd.repo,
         "origin",
         ["experiment1", "experiment2"],
-        rev="foo",
+        rev=["foo"],
         all_commits=True,
         num=2,
         force=True,
@@ -322,7 +322,7 @@ def test_experiments_pull(dvc, scm, mocker):
         cmd.repo,
         "origin",
         ["experiment"],
-        rev="foo",
+        rev=["foo"],
         all_commits=True,
         num=1,
         force=True,
@@ -371,7 +371,7 @@ def test_experiments_remove_flag(dvc, scm, mocker, capsys, caplog):
         cmd.repo,
         exp_names=[],
         all_commits=True,
-        rev="foo",
+        rev=["foo"],
         num=2,
         queue=False,
         git_remote="myremote",
Repository: iterative/shtab

Issue:
Could replace more non-word characters
I have an argparse script which accepts subcommands with names like:

```
my/first/subcommand
my/second/subcommand
```

which end up causing invalid completion scripts similar to #20.

It would be trivial to add `/` to the list of characters replaced in `wordify()`, or even change the character set to `\W` to replace any non-word character. Are either of these options preferable? (both work when tested with my script)

I'm happy to put together a one-line pull request if you think this is worthwhile.

Comments:

Patch:
diff --git a/shtab/__init__.py b/shtab/__init__.py
index a34c474..b751284 100644
--- a/shtab/__init__.py
+++ b/shtab/__init__.py
@@ -129,8 +129,8 @@ def complete2pattern(opt_complete, shell: str, choice_type2fn) -> str:
 
 
 def wordify(string: str) -> str:
-    """Replace non-word chars [-. :] with underscores [_]"""
-    return re.sub(r"[-.\s:]", "_", string)
+    """Replace non-word chars [\\W] with underscores [_]"""
+    return re.sub("\\W", "_", string)
 
 
 def get_public_subcommands(sub):


Test patch:
diff --git a/tests/test_shtab.py b/tests/test_shtab.py
index de23513..05ce08c 100644
--- a/tests/test_shtab.py
+++ b/tests/test_shtab.py
@@ -241,6 +241,25 @@ def test_subparser_colons(shell, caplog):
     assert not caplog.record_tuples
 
 
+@fix_shell
+def test_subparser_slashes(shell, caplog):
+    parser = ArgumentParser(prog="test")
+    subparsers = parser.add_subparsers()
+    subparsers.add_parser("sub/cmd", help="help message")
+    with caplog.at_level(logging.INFO):
+        completion = shtab.complete(parser, shell=shell)
+    print(completion)
+
+    if shell == "bash":
+        shell = Bash(completion)
+        shell.compgen('-W "${_shtab_test_subparsers[*]}"', "s", "sub/cmd")
+        shell.compgen('-W "${_shtab_test_pos_0_choices[*]}"', "s", "sub/cmd")
+        shell.test('-z "${_shtab_test_COMPGEN-}"')
+    elif shell == "zsh":
+        assert "_shtab_test_sub/cmd" not in completion
+        assert "_shtab_test_sub_cmd" in completion
+
+
 @fix_shell
 def test_add_argument_to_optional(shell, caplog):
     parser = ArgumentParser(prog="test")