From 3187040fe8ac52450d3485c44afdb1480de13d31 Mon Sep 17 00:00:00 2001 From: Alexander Schepanovski Date: Thu, 27 Jun 2019 22:45:14 +0700 Subject: [PATCH] dvc: raise when Repo.open() fails --- dvc/exceptions.py | 7 +++++++ dvc/repo/__init__.py | 13 ++++++++++--- tests/func/test_api.py | 10 ++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/dvc/exceptions.py b/dvc/exceptions.py index c5496fa4e..6b38af4ea 100644 --- a/dvc/exceptions.py +++ b/dvc/exceptions.py @@ -263,3 +263,10 @@ class ETagMismatchError(DvcException): "ETag mismatch detected when copying file to cache! " "(expected: '{}', actual: '{}')".format(etag, cached_etag) ) + + +class OutputFileMissingError(DvcException): + def __init__(self, path): + super(OutputFileMissingError, self).__init__( + "Can't find {} neither locally nor on remote".format(path) + ) diff --git a/dvc/repo/__init__.py b/dvc/repo/__init__.py index 2a8daba29..df0124495 100644 --- a/dvc/repo/__init__.py +++ b/dvc/repo/__init__.py @@ -8,10 +8,11 @@ from dvc.exceptions import ( NotDvcRepoError, OutputNotFoundError, TargetNotDirectoryError, + OutputFileMissingError, ) from dvc.ignore import DvcIgnoreFileHandler from dvc.path_info import PathInfo -from dvc.utils.compat import open as _open +from dvc.utils.compat import open as _open, fspath_py35 from dvc.utils import relpath logger = logging.getLogger(__name__) @@ -455,9 +456,15 @@ class Repo(object): if out.isdir(): raise ValueError("Can't open a dir") + cache_file = self.cache.local.checksum_to_path_info(out.checksum) + cache_file = fspath_py35(cache_file) + with self.state: cache_info = out.get_used_cache(remote=remote) self.cloud.pull(cache_info, remote=remote) - cache_file = self.cache.local.checksum_to_path_info(out.checksum) - return _open(cache_file.fspath, mode=mode, encoding=encoding) + # Since pull may just skip with a warning, we need to check it here + if not os.path.exists(cache_file): + raise OutputFileMissingError(relpath(path, self.root_dir)) + + return _open(cache_file, mode=mode, encoding=encoding) diff --git a/tests/func/test_api.py b/tests/func/test_api.py index ab1437bee..84f58044b 100644 --- a/tests/func/test_api.py +++ b/tests/func/test_api.py @@ -2,6 +2,7 @@ import pytest import shutil from dvc import api +from dvc.exceptions import OutputFileMissingError from dvc.main import main from dvc.path_info import URLInfo from dvc.remote.config import RemoteConfig @@ -113,6 +114,15 @@ def test_open_external(repo_dir, dvc_repo, erepo, remote_url): assert fd.read() == repo_dir.FOO_CONTENTS +def test_open_missing(erepo): + # Remove cache to make foo missing + shutil.rmtree(erepo.dvc.cache.local.cache_dir) + + repo_url = "file://" + erepo.dvc.root_dir + with pytest.raises(OutputFileMissingError): + api.read(erepo.FOO, repo=repo_url) + + def _set_remote_url_and_commit(repo, remote_url): rconfig = RemoteConfig(repo.config) rconfig.modify("upstream", "url", remote_url)