dvc-objects 1.3.1__tar.gz → 1.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dvc-objects-1.3.1/src/dvc_objects.egg-info → dvc-objects-1.4.0}/PKG-INFO +3 -1
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/noxfile.py +8 -4
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/pyproject.toml +4 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects/executors.py +6 -1
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects/fs/generic.py +1 -1
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects/fs/system.py +16 -6
- {dvc-objects-1.3.1 → dvc-objects-1.4.0/src/dvc_objects.egg-info}/PKG-INFO +3 -1
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects.egg-info/SOURCES.txt +1 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects.egg-info/requires.txt +2 -0
- dvc-objects-1.4.0/tests/benchmarks/test_fs.py +42 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/.cruft.json +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/.gitattributes +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/.github/dependabot.yml +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/.github/workflows/release.yml +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/.github/workflows/tests.yml +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/.github/workflows/update-template.yaml +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/.gitignore +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/.pre-commit-config.yaml +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/CODE_OF_CONDUCT.rst +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/CONTRIBUTING.rst +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/LICENSE +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/README.rst +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/setup.cfg +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects/__init__.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects/_tqdm.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects/db.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects/errors.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects/fs/__init__.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects/fs/base.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects/fs/callbacks.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects/fs/errors.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects/fs/local.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects/fs/memory.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects/fs/path.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects/fs/scheme.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects/fs/utils.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects/obj.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects/py.typed +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects/transfer.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects/utils.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects.egg-info/dependency_links.txt +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/src/dvc_objects.egg-info/top_level.txt +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/tests/__init__.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/tests/conftest.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/tests/fs/__init__.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/tests/fs/test_callbacks.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/tests/fs/test_localfs.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/tests/fs/test_system.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/tests/fs/test_utils.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/tests/test_odb.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/tests/test_reflink.py +0 -0
- {dvc-objects-1.3.1 → dvc-objects-1.4.0}/tests/test_transfer.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: dvc-objects
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: dvc objects
|
|
5
5
|
Author-email: Iterative <support@dvc.org>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -28,6 +28,8 @@ Requires-Dist: pytest-cov==4.0.0; extra == "tests"
|
|
|
28
28
|
Requires-Dist: pytest-mock==3.8.2; extra == "tests"
|
|
29
29
|
Requires-Dist: mypy==1.5.1; extra == "tests"
|
|
30
30
|
Requires-Dist: pytest-servers[s3]==0.1.3; extra == "tests"
|
|
31
|
+
Requires-Dist: pytest-benchmark; extra == "tests"
|
|
32
|
+
Requires-Dist: reflink; extra == "tests"
|
|
31
33
|
Provides-Extra: dev
|
|
32
34
|
Requires-Dist: dvc-objects[tests]; extra == "dev"
|
|
33
35
|
Requires-Dist: types-tqdm; extra == "dev"
|
|
@@ -8,10 +8,12 @@ nox.options.reuse_existing_virtualenvs = True
|
|
|
8
8
|
nox.options.sessions = "lint", "tests"
|
|
9
9
|
locations = "src", "tests"
|
|
10
10
|
|
|
11
|
+
pip_dev_flags = ["--use-pep517"] # reflink package is still missing wheels
|
|
12
|
+
|
|
11
13
|
|
|
12
14
|
@nox.session(python=["3.8", "3.9", "3.10", "3.11", "pypy3.8", "pypy3.9"])
|
|
13
15
|
def tests(session: nox.Session) -> None:
|
|
14
|
-
session.install(".[tests]")
|
|
16
|
+
session.install(".[tests]", *pip_dev_flags)
|
|
15
17
|
session.run(
|
|
16
18
|
"pytest",
|
|
17
19
|
"--cov",
|
|
@@ -24,7 +26,7 @@ def tests(session: nox.Session) -> None:
|
|
|
24
26
|
@nox.session
|
|
25
27
|
def lint(session: nox.Session) -> None:
|
|
26
28
|
session.install("pre-commit")
|
|
27
|
-
session.install("-e", ".[dev]")
|
|
29
|
+
session.install("-e", ".[dev]", *pip_dev_flags)
|
|
28
30
|
|
|
29
31
|
args = *(session.posargs or ("--show-diff-on-failure",)), "--all-files"
|
|
30
32
|
session.run("pre-commit", "run", *args)
|
|
@@ -34,7 +36,7 @@ def lint(session: nox.Session) -> None:
|
|
|
34
36
|
@nox.session
|
|
35
37
|
def safety(session: nox.Session) -> None:
|
|
36
38
|
"""Scan dependencies for insecure packages."""
|
|
37
|
-
session.install(".[dev]")
|
|
39
|
+
session.install(".[dev]", *pip_dev_flags)
|
|
38
40
|
session.install("safety")
|
|
39
41
|
session.run("safety", "check", "--full-report")
|
|
40
42
|
|
|
@@ -58,4 +60,6 @@ def dev(session: nox.Session) -> None:
|
|
|
58
60
|
session.run("virtualenv", venv_dir, silent=True)
|
|
59
61
|
|
|
60
62
|
python = os.path.join(venv_dir, "bin/python")
|
|
61
|
-
session.run(
|
|
63
|
+
session.run(
|
|
64
|
+
python, "-m", "pip", "install", "-e", ".[dev]", *pip_dev_flags, external=True
|
|
65
|
+
)
|
|
@@ -41,6 +41,8 @@ tests = [
|
|
|
41
41
|
"pytest-mock==3.8.2",
|
|
42
42
|
"mypy==1.5.1",
|
|
43
43
|
"pytest-servers[s3]==0.1.3",
|
|
44
|
+
"pytest-benchmark",
|
|
45
|
+
"reflink",
|
|
44
46
|
]
|
|
45
47
|
dev = [
|
|
46
48
|
"dvc-objects[tests]",
|
|
@@ -98,6 +100,8 @@ ignore_missing_imports = true
|
|
|
98
100
|
module = [
|
|
99
101
|
"fsspec.*",
|
|
100
102
|
"funcy",
|
|
103
|
+
"reflink.*",
|
|
104
|
+
"shortuuid",
|
|
101
105
|
]
|
|
102
106
|
|
|
103
107
|
[tool.codespell]
|
|
@@ -45,10 +45,15 @@ class ThreadPoolExecutor(futures.ThreadPoolExecutor):
|
|
|
45
45
|
It does not create all the futures at once to reduce memory usage.
|
|
46
46
|
"""
|
|
47
47
|
|
|
48
|
+
it = zip(*iterables)
|
|
49
|
+
if self.max_workers == 1:
|
|
50
|
+
for args in it:
|
|
51
|
+
yield fn(*args)
|
|
52
|
+
return
|
|
53
|
+
|
|
48
54
|
def create_taskset(n: int) -> Set[futures.Future]:
|
|
49
55
|
return {self.submit(fn, *args) for args in islice(it, n)}
|
|
50
56
|
|
|
51
|
-
it = zip(*iterables)
|
|
52
57
|
tasks = create_taskset(self.max_workers * 5)
|
|
53
58
|
while tasks:
|
|
54
59
|
done, tasks = futures.wait(tasks, return_when=futures.FIRST_COMPLETED)
|
|
@@ -4,6 +4,7 @@ import os
|
|
|
4
4
|
import platform
|
|
5
5
|
import stat
|
|
6
6
|
import sys
|
|
7
|
+
import functools
|
|
7
8
|
from typing import TYPE_CHECKING
|
|
8
9
|
|
|
9
10
|
if TYPE_CHECKING:
|
|
@@ -36,7 +37,8 @@ def symlink(source: "AnyFSPath", link_name: "AnyFSPath") -> None:
|
|
|
36
37
|
os.symlink(source, link_name)
|
|
37
38
|
|
|
38
39
|
|
|
39
|
-
|
|
40
|
+
@functools.lru_cache(maxsize=1)
|
|
41
|
+
def _clonefile():
|
|
40
42
|
import ctypes
|
|
41
43
|
|
|
42
44
|
def _cdll(name):
|
|
@@ -48,22 +50,30 @@ def _reflink_darwin(src: "AnyFSPath", dst: "AnyFSPath") -> None:
|
|
|
48
50
|
clib = _cdll(LIBC)
|
|
49
51
|
except OSError as exc:
|
|
50
52
|
logger.debug(
|
|
51
|
-
"unable to access '
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
"unable to access '%s' (errno '%d'). Falling back to '%s'.",
|
|
54
|
+
LIBC,
|
|
55
|
+
exc.errno,
|
|
56
|
+
LIBC_FALLBACK,
|
|
54
57
|
)
|
|
55
58
|
if exc.errno != errno.ENOENT:
|
|
56
59
|
raise
|
|
57
60
|
# NOTE: trying to bypass System Integrity Protection (SIP)
|
|
58
61
|
clib = _cdll(LIBC_FALLBACK)
|
|
59
62
|
|
|
60
|
-
|
|
63
|
+
clonefile = getattr(clib, "clonefile", None)
|
|
64
|
+
if clonefile is None:
|
|
61
65
|
raise OSError(
|
|
62
66
|
errno.ENOTSUP,
|
|
63
67
|
"'clonefile' not supported by the standard library",
|
|
64
68
|
)
|
|
65
69
|
|
|
66
|
-
|
|
70
|
+
return clonefile
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _reflink_darwin(src: "AnyFSPath", dst: "AnyFSPath") -> None:
|
|
74
|
+
import ctypes
|
|
75
|
+
|
|
76
|
+
clonefile = _clonefile()
|
|
67
77
|
clonefile.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_int]
|
|
68
78
|
clonefile.restype = ctypes.c_int
|
|
69
79
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: dvc-objects
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: dvc objects
|
|
5
5
|
Author-email: Iterative <support@dvc.org>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -28,6 +28,8 @@ Requires-Dist: pytest-cov==4.0.0; extra == "tests"
|
|
|
28
28
|
Requires-Dist: pytest-mock==3.8.2; extra == "tests"
|
|
29
29
|
Requires-Dist: mypy==1.5.1; extra == "tests"
|
|
30
30
|
Requires-Dist: pytest-servers[s3]==0.1.3; extra == "tests"
|
|
31
|
+
Requires-Dist: pytest-benchmark; extra == "tests"
|
|
32
|
+
Requires-Dist: reflink; extra == "tests"
|
|
31
33
|
Provides-Extra: dev
|
|
32
34
|
Requires-Dist: dvc-objects[tests]; extra == "dev"
|
|
33
35
|
Requires-Dist: types-tqdm; extra == "dev"
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import errno
|
|
2
|
+
import pytest
|
|
3
|
+
import shutil
|
|
4
|
+
from reflink import reflink as pyreflink
|
|
5
|
+
from reflink.error import ReflinkImpossibleError
|
|
6
|
+
from dvc_objects.fs.system import reflink, hardlink, symlink
|
|
7
|
+
|
|
8
|
+
NLINKS = 10000
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@pytest.mark.parametrize(
|
|
12
|
+
"link", [pytest.param(pyreflink, id="pyreflink"), reflink, hardlink, symlink]
|
|
13
|
+
)
|
|
14
|
+
def test_link(benchmark, tmp_path, link):
|
|
15
|
+
(tmp_path / "original").mkdir()
|
|
16
|
+
|
|
17
|
+
for idx in range(NLINKS):
|
|
18
|
+
(tmp_path / "original" / str(idx)).write_text(str(idx))
|
|
19
|
+
|
|
20
|
+
def _setup():
|
|
21
|
+
try:
|
|
22
|
+
shutil.rmtree(tmp_path / "links")
|
|
23
|
+
except FileNotFoundError:
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
(tmp_path / "links").mkdir()
|
|
27
|
+
|
|
28
|
+
original = str(tmp_path / "original")
|
|
29
|
+
links = str(tmp_path / "links")
|
|
30
|
+
|
|
31
|
+
def _link():
|
|
32
|
+
for idx in range(NLINKS):
|
|
33
|
+
try:
|
|
34
|
+
link(f"{original}/{idx}", f"{links}/{idx}")
|
|
35
|
+
except Exception as exc:
|
|
36
|
+
if isinstance(exc, (ReflinkImpossibleError, NotImplementedError)) or (
|
|
37
|
+
isinstance(exc, OSError) and exc.errno == errno.ENOTSUP
|
|
38
|
+
):
|
|
39
|
+
pytest.skip(str(exc))
|
|
40
|
+
raise
|
|
41
|
+
|
|
42
|
+
benchmark.pedantic(_link, setup=_setup)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|