Compare commits

...
11 Commits
Author SHA1 Message Date
skshetry 7e93fc8c4a lint: pin astroid version (#8323)
See https://github.com/PyCQA/pylint/issues/7488. Pylint is failing on our codebase.
2022-09-19 12:22:21 +05:45
skshetry 853a918d5c cli: rename cli util, hide data ls from the help (#8321) 2022-09-19 10:29:52 +05:45
skshetry b5f20f8467 use native concurrency (#8320) 2022-09-19 10:23:55 +05:45
skshetry 2f6bc70b45 remove mergify (#8319) 2022-09-19 09:50:56 +05:45
Daniele Trifirò 197f522175 deps: add testing group for dvc.testing requirements 2022-09-17 00:54:35 +03:00
Ruslan Kuprieiev 35e6f082a4 analytics: use iterative-telemetry for user_id lookup 2022-09-17 00:45:45 +03:00
Ruslan Kuprieiev 4531fec2b7 deps: bump dvc-data to 0.10.0 2022-09-16 22:56:56 +03:00
skshetry 391bb29be2 dvcfs: rename DvcFileSystem to DVCFileSystem (#8307) 2022-09-16 18:18:55 +05:45
Peter Rowlands 146bdbbe9b deps: bump dvc-azure to 2.20.4 2022-09-16 17:47:38 +09:00
Saugat Pachhai (सौगात) c1f659bdd7 dvcfs: prevent opening file object in write mode 2022-09-16 11:31:24 +03:00
dependabot[bot] 0fe8f4e368 build(deps): Bump dvc-render from 0.0.10 to 0.0.11
Bumps [dvc-render](https://github.com/iterative/dvc-render) from 0.0.10 to 0.0.11.
- [Release notes](https://github.com/iterative/dvc-render/releases)
- [Commits](https://github.com/iterative/dvc-render/compare/0.0.10...0.0.11)

---
updated-dependencies:
- dependency-name: dvc-render
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-09-16 09:58:16 +02:00
30 changed files with 157 additions and 224 deletions
-9
View File
@@ -1,9 +0,0 @@
pull_request_rules:
- name: backport patches to 1.11
conditions:
- base=main
- label=backport-1.11
actions:
backport:
branches:
- "1.11"
+6 -11
View File
@@ -1,23 +1,18 @@
name: benchmarks
on: [pull_request, workflow_dispatch]
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
bench:
name: run benchmarks
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-18.04]
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/[email protected]
with:
access_token: ${{ github.token }}
- uses: actions/setup-python@v4
with:
python-version: 3.8
python-version: "3.10"
- uses: iterative/dvc-bench@main
with:
pytest_options: "-k 'test_init or test_help'"
+11 -19
View File
@@ -1,25 +1,27 @@
name: Tests
on:
pull_request: {}
push: {}
push:
branches: [main]
pull_request:
schedule:
- cron: '5 1 * * *' # every day at 01:05
workflow_dispatch:
env:
DVC_TEST: "true"
HOMEBREW_NO_AUTO_UPDATE: 1
SHELL: /bin/bash
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
lint:
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/[email protected]
with:
access_token: ${{ github.token }}
- uses: actions/checkout@v3
with:
fetch-depth: 0
@@ -31,7 +33,7 @@ jobs:
run: |
pip install --upgrade pip setuptools wheel
pip install collective.checkdocs==0.2
pip install ".[dev]" pre-commit
pip install ".[dev]"
- name: Check README
run: python setup.py checkdocs
- uses: pre-commit/[email protected]
@@ -57,18 +59,8 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.pyv }}
- name: get pip cache dir
id: pip-cache-dir
run: |
echo "::set-output name=dir::$(pip cache dir)"
- name: set pip cache
id: pip-cache
uses: actions/cache@v3
with:
path: ${{ steps.pip-cache-dir.outputs.dir }}
key: ${{ runner.os }}-pip-${{ hashFiles('setup.cfg') }}
restore-keys: |
${{ runner.os }}-pip-
cache: pip
cache-dependency-path: setup.cfg
- name: install
if: steps.cache.pip-cache-dir.cache-hit != 'true'
run: |
+3 -43
View File
@@ -102,6 +102,8 @@ def _runtime_info():
"""
Gather information from the environment where DVC runs to fill a report.
"""
from iterative_telemetry import find_or_create_user_id
from dvc import __version__
from dvc.utils import is_binary
@@ -110,7 +112,7 @@ def _runtime_info():
"is_binary": is_binary(),
"scm_class": _scm_in_use(),
"system_info": _system_info(),
"user_id": _find_or_create_user_id(),
"user_id": find_or_create_user_id(),
}
@@ -146,45 +148,3 @@ def _system_info():
# We don't collect data for any other system.
raise NotImplementedError
def _find_or_create_user_id():
"""
The user's ID is stored on a file under the global config directory.
The file should contain a JSON with a "user_id" key:
{"user_id": "16fd2706-8baf-433b-82eb-8c7fada847da"}
IDs are generated randomly with UUID.
"""
import uuid
from dvc.config import Config
from dvc.lock import Lock, LockError
from dvc.utils.fs import makedirs
config_dir = Config.get_dir("global")
fname = os.path.join(config_dir, "user_id")
lockfile = os.path.join(config_dir, "user_id.lock")
# Since the `fname` and `lockfile` are under the global config,
# we need to make sure such directory exist already.
makedirs(config_dir, exist_ok=True)
try:
with Lock(lockfile):
try:
with open(fname, encoding="utf-8") as fobj:
user_id = json.load(fobj)["user_id"]
except (FileNotFoundError, ValueError, KeyError):
user_id = str(uuid.uuid4())
with open(fname, "w", encoding="utf-8") as fobj:
json.dump({"user_id": user_id}, fobj)
return user_id
except LockError:
logger.debug("Failed to acquire '%s'", lockfile)
+2 -2
View File
@@ -1,4 +1,4 @@
from dvc.fs.dvc import _DvcFileSystem as DvcFileSystem
from dvc.fs.dvc import _DVCFileSystem as DVCFileSystem
from .data import open # pylint: disable=redefined-builtin
from .data import get_url, read
@@ -11,5 +11,5 @@ __all__ = [
"open",
"params_show",
"read",
"DvcFileSystem",
"DVCFileSystem",
]
+5 -2
View File
@@ -21,10 +21,13 @@ def append_doc_link(help_message, path):
)
def fix_plumbing_subparsers(subparsers):
# metavar needs to be explicitly set in order to hide plumbing subcommands
def hide_subparsers_from_help(subparsers):
# metavar needs to be explicitly set in order to hide subcommands
# from the 'positional arguments' choices list
# see: https://bugs.python.org/issue22848
# Need to set `add_help=False`, but avoid setting `help`
# (not even to `argparse.SUPPPRESS`).
# NOTE: The argument is the parent subparser, not the subcommand parser.
cmds = [
cmd for cmd, parser in subparsers.choices.items() if parser.add_help
]
+7 -3
View File
@@ -8,7 +8,11 @@ from funcy import chunks, compact, log_durations
from dvc.cli import completion
from dvc.cli.actions import CommaSeparatedArgs
from dvc.cli.command import CmdBase
from dvc.cli.utils import append_doc_link, fix_subparsers
from dvc.cli.utils import (
append_doc_link,
fix_subparsers,
hide_subparsers_from_help,
)
from dvc.ui import ui
from dvc.utils import colorize
@@ -251,7 +255,7 @@ def add_parser(subparsers, parent_parser):
parents=[parent_parser],
description=append_doc_link(DATA_LS_HELP, "data/ls"),
formatter_class=argparse.RawDescriptionHelpFormatter,
help=DATA_LS_HELP,
add_help=False,
)
data_ls_parser.add_argument(
"--md",
@@ -289,5 +293,5 @@ def add_parser(subparsers, parent_parser):
".dvc files, or stage names."
),
).complete = completion.DVCFILES_AND_STAGE
data_ls_parser.set_defaults(func=CmdDataLs)
hide_subparsers_from_help(data_subparsers)
+2 -2
View File
@@ -2,8 +2,8 @@ import argparse
from dvc.cli.utils import (
append_doc_link,
fix_plumbing_subparsers,
fix_subparsers,
hide_subparsers_from_help,
)
from dvc.commands.experiments import (
apply,
@@ -59,7 +59,7 @@ def add_parser(subparsers, parent_parser):
fix_subparsers(experiments_subparsers)
for cmd in SUB_COMMANDS:
cmd.add_parser(experiments_subparsers, parent_parser)
fix_plumbing_subparsers(experiments_subparsers)
hide_subparsers_from_help(experiments_subparsers)
def add_rev_selection_flags(
+2 -2
View File
@@ -152,7 +152,7 @@ class RepoDependency(Dependency):
def _check_circular_import(self, odb, obj_ids):
from dvc.exceptions import CircularImportError
from dvc.fs.dvc import DvcFileSystem
from dvc.fs.dvc import DVCFileSystem
from dvc_data.hashfile.db.reference import ReferenceHashFileDB
from dvc_data.hashfile.tree import Tree
@@ -169,7 +169,7 @@ class RepoDependency(Dependency):
checked_urls = set()
for obj in iter_objs():
if not isinstance(obj.fs, DvcFileSystem):
if not isinstance(obj.fs, DVCFileSystem):
continue
if (
obj.fs.repo_url in checked_urls
+2 -2
View File
@@ -24,13 +24,13 @@ from dvc_objects.fs.errors import ( # noqa: F401
from dvc_objects.fs.path import Path # noqa: F401
from .data import DataFileSystem # noqa: F401
from .dvc import DvcFileSystem # noqa: F401
from .dvc import DVCFileSystem # noqa: F401
from .git import GitFileSystem # noqa: F401
known_implementations.update(
{
"dvc": {
"class": "dvc.fs.dvc.DvcFileSystem",
"class": "dvc.fs.dvc.DVCFileSystem",
"err": "dvc is supported, but requires 'dvc' to be installed",
},
"git": {
+7 -3
View File
@@ -1,3 +1,4 @@
import errno
import logging
import ntpath
import os
@@ -64,7 +65,7 @@ def _get_dvc_path(dvc_fs, subkey):
return dvc_fs.path.join(*subkey) if subkey else ""
class _DvcFileSystem(AbstractFileSystem): # pylint:disable=abstract-method
class _DVCFileSystem(AbstractFileSystem): # pylint:disable=abstract-method
"""DVC + git-tracked files fs.
Args:
@@ -222,6 +223,9 @@ class _DvcFileSystem(AbstractFileSystem): # pylint:disable=abstract-method
def _open(
self, path, mode="rb", **kwargs
): # pylint: disable=arguments-renamed, arguments-differ
if mode != "rb":
raise OSError(errno.EROFS, os.strerror(errno.EROFS))
key = self._get_key_from_relative(path)
fs_path = self._from_key(key)
try:
@@ -361,7 +365,7 @@ class _DvcFileSystem(AbstractFileSystem): # pylint:disable=abstract-method
return info
class DvcFileSystem(FileSystem):
class DVCFileSystem(FileSystem):
protocol = "local"
PARAM_CHECKSUM = "md5"
@@ -371,7 +375,7 @@ class DvcFileSystem(FileSystem):
@wrap_prop(threading.Lock())
@cached_property
def fs(self):
return _DvcFileSystem(**self.fs_args)
return _DVCFileSystem(**self.fs_args)
def isdvc(self, path, **kwargs):
return self.fs.isdvc(path, **kwargs)
+5 -5
View File
@@ -187,7 +187,7 @@ class Repo:
self.config = Config(self.dvc_dir, fs=self.fs, config=config)
self._uninitialized = uninitialized
# used by DvcFileSystem to determine if it should traverse subrepos
# used by DVCFileSystem to determine if it should traverse subrepos
self.subrepos = subrepos
self.cloud = DataCloud(self)
@@ -526,9 +526,9 @@ class Repo:
@cached_property
def dvcfs(self):
from dvc.fs.dvc import DvcFileSystem
from dvc.fs.dvc import DVCFileSystem
return DvcFileSystem(
return DVCFileSystem(
repo=self, subrepos=self.subrepos, **self._fs_conf
)
@@ -540,13 +540,13 @@ class Repo:
def open_by_relpath(self, path, remote=None, mode="r", encoding=None):
"""Opens a specified resource as a file descriptor"""
from dvc.fs.data import DataFileSystem
from dvc.fs.dvc import DvcFileSystem
from dvc.fs.dvc import DVCFileSystem
if os.path.isabs(path):
fs = DataFileSystem(index=self.index.data["local"])
fs_path = path
else:
fs = DvcFileSystem(repo=self, subrepos=True)
fs = DVCFileSystem(repo=self, subrepos=True)
fs_path = fs.from_os_path(path)
try:
+2 -2
View File
@@ -30,9 +30,9 @@ def _collect_paths(
recursive: bool = False,
rev: str = None,
) -> StrPaths:
from dvc.fs.dvc import DvcFileSystem
from dvc.fs.dvc import DVCFileSystem
fs = DvcFileSystem(repo=repo)
fs = DVCFileSystem(repo=repo)
fs_paths = [fs.from_os_path(target) for target in targets]
target_paths: StrPaths = []
+2 -2
View File
@@ -23,9 +23,9 @@ def diff(self, a_rev="HEAD", b_rev=None, targets=None):
if self.scm.no_commits:
return {}
from dvc.fs.dvc import DvcFileSystem
from dvc.fs.dvc import DVCFileSystem
dvcfs = DvcFileSystem(repo=self)
dvcfs = DVCFileSystem(repo=self)
targets = ensure_list(targets)
targets = [dvcfs.from_os_path(target) for target in targets]
+2 -2
View File
@@ -4,7 +4,7 @@ from typing import TYPE_CHECKING, Optional
from dvc.exceptions import PathMissingError
if TYPE_CHECKING:
from dvc.fs.dvc import DvcFileSystem
from dvc.fs.dvc import DVCFileSystem
from . import Repo
@@ -55,7 +55,7 @@ def ls(
def _ls(
repo: "Repo", path: str, recursive: bool = None, dvc_only: bool = False
):
fs: "DvcFileSystem" = repo.dvcfs
fs: "DVCFileSystem" = repo.dvcfs
fs_path = fs.from_os_path(path)
try:
+2 -2
View File
@@ -4,7 +4,7 @@ from typing import List
from scmrepo.exceptions import SCMError
from dvc.fs.dvc import DvcFileSystem
from dvc.fs.dvc import DVCFileSystem
from dvc.output import Output
from dvc.repo import locked
from dvc.repo.collect import StrPaths, collect
@@ -77,7 +77,7 @@ def _read_metric(path, fs, rev, **kwargs):
def _read_metrics(repo, metrics, rev, onerror=None):
fs = DvcFileSystem(repo=repo)
fs = DVCFileSystem(repo=repo)
relpath = ""
if repo.root_dir != repo.fs.path.getcwd():
+4 -4
View File
@@ -152,9 +152,9 @@ class Plots:
props: Optional[Dict] = None,
onerror: Optional[Callable] = None,
):
from dvc.fs.dvc import DvcFileSystem
from dvc.fs.dvc import DVCFileSystem
fs = DvcFileSystem(repo=self.repo)
fs = DVCFileSystem(repo=self.repo)
props = props or {}
@@ -472,9 +472,9 @@ def _collect_definitions(
result: Dict = defaultdict(dict)
props = props or {}
from dvc.fs.dvc import DvcFileSystem
from dvc.fs.dvc import DVCFileSystem
fs = DvcFileSystem(repo=repo)
fs = DVCFileSystem(repo=repo)
if not config_files:
dpath.util.merge(
+3 -3
View File
@@ -1,7 +1,7 @@
import pytest
from dvc import api
from dvc.api import DvcFileSystem
from dvc.api import DVCFileSystem
from dvc.utils.fs import remove
@@ -38,7 +38,7 @@ class TestAPI:
)
def test_filesystem(
self,
M,
M, # from `pytest-test-utils`
tmp_dir,
make_tmp_dir,
scm,
@@ -59,7 +59,7 @@ class TestAPI:
path=tmp_dir, posixpath=tmp_dir.as_posix()
)
fs = DvcFileSystem(**fs_kwargs)
fs = DVCFileSystem(**fs_kwargs)
assert fs.ls("/", detail=False) == M.unordered(
"/.gitignore", "/scripts", "/data"
+1 -1
View File
@@ -71,7 +71,7 @@ class TestRemote:
_check_status(status_dir, ok=dir_hashes)
# Remove and check status
remove(dvc.odb.local.path)
dvc.odb.local.clear()
status = dvc.cloud.status(foo_hashes)
_check_status(status, deleted={foo_hash})
+10 -5
View File
@@ -63,12 +63,13 @@ install_requires =
pyparsing>=2.4.7
typing-extensions>=3.7.4
scmrepo==0.1.1
dvc-render==0.0.10
dvc-render==0.0.11
dvc-task==0.1.2
dvclive>=0.10.0
dvc-data==0.8.0
dvc-data==0.10.0
dvc-http==2.19.1
hydra-core>=1.1.0
iterative-telemetry==0.0.5
[options.extras_require]
all =
@@ -86,7 +87,7 @@ dev =
%(tests)s
dvc-data[cli]
# Extra dependencies for remote integrations
azure = dvc-azure==2.20.2
azure = dvc-azure==2.20.4
gdrive = dvc-gdrive==2.19.0
gs = dvc-gs==2.19.1
hdfs =
@@ -103,6 +104,8 @@ webhdfs = dvc-webhdfs==2.19.0
# requests-kerberos requires krb5 & gssapi, which does not provide wheels Linux
webhdfs_kerberos = dvc-webhdfs[kerberos]==2.19.0
terraform = tpi[ssh]>=2.1.0
testing =
pytest-test-utils==0.0.8
tests =
%(terraform)s
dvc-ssh==2.19.0
@@ -112,7 +115,7 @@ tests =
pytest-xdist==2.5.0
pytest-mock==3.8.2
pytest-lazy-fixture==0.6.3
pytest-test-utils==0.0.8
%(testing)s
# https://github.com/docker/docker-py/issues/2902
pytest-docker==0.11.0; python_version < '3.10' or sys_platform != 'win32'
flaky==3.7.0
@@ -122,6 +125,8 @@ tests =
pylint==2.15.2
# we use this to suppress pytest-related false positives in our tests.
pylint-pytest==1.1.2
# see https://github.com/PyCQA/pylint/issues/7488
astroid==2.12.9
# we use this to suppress some messages in tests, eg: foo/bar naming,
# and, protected method calls in our tests
pylint-plugin-utils==0.7
@@ -146,7 +151,7 @@ exclude =
console_scripts =
dvc = dvc.cli:main
fsspec.specs =
dvc = dvc.api:DvcFileSystem
dvc = dvc.api:DVCFileSystem
[flake8]
ignore=
+9 -7
View File
@@ -453,7 +453,9 @@ class TestAddCommit(TestDvc):
ret = main(["commit", self.FOO + ".dvc"])
self.assertEqual(ret, 0)
self.assertTrue(os.path.isfile(self.FOO))
self.assertEqual(len(os.listdir(self.dvc.odb.local.path)), 1)
self.assertTrue(
self.dvc.odb.local.exists("acbd18db4cc2f85cedef654fccc4a4d8")
)
def test_should_collect_dir_cache_only_once(mocker, tmp_dir, dvc):
@@ -832,9 +834,9 @@ def test_add_symlink_file(tmp_dir, dvc):
assert (tmp_dir / "dir" / "foo").read_text() == "bar"
assert (tmp_dir / "dir" / "bar").read_text() == "bar"
assert (tmp_dir / ".dvc" / "cache").read_text() == {
"37": {"b51d194a7513e45b56f6524f2d51f2": "bar"}
}
assert (
tmp_dir / ".dvc" / "cache" / "37" / "b51d194a7513e45b56f6524f2d51f2"
).read_text() == "bar"
assert not (
tmp_dir / ".dvc" / "cache" / "37" / "b51d194a7513e45b56f6524f2d51f2"
).is_symlink()
@@ -891,9 +893,9 @@ def test_add_with_cache_link_error(tmp_dir, dvc, mocker, capsys):
assert (tmp_dir / "foo").exists()
assert (tmp_dir / "foo.dvc").exists()
assert (tmp_dir / ".dvc" / "cache").read_text() == {
"ac": {"bd18db4cc2f85cedef654fccc4a4d8": "foo"}
}
assert (
tmp_dir / ".dvc" / "cache" / "ac" / "bd18db4cc2f85cedef654fccc4a4d8"
).read_text() == "foo"
def test_add_preserve_fields(tmp_dir, dvc):
+10 -9
View File
@@ -49,7 +49,7 @@ def test_cloud_cli(tmp_dir, dvc, remote, mocker):
for (_args, _kwargs) in oids_exist.call_args_list
)
remove(dvc.odb.local.path)
dvc.odb.local.clear()
oids_exist.reset_mock()
assert main(["fetch"] + args) == 0
@@ -164,7 +164,7 @@ def test_missing_cache(tmp_dir, dvc, local_remote, caplog):
tmp_dir.dvc_gen({"foo": "foo", "bar": "bar"})
# purge cache
remove(dvc.odb.local.path)
dvc.odb.local.clear()
header = (
"Some of the cache files do not exist "
@@ -205,7 +205,7 @@ def test_verify_hashes(
# remove artifacts and cache to trigger fetching
remove("file")
remove("dir")
remove(dvc.odb.local.path)
dvc.odb.local.clear()
hash_spy = mocker.spy(dvc_data.hashfile.hash, "file_md5")
@@ -213,7 +213,7 @@ def test_verify_hashes(
assert hash_spy.call_count == 0
# Removing cache will invalidate existing state entries
remove(dvc.odb.local.path)
dvc.odb.local.clear()
dvc.config["remote"]["upstream"]["verify"] = True
@@ -310,18 +310,19 @@ def test_pull_external_dvc_imports_mixed(
def clean(outs, dvc=None):
if dvc:
outs = outs + [dvc.odb.local.path]
dvc.odb.local.clear()
for path in outs:
print(path)
remove(path)
if dvc:
os.makedirs(dvc.odb.local.path, exist_ok=True)
clean_repos()
def recurse_list_dir(d):
return [
os.path.join(d, f) for _, _, filenames in os.walk(d) for f in filenames
os.path.join(root, f)
for root, _, filenames in os.walk(d)
for f in filenames
]
@@ -488,11 +489,11 @@ def test_push_pull_fetch_pipeline_stages(tmp_dir, dvc, run_copy, local_remote):
dvc.pull("copy-foo-bar")
assert (tmp_dir / "bar").exists()
assert len(recurse_list_dir(dvc.odb.local.path)) == 1
assert len(recurse_list_dir(dvc.odb.local.path)) == 2
clean(["bar"], dvc)
dvc.fetch("copy-foo-bar")
assert len(recurse_list_dir(dvc.odb.local.path)) == 1
assert len(recurse_list_dir(dvc.odb.local.path)) == 2
def test_pull_partial(tmp_dir, dvc, local_remote):
+1 -3
View File
@@ -421,8 +421,6 @@ def test_run_dvcignored_dep(tmp_dir, dvc, run_copy):
def test_pull_ignore(tmp_dir, dvc, local_cloud):
from dvc.utils.fs import remove
tmp_dir.dvc_gen(
{
".dvcignore": "data/processed/",
@@ -437,7 +435,7 @@ def test_pull_ignore(tmp_dir, dvc, local_cloud):
foo_path.unlink()
assert not foo_path.exists()
remove(tmp_dir / ".dvc/cache")
dvc.odb.local.clear()
dvc.pull()
assert foo_path.exists()
+18 -37
View File
@@ -112,18 +112,15 @@ def test_shared_cache_dir(tmp_dir):
assert not os.path.exists(os.path.join("dir1", ".dvc", "cache"))
assert not os.path.exists(os.path.join("dir2", ".dvc", "cache"))
subdirs = list(
filter(
lambda x: os.path.isdir(os.path.join(cache_dir, x)),
os.listdir(cache_dir),
)
assert os.path.exists(
os.path.join(cache_dir, "dc", "f6c2fa538b445a3a095255c3641dfc")
)
assert os.path.exists(
os.path.join(cache_dir, "b4", "333c8cfa2ebba7ef20ec6c3265902b")
)
assert os.path.exists(
os.path.join(cache_dir, "9e", "fab2399c7c560b34de477b9aa0a465")
)
assert len(subdirs) == 3
assert len(os.listdir(os.path.join(cache_dir, subdirs[0]))) == 1
assert len(os.listdir(os.path.join(cache_dir, subdirs[1]))) == 1
assert len(os.listdir(os.path.join(cache_dir, subdirs[2]))) == 1
def test_cache_link_type(tmp_dir, scm, dvc):
@@ -167,10 +164,9 @@ def test_cmd_cache_relative_path(tmp_dir, scm, dvc, make_tmp_dir):
tmp_dir.dvc_gen({"foo": "foo"})
subdirs = os.listdir(cache_dir)
assert len(subdirs) == 1
files = os.listdir(os.path.join(cache_dir, subdirs[0]))
assert len(files) == 1
assert os.path.exists(
os.path.join(cache_dir, "ac", "bd18db4cc2f85cedef654fccc4a4d8")
)
def test_default_cache_type(dvc):
@@ -194,28 +190,13 @@ def test_shared_cache(tmp_dir, dvc, group):
{"file": "file content", "dir": {"file2": "file 2 " "content"}}
)
actual = {}
for root, dnames, fnames in os.walk(cache_dir):
for name in dnames + fnames:
path = os.path.join(root, name)
actual[path] = oct(stat.S_IMODE(os.stat(path).st_mode))
file_mode = oct(0o444)
dir_mode = oct(0o2775 if group else (0o777 & ~system.umask))
for root, dnames, fnames in os.walk(cache_dir):
for dname in dnames:
path = os.path.join(root, dname)
assert oct(stat.S_IMODE(os.stat(path).st_mode)) == dir_mode
expected = {
os.path.join(cache_dir, "17"): dir_mode,
os.path.join(
cache_dir, "17", "4eaa1dd94050255b7b98a7e1924b31.dir"
): file_mode,
os.path.join(cache_dir, "97"): dir_mode,
os.path.join(
cache_dir, "97", "e17781c198500e2766ea56bd697c03"
): file_mode,
os.path.join(cache_dir, "d1"): dir_mode,
os.path.join(
cache_dir, "d1", "0b4c3ff123b26dc068d43a8bef2d23"
): file_mode,
}
assert expected == actual
for fname in fnames:
path = os.path.join(root, fname)
assert oct(stat.S_IMODE(os.stat(path).st_mode)) == file_mode
+1 -1
View File
@@ -201,7 +201,7 @@ def test_partial_push_n_pull(tmp_dir, dvc, tmp_path_factory, local_remote):
# Push everything and delete local cache
dvc.push()
remove(dvc.odb.local.path)
dvc.odb.local.clear()
baz._collect_used_dir_cache()
with patch.object(generic, "transfer", side_effect=Exception):
+1 -1
View File
@@ -726,7 +726,7 @@ class TestRunCommit(TestDvc):
ret = main(["commit", fname + ".dvc"])
self.assertEqual(ret, 0)
self.assertTrue(os.path.isfile(fname))
self.assertEqual(len(os.listdir(self.dvc.odb.local.path)), 1)
self.assertEqual(len(list(self.dvc.odb.local.all())), 1)
class TestRunPersist(TestDvc):
+2 -2
View File
@@ -50,7 +50,7 @@ def test_open_dirty_hash(tmp_dir, dvc):
fs = DataFileSystem(index=dvc.index.data["repo"])
with fs.open("file", "r") as fobj:
# NOTE: Unlike DvcFileSystem, DataFileSystem should not
# NOTE: Unlike DVCFileSystem, DataFileSystem should not
# be affected by a dirty workspace.
assert fobj.read() == "file"
@@ -71,7 +71,7 @@ def test_open_dirty_no_hash(tmp_dir, dvc):
(tmp_dir / "file.dvc").write_text("outs:\n- path: file\n")
fs = DataFileSystem(index=dvc.index.data["repo"])
# NOTE: Unlike DvcFileSystem, DataFileSystem should not
# NOTE: Unlike DVCFileSystem, DataFileSystem should not
# be affected by a dirty workspace.
with pytest.raises(FileNotFoundError):
with fs.open("file", "r"):
+30 -30
View File
@@ -5,7 +5,7 @@ from unittest import mock
import pytest
from dvc.fs.dvc import DvcFileSystem
from dvc.fs.dvc import DVCFileSystem
from dvc.testing.tmp_dir import make_subrepo
from dvc_data.hashfile.build import build
from dvc_data.hashfile.hash_info import HashInfo
@@ -16,7 +16,7 @@ def test_exists(tmp_dir, dvc):
dvc.add("foo")
(tmp_dir / "foo").unlink()
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
assert fs.exists("foo")
@@ -25,7 +25,7 @@ def test_open(tmp_dir, dvc):
dvc.add("foo")
(tmp_dir / "foo").unlink()
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
with fs.open("foo", "r") as fobj:
assert fobj.read() == "foo"
@@ -34,7 +34,7 @@ def test_open_dirty_hash(tmp_dir, dvc):
tmp_dir.dvc_gen("file", "file")
(tmp_dir / "file").write_text("something")
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
with fs.open("file", "r") as fobj:
assert fobj.read() == "something"
@@ -43,7 +43,7 @@ def test_open_dirty_no_hash(tmp_dir, dvc):
tmp_dir.gen("file", "file")
(tmp_dir / "file.dvc").write_text("outs:\n- path: file\n")
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
with fs.open("file", "r") as fobj:
assert fobj.read() == "file"
@@ -63,7 +63,7 @@ def test_open_in_history(tmp_dir, scm, dvc):
if rev == "workspace":
continue
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
with fs.open("foo", "r") as fobj:
assert fobj.read() == "foo"
@@ -86,7 +86,7 @@ def test_isdir_isfile(tmp_dir, dvc):
},
)
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
assert fs.isdir("datadir")
assert not fs.isfile("datadir")
assert not fs.isdvc("datadir")
@@ -107,7 +107,7 @@ def test_isdir_isfile(tmp_dir, dvc):
(tmp_dir / "datafile").unlink()
(tmp_dir / "subdir" / "baz").unlink()
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
assert fs.isdir("datadir")
assert not fs.isfile("datadir")
assert fs.isdvc("datadir")
@@ -127,7 +127,7 @@ def test_exists_isdir_isfile_dirty(tmp_dir, dvc):
{"datafile": "data", "datadir": {"foo": "foo", "bar": "bar"}}
)
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
shutil.rmtree(tmp_dir / "datadir")
(tmp_dir / "datafile").unlink()
@@ -162,7 +162,7 @@ def test_isdir_mixed(tmp_dir, dvc):
dvc.add(str(tmp_dir / "dir" / "foo"))
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
assert fs.isdir("dir")
assert not fs.isfile("dir")
@@ -192,7 +192,7 @@ def test_walk(tmp_dir, dvc, dvcfiles, extra_expected):
)
dvc.add(str(tmp_dir / "dir"), recursive=True)
tmp_dir.gen({"dir": {"foo": "foo", "bar": "bar"}})
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
expected = [
"dir/subdir1",
@@ -227,7 +227,7 @@ def test_walk_dirty(tmp_dir, dvc):
tmp_dir.gen({"dir": {"bar": "bar", "subdir3": {"foo3": "foo3"}}})
(tmp_dir / "dir" / "foo").unlink()
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
expected = [
"dir/subdir1",
"dir/subdir2",
@@ -253,7 +253,7 @@ def test_walk_dirty_cached_dir(tmp_dir, scm, dvc):
tmp_dir.dvc_gen({"data": {"foo": "foo", "bar": "bar"}}, commit="add data")
(tmp_dir / "data" / "foo").unlink()
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
actual = []
for root, dirs, files in fs.walk("data"):
@@ -277,7 +277,7 @@ def test_walk_mixed_dir(tmp_dir, scm, dvc):
)
tmp_dir.scm.commit("add dir")
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
expected = [
"dir/foo",
@@ -294,7 +294,7 @@ def test_walk_mixed_dir(tmp_dir, scm, dvc):
def test_walk_missing(tmp_dir, dvc):
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
for _ in fs.walk("dir"):
pass
@@ -302,7 +302,7 @@ def test_walk_missing(tmp_dir, dvc):
def test_walk_not_a_dir(tmp_dir, dvc):
tmp_dir.dvc_gen("foo", "foo")
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
for _ in fs.walk("foo"):
pass
@@ -312,7 +312,7 @@ def test_isdvc(tmp_dir, dvc):
tmp_dir.gen({"foo": "foo", "bar": "bar", "dir": {"baz": "baz"}})
dvc.add("foo")
dvc.add("dir")
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
assert fs.isdvc("foo")
assert not fs.isdvc("bar")
assert fs.isdvc("dir")
@@ -322,7 +322,7 @@ def test_isdvc(tmp_dir, dvc):
def test_subrepos(tmp_dir, scm, dvc, mocker):
tmp_dir.scm_gen(
{"dir": {"repo.txt": "file to confuse DvcFileSystem"}},
{"dir": {"repo.txt": "file to confuse DVCFileSystem"}},
commit="dir/repo.txt",
)
@@ -340,7 +340,7 @@ def test_subrepos(tmp_dir, scm, dvc, mocker):
)
dvc._reset()
fs = DvcFileSystem(repo=dvc, subrepos=True)
fs = DVCFileSystem(repo=dvc, subrepos=True)
def assert_fs_belongs_to_repo(ret_val):
method = fs.fs._get_repo
@@ -400,7 +400,7 @@ def test_subrepos(tmp_dir, scm, dvc, mocker):
)
def test_subrepo_walk(tmp_dir, scm, dvc, dvcfiles, extra_expected):
tmp_dir.scm_gen(
{"dir": {"repo.txt": "file to confuse DvcFileSystem"}},
{"dir": {"repo.txt": "file to confuse DVCFileSystem"}},
commit="dir/repo.txt",
)
@@ -420,7 +420,7 @@ def test_subrepo_walk(tmp_dir, scm, dvc, dvcfiles, extra_expected):
# using fs that does not have dvcignore
dvc._reset()
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
expected = [
"dir/repo",
"dir/repo.txt",
@@ -451,7 +451,7 @@ def test_subrepo_walk(tmp_dir, scm, dvc, dvcfiles, extra_expected):
def test_dvcfs_no_subrepos(tmp_dir, dvc, scm):
tmp_dir.scm_gen(
{"dir": {"repo.txt": "file to confuse DvcFileSystem"}},
{"dir": {"repo.txt": "file to confuse DVCFileSystem"}},
commit="dir/repo.txt",
)
tmp_dir.dvc_gen({"lorem": "lorem"}, commit="add foo")
@@ -464,7 +464,7 @@ def test_dvcfs_no_subrepos(tmp_dir, dvc, scm):
# using fs that does not have dvcignore
dvc._reset()
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
expected = [
"/.dvcignore",
"/.gitignore",
@@ -496,7 +496,7 @@ def test_dvcfs_no_subrepos(tmp_dir, dvc, scm):
def test_get_hash_cached_file(tmp_dir, dvc, mocker):
tmp_dir.dvc_gen({"foo": "foo"})
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
expected = "acbd18db4cc2f85cedef654fccc4a4d8"
assert fs.info("foo").get("md5") is None
_, _, obj = build(dvc.odb.local, "foo", fs, "md5")
@@ -509,7 +509,7 @@ def test_get_hash_cached_dir(tmp_dir, dvc, mocker):
tmp_dir.dvc_gen(
{"dir": {"foo": "foo", "bar": "bar", "subdir": {"data": "data"}}}
)
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
expected = "8761c4e9acad696bee718615e23e22db.dir"
assert fs.info("dir").get("md5") is None
_, _, obj = build(dvc.odb.local, "dir", fs, "md5")
@@ -529,7 +529,7 @@ def test_get_hash_cached_granular(tmp_dir, dvc, mocker):
tmp_dir.dvc_gen(
{"dir": {"foo": "foo", "bar": "bar", "subdir": {"data": "data"}}}
)
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
subdir = "dir/subdir"
assert fs.info(subdir).get("md5") is None
_, _, obj = build(dvc.odb.local, subdir, fs, "md5")
@@ -558,7 +558,7 @@ def test_get_hash_mixed_dir(tmp_dir, scm, dvc):
)
tmp_dir.scm.commit("add dir")
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
_, _, obj = build(dvc.odb.local, "dir", fs, "md5")
assert obj.hash_info == HashInfo(
"md5", "e1d9e8eae5374860ae025ec84cfd85c7.dir"
@@ -577,7 +577,7 @@ def test_get_hash_dirty_file(tmp_dir, dvc):
# file is modified in workspace
# hash_file(file) should return workspace hash, not DVC cached hash
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
assert fs.info("file").get("md5") is None
staging, _, obj = build(dvc.odb.local, "file", fs, "md5")
assert obj.hash_info == something_hash_info
@@ -599,7 +599,7 @@ def test_get_hash_dirty_dir(tmp_dir, dvc):
tmp_dir.dvc_gen({"dir": {"foo": "foo", "bar": "bar"}})
(tmp_dir / "dir" / "baz").write_text("baz")
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
_, meta, obj = build(dvc.odb.local, "dir", fs, "md5")
assert obj.hash_info == HashInfo(
"md5", "ba75a2162ca9c29acecb7957105a0bc2.dir"
@@ -661,7 +661,7 @@ def test_walk_nested_subrepos(tmp_dir, dvc, scm, traverse_subrepos):
expected["/subrepo1"].add("subrepo3")
actual = {}
fs = DvcFileSystem(repo=dvc)
fs = DVCFileSystem(repo=dvc)
for root, dirs, files in fs.walk(
"/", ignore_subrepos=not traverse_subrepos
):
+2 -2
View File
@@ -2,7 +2,7 @@ import os
import pytest
from dvc.fs.dvc import DvcFileSystem
from dvc.fs.dvc import DVCFileSystem
from dvc.testing.tmp_dir import make_subrepo
@@ -38,7 +38,7 @@ def dvcfs(tmp_dir, dvc, scm):
tmp_dir.scm_gen(fs_structure, commit="repo init")
tmp_dir.dvc_gen(dvc_structure, commit="use dvc")
yield DvcFileSystem(repo=dvc, subrepos=True)
yield DVCFileSystem(repo=dvc, subrepos=True)
def test_info_not_existing(dvcfs):
+5 -8
View File
@@ -14,7 +14,11 @@ def tmp_global_dir(mocker, tmp_path):
"""
Fixture to prevent modifying the actual global config
"""
mocker.patch("dvc.config.Config.get_dir", return_value=str(tmp_path))
def _user_config_dir(appname, *_args, **_kwargs):
return str(tmp_path / appname)
mocker.patch("iterative_telemetry.user_config_dir", _user_config_dir)
def test_collect_and_send_report(mocker, tmp_global_dir):
@@ -155,10 +159,3 @@ def test_system_info():
)
assert schema(analytics._system_info())
def test_find_or_create_user_id(tmp_global_dir):
created = analytics._find_or_create_user_id()
found = analytics._find_or_create_user_id()
assert created == found