internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: iterative/dvc

Issue:
push/pull: globs that match no targets should fail
When using `--glob` with `push` or `pull`, a glob that matches no targets will instead act on all targets. In other words, `dvc push/pull --glob 'nomatches*'` will be the same as `dvc push/pull/repro` without any target argument.

```
$ mkdir repo
$ mkdir dvcremote
$ cd repo
$ git init
Initialized empty Git repository in /private/tmp/glob/repo/.git/
$ dvc init -q
$ dvc remote add -d default ../dvcremote
Setting 'default' as a default remote.
$ echo foo > foo
$ dvc add foo
100% Adding...|████████████████████████████████████████████████|1/1 [00:00, 52.98file/s]

To track the changes with git, run:

    git add foo.dvc .gitignore

To enable auto staging, run:

        dvc config core.autostage true
$ dvc push --glob 'z*'
1 file pushed
$ rm foo
$ dvc pull --glob 'z*'
A       foo
1 file added
```

I would expect the commands to fail or push/pull nothing if there are no `--glob` matches.


Discussion:
See https://github.com/iterative/dvc/issues/7462#issuecomment-1070954669

Resolving patch:
diff --git a/dvc/utils/__init__.py b/dvc/utils/__init__.py
--- a/dvc/utils/__init__.py
+++ b/dvc/utils/__init__.py
@@ -476,17 +476,25 @@ def is_exec(mode):
 
 
 def glob_targets(targets, glob=True, recursive=True):
+    from ..exceptions import DvcException
+
     if not glob:
         return targets
 
     from glob import iglob
 
-    return [
+    results = [
         exp_target
         for target in targets
         for exp_target in iglob(target, recursive=recursive)
     ]
 
+    if not results:
+        msg = f"Glob {targets} has no matches."
+        raise DvcException(msg)
+
+    return results
+
 
 def error_handler(func):
     def wrapper(*args, **kwargs):


Test patch:
diff --git a/tests/func/test_utils.py b/tests/func/test_utils.py
--- a/tests/func/test_utils.py
+++ b/tests/func/test_utils.py
@@ -1,4 +1,9 @@
+import re
+
+import pytest
+
 from dvc import utils
+from dvc.exceptions import DvcException
 from dvc.fs.local import LocalFileSystem
 
 
@@ -42,3 +47,10 @@ def test_boxify():
     )
 
     assert expected == utils.boxify("message")
+
+
+def test_glob_no_match():
+    with pytest.raises(
+        DvcException, match=re.escape("Glob ['invalid*'] has no matches.")
+    ):
+        utils.glob_targets(["invalid*"], glob=True)
Repository: iterative/dvc

Issue:
config: option for `--jobs` value
Several DVC commands have a `--jobs` option that has default values (e.g, https://dvc.org/doc/commands-reference/gc).

Afaik there is no way to change the default value. Having the option to change it through `dvc config` would be useful.

Can you consider adding it?

Thanks


Discussion:
Hi @andrethrill !

Currently, most, if not all, of those commands are those that are related somehow to remotes and use that --jobs option only to set a number of connections. Different remote types have different default values for --jobs, so it seems like it would be a good fit to start with adding `jobs` configuration option for separate remotes. We don't currently do anything in parallel within the core dvc (we will soon though :wink: ), but when we will do that, we could add `dvc config core.jobs` options for that, so it should fit nicely. I've added this to our todo list. Thanks for the feedback! :slightly_smiling_face: 
Thanks for the clarification @efiop !

Just to be sure: so, at the moment, when I garbage collect the local cache only, it is a single thread job. Correct?
@andrethrill Yes, correct.
We'll add this option when additing something that uses it. Closing for now.
Fixed in https://github.com/iterative/dvc/issues/4504
Reopening due to https://github.com/iterative/dvc/issues/5647

To close it we need to allow users to set `core.jobs` value. Currently:
```bash
(dvc3.7) repo git:master ✩  ❯ dvc config core.jobs 4
ERROR: configuration error - config file error: extra keys not allowed @ data['core']['jobs']
```
`DVC version: 2.0.12`

Resolving patch:
diff --git a/dvc/fs/__init__.py b/dvc/fs/__init__.py
--- a/dvc/fs/__init__.py
+++ b/dvc/fs/__init__.py
@@ -104,11 +104,6 @@ def get_cloud_fs(repo, **kwargs):
     except Invalid as exc:
         raise RepoConfigError(str(exc)) from None
 
-    if "jobs" not in remote_conf:
-        jobs = core_config.get("jobs")
-        if jobs:
-            remote_conf["jobs"] = jobs
-
     if "checksum_jobs" not in remote_conf:
         checksum_jobs = core_config.get("checksum_jobs")
         if checksum_jobs:


Test patch:
diff --git a/tests/unit/remote/test_remote.py b/tests/unit/remote/test_remote.py
--- a/tests/unit/remote/test_remote.py
+++ b/tests/unit/remote/test_remote.py
@@ -23,7 +23,6 @@ def test_remote_with_jobs(dvc):
         "url": "s3://bucket/name",
         "jobs": 100,
     }
-    dvc.config["core"]["jobs"] = 200
 
     cls, config, _ = get_cloud_fs(dvc, name="with_jobs")
     fs = cls(**config)
Repository: iterative/dvc

Issue:
checkout/pull: dvcignored contents are removed on checkout
```bash
cd "$(mktemp -d)"
dvc init --no-scm
dvc remote add -d local "$(mktemp -d)"
mkdir -p data/processed
echo "foo" > data/foo
echo "bar" > data/processed/bar
echo "data/processed/" >> .dvcignore
dvc add data
dvc push
rm -rf .dvc/cache data/foo
dvc pull | tee
```

This is a regression introduced in b349b39d6266a28705b03b1b06e5c0cf98a9080d (see #5812), which was released in [2.2.0](https://github.com/iterative/dvc/releases/tag/2.2.0) and is present since then.


Discussion:
#4344 and this issue are related to staging in dvc-data.

Resolving patch:
diff --git a/dvc/output.py b/dvc/output.py
--- a/dvc/output.py
+++ b/dvc/output.py
@@ -583,6 +583,7 @@ def _checkout(self, *args, **kwargs):
         from dvc_data.checkout import CheckoutError as _CheckoutError
         from dvc_data.checkout import LinkError, PromptError
 
+        kwargs.setdefault("ignore", self.dvcignore)
         try:
             return checkout(*args, **kwargs)
         except PromptError as exc:
@@ -627,7 +628,6 @@ def commit(self, filter_info=None):
                 obj,
                 self.odb,
                 relink=True,
-                ignore=self.dvcignore,
                 state=self.repo.state,
                 prompt=prompt.confirm,
             )


Test patch:
diff --git a/tests/func/test_ignore.py b/tests/func/test_ignore.py
--- a/tests/func/test_ignore.py
+++ b/tests/func/test_ignore.py
@@ -418,3 +418,27 @@ def test_run_dvcignored_dep(tmp_dir, dvc, run_copy):
     tmp_dir.gen({".dvcignore": "dir\n", "dir": {"foo": "foo"}})
     run_copy(os.path.join("dir", "foo"), "bar", name="copy-foo-to-bar")
     assert (tmp_dir / "bar").read_text() == "foo"
+
+
+def test_pull_ignore(tmp_dir, dvc, local_cloud):
+    from dvc.utils.fs import remove
+
+    tmp_dir.dvc_gen(
+        {
+            ".dvcignore": "data/processed/",
+            "data": {"foo": "foo", "processed": {"bar": "bar"}},
+        }
+    )
+    tmp_dir.add_remote(config=local_cloud.config)
+    dvc.add("data")
+    dvc.push()
+
+    foo_path = tmp_dir / "data" / "foo"
+    foo_path.unlink()
+    assert not foo_path.exists()
+
+    remove(tmp_dir / ".dvc/cache")
+    dvc.pull()
+
+    assert foo_path.exists()
+    assert foo_path.read_text() == "foo"
Repository: iterative/dvc

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.


Discussion:
Is this a high priority issue? We don't get many requests for TOML metrics support (that one discord question is the only one in the last couple of years as far as I can tell)
It's not high priority, but a user did request it, so @flippedcoder volunteered to open an issue for it.
Anyone looking for contributing, the place to add the support is here:
https://github.com/iterative/dvc/blob/6c646a70703cc68991eeb3232748b39c759c942c/dvc/repo/metrics/show.py#L70

Please compare that to the `params` which already supports `toml` file:
https://github.com/iterative/dvc/blob/6c646a70703cc68991eeb3232748b39c759c942c/dvc/repo/params/show.py#L53-L55

Also note that, `LOADERS` also supports reading `.py` files which we might need to forbid here, if we use it in the metrics.



Resolving patch:
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 @@ def _extract_metrics(metrics, path, rev):
 
 @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 {}
 


Test patch:
diff --git a/tests/func/metrics/test_show.py b/tests/func/metrics/test_show.py
--- a/tests/func/metrics/test_show.py
+++ b/tests/func/metrics/test_show.py
@@ -8,7 +8,7 @@
 from dvc.exceptions import OverlappingOutputPathsError
 from dvc.repo import Repo
 from dvc.utils.fs import remove
-from dvc.utils.serialize import YAMLFileCorruptedError
+from dvc.utils.serialize import JSONFileCorruptedError, YAMLFileCorruptedError
 
 
 def test_show_simple(tmp_dir, dvc, run_copy_metrics):
@@ -31,6 +31,16 @@ def test_show(tmp_dir, dvc, run_copy_metrics):
     }
 
 
+def test_show_toml(tmp_dir, dvc, run_copy_metrics):
+    tmp_dir.gen("metrics_t.toml", "[foo]\nbar = 1.2")
+    run_copy_metrics(
+        "metrics_t.toml", "metrics.toml", metrics=["metrics.toml"]
+    )
+    assert dvc.metrics.show() == {
+        "": {"data": {"metrics.toml": {"data": {"foo": {"bar": 1.2}}}}}
+    }
+
+
 def test_show_targets(tmp_dir, dvc, run_copy_metrics):
     tmp_dir.gen("metrics_t.yaml", "foo: 1.1")
     run_copy_metrics(
@@ -218,7 +228,7 @@ def test_show_malformed_metric(tmp_dir, scm, dvc, caplog):
         dvc.metrics.show(targets=["metric.json"])[""]["data"]["metric.json"][
             "error"
         ],
-        YAMLFileCorruptedError,
+        JSONFileCorruptedError,
     )
Repository: iterative/dvc

Issue:
installing from Ubuntu repo does not install s3 adapter
# Bug Report

DVC version 2.6.3

![image](https://user-images.githubusercontent.com/167835/186968532-080d228a-054f-4688-8967-8ec62cd17458.png)

DVC version 2.21.1

![image](https://user-images.githubusercontent.com/167835/186968664-c2b3edcb-2dca-4eba-9cee-fbdd472979eb.png)



Discussion:
Looks like we need to add dvc-* packages to pyinstaller hooks as hidden imports.
related? https://github.com/iterative/setup-dvc/issues/41

Resolving patch:
diff --git a/scripts/pyinstaller/build.py b/scripts/pyinstaller/build.py
--- a/scripts/pyinstaller/build.py
+++ b/scripts/pyinstaller/build.py
@@ -1,6 +1,6 @@
 import os
 import pathlib
-from subprocess import STDOUT, check_call
+from subprocess import STDOUT, check_call, check_output
 
 path = pathlib.Path(__file__).parent.absolute()
 hooks = path / "hooks"
@@ -21,10 +21,27 @@
     stderr=STDOUT,
 )
 
-check_call(
+out = check_output(
     [
         path / "dist" / "dvc" / "dvc",
         "doctor",
     ],
     stderr=STDOUT,
-)
+).decode()
+
+remotes = [
+    "s3",
+    "oss",
+    "gdrive",
+    "gs",
+    "hdfs",
+    "http",
+    "webhdfs",
+    "azure",
+    "ssh",
+    "webdav",
+]
+
+print(out)
+for remote in remotes:
+    assert f"\t{remote}" in out, f"Missing support for {remote}"
diff --git a/scripts/pyinstaller/hooks/hook-dvc.py b/scripts/pyinstaller/hooks/hook-dvc.py
--- a/scripts/pyinstaller/hooks/hook-dvc.py
+++ b/scripts/pyinstaller/hooks/hook-dvc.py
@@ -16,5 +16,15 @@
 datas += copy_metadata("aiohttp")
 datas += copy_metadata("aiohttp_retry")
 
-# https://github.com/pypa/setuptools/issues/1963
-hiddenimports = ["pkg_resources.py2_warn"]
+hiddenimports = [
+    "dvc_azure",
+    "dvc_gdrive",
+    "dvc_gs",
+    "dvc_hdfs",
+    "dvc_oss",
+    "dvc_s3",
+    "dvc_webdav",
+    "dvc_webhdfs",
+    # https://github.com/pypa/setuptools/issues/1963
+    "pkg_resources.py2_warn",
+]


Test patch:
Repository: iterative/dvc

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



Discussion:

Resolving 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


Discussion:
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

Resolving 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:
cloud versioning: not able to do any data sync operations
# Bug Report

## Description

https://github.com/iterative/dvc/pull/8662 broke all data sync operations.

### Reproduce

Try any of the following with a `version_aware` or `worktree` remote:

```
$ dvc push
ERROR: failed to push data to the cloud - config file error: '<command>' is unsupported for cloud versioned remotes
$ dvc pull
ERROR: failed to pull data from the cloud - config file error: '<command>' is unsupported for cloud versioned remotes
$ dvc fetch
ERROR: failed to fetch data from the cloud - config file error: '<command>' is unsupported for cloud versioned remotes
```

Also, the error isn't showing the command as expected.



Discussion:
looks like the issue here happens when using the default remote, if you are running the commands with `-r/--remote <remotename>` the error does not occur

Resolving patch:
diff --git a/dvc/data_cloud.py b/dvc/data_cloud.py
--- a/dvc/data_cloud.py
+++ b/dvc/data_cloud.py
@@ -5,7 +5,7 @@
 
 from funcy import cached_property
 
-from dvc.config import RemoteConfigError
+from dvc.config import NoRemoteError, RemoteConfigError
 from dvc_data.hashfile.db import get_index
 
 if TYPE_CHECKING:
@@ -63,8 +63,6 @@ def get_remote(
         name: Optional[str] = None,
         command: str = "<command>",
     ) -> "Remote":
-        from dvc.config import NoRemoteError
-
         if not name:
             name = self.repo.config["core"].get("remote")
 
@@ -98,7 +96,7 @@ def get_remote_odb(
     ) -> "HashFileDB":
         remote = self.get_remote(name=name, command=command)
         if remote.fs.version_aware or remote.worktree:
-            raise RemoteConfigError(
+            raise NoRemoteError(
                 f"'{command}' is unsupported for cloud versioned remotes"
             )
         return remote.odb


Test patch:
Repository: iterative/dvc

Issue:
DuplicateError: Duplicate section name at line 12.
# Bug Report

## Description

When any user has any config file in incorrect format like repeated section name, we throw the raw exception from ConfigObj. 
IMO, this should be wrapped by the ConfigError in dvc side.

### Relevant stack trace

```py
    config = dict(Config(dvc_dir, validate=False))
  File "dvc/config.py", line 105, in __init__
    self.load(validate=validate, config=config)
  File "dvc/config.py", line 151, in load
    conf = self.load_config_to_level()
  File "dvc/config.py", line 286, in load_config_to_level
    merge(merged_conf, self.load_one(merge_level))
  File "dvc/config.py", line 203, in load_one
    conf = self._load_config(level)
  File "dvc/config.py", line 180, in _load_config
    conf_obj = ConfigObj(fobj)
  File "configobj.py", line 1229, in __init__
    self._load(infile, configspec)
  File "configobj.py", line 1318, in _load
    raise error
```

Reference Issue in Studio:  https://github.com/iterative/studio/issues/4846



Discussion:

Resolving patch:
diff --git a/dvc/config.py b/dvc/config.py
--- a/dvc/config.py
+++ b/dvc/config.py
@@ -169,7 +169,7 @@ def _get_fs(self, level):
         return self.fs if level == "repo" else self.wfs
 
     def _load_config(self, level):
-        from configobj import ConfigObj
+        from configobj import ConfigObj, ConfigObjError
 
         filename = self.files[level]
         fs = self._get_fs(level)
@@ -180,6 +180,8 @@ def _load_config(self, level):
                     conf_obj = ConfigObj(fobj)
                 except UnicodeDecodeError as exc:
                     raise ConfigError(str(exc)) from exc
+                except ConfigObjError as exc:
+                    raise ConfigError(str(exc)) from exc
         else:
             conf_obj = ConfigObj()
         return _parse_named(_lower_keys(conf_obj.dict()))


Test patch:
diff --git a/tests/unit/test_config.py b/tests/unit/test_config.py
--- a/tests/unit/test_config.py
+++ b/tests/unit/test_config.py
@@ -81,3 +81,16 @@ def test_load_unicode_error(tmp_dir, dvc, mocker):
     with pytest.raises(ConfigError):
         with config.edit():
             pass
+
+
+def test_load_configob_error(tmp_dir, dvc, mocker):
+    from configobj import ConfigObjError
+
+    config = Config(validate=False)
+    mocker.patch(
+        "configobj.ConfigObj",
+        side_effect=ConfigObjError(),
+    )
+    with pytest.raises(ConfigError):
+        with config.edit():
+            pass