Skip to content

Commit bbb1c59

Browse files
authored
deps/outs: get rid of remotes in favor of trees (#4208)
Outputs and dependencies don't really care about the remotes, as they don't do any pushing or pulling. What they really need are the trees, so let's use them directly. Part of #4050
1 parent 58f6534 commit bbb1c59

File tree

10 files changed

+45
-49
lines changed

10 files changed

+45
-49
lines changed

dvc/dependency/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from dvc.dependency.s3 import S3Dependency
1313
from dvc.dependency.ssh import SSHDependency
1414
from dvc.output.base import BaseOutput
15-
from dvc.remote import get_remote
15+
from dvc.remote import get_cloud_tree
1616
from dvc.scheme import Schemes
1717

1818
from .repo import RepoDependency
@@ -54,8 +54,8 @@
5454
def _get(stage, p, info):
5555
parsed = urlparse(p) if p else None
5656
if parsed and parsed.scheme == "remote":
57-
remote = get_remote(stage.repo, name=parsed.netloc)
58-
return DEP_MAP[remote.scheme](stage, p, info, remote=remote)
57+
tree = get_cloud_tree(stage.repo, name=parsed.netloc)
58+
return DEP_MAP[tree.scheme](stage, p, info, tree=tree)
5959

6060
if info and info.get(RepoDependency.PARAM_REPO):
6161
repo = info.pop(RepoDependency.PARAM_REPO)

dvc/dependency/repo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def __init__(self, def_repo, stage, *args, **kwargs):
2626
self.def_repo = def_repo
2727
super().__init__(stage, *args, **kwargs)
2828

29-
def _parse_path(self, remote, path):
29+
def _parse_path(self, tree, path):
3030
return None
3131

3232
@property

dvc/output/__init__.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from dvc.output.local import LocalOutput
1111
from dvc.output.s3 import S3Output
1212
from dvc.output.ssh import SSHOutput
13-
from dvc.remote import get_remote
13+
from dvc.remote import get_cloud_tree
1414
from dvc.remote.hdfs import HDFSRemoteTree
1515
from dvc.remote.local import LocalRemoteTree
1616
from dvc.remote.s3 import S3RemoteTree
@@ -66,13 +66,13 @@ def _get(
6666
parsed = urlparse(p)
6767

6868
if parsed.scheme == "remote":
69-
remote = get_remote(stage.repo, name=parsed.netloc)
70-
return OUTS_MAP[remote.scheme](
69+
tree = get_cloud_tree(stage.repo, name=parsed.netloc)
70+
return OUTS_MAP[tree.scheme](
7171
stage,
7272
p,
7373
info,
7474
cache=cache,
75-
remote=remote,
75+
tree=tree,
7676
metric=metric,
7777
plot=plot,
7878
persist=persist,
@@ -85,7 +85,7 @@ def _get(
8585
p,
8686
info,
8787
cache=cache,
88-
remote=None,
88+
tree=None,
8989
metric=metric,
9090
plot=plot,
9191
persist=persist,
@@ -95,7 +95,7 @@ def _get(
9595
p,
9696
info,
9797
cache=cache,
98-
remote=None,
98+
tree=None,
9999
metric=metric,
100100
plot=plot,
101101
persist=persist,

dvc/output/base.py

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
DvcException,
1313
RemoteCacheRequiredError,
1414
)
15-
from dvc.remote.base import BaseRemoteTree, Remote
15+
from dvc.remote.base import BaseRemoteTree
1616

1717
logger = logging.getLogger(__name__)
1818

@@ -47,7 +47,6 @@ def __init__(self, path):
4747
class BaseOutput:
4848
IS_DEPENDENCY = False
4949

50-
REMOTE_CLS = Remote
5150
TREE_CLS = BaseRemoteTree
5251

5352
PARAM_PATH = "path"
@@ -85,7 +84,7 @@ def __init__(
8584
stage,
8685
path,
8786
info=None,
88-
remote=None,
87+
tree=None,
8988
cache=True,
9089
metric=False,
9190
plot=False,
@@ -106,24 +105,23 @@ def __init__(
106105
self.repo = stage.repo if stage else None
107106
self.def_path = path
108107
self.info = info
109-
if remote:
110-
self.remote = remote
108+
if tree:
109+
self.tree = tree
111110
else:
112-
tree = self.TREE_CLS(self.repo, {})
113-
self.remote = self.REMOTE_CLS(tree)
111+
self.tree = self.TREE_CLS(self.repo, {})
114112
self.use_cache = False if self.IS_DEPENDENCY else cache
115113
self.metric = False if self.IS_DEPENDENCY else metric
116114
self.plot = False if self.IS_DEPENDENCY else plot
117115
self.persist = persist
118116

119-
self.path_info = self._parse_path(remote, path)
117+
self.path_info = self._parse_path(tree, path)
120118
if self.use_cache and self.cache is None:
121119
raise RemoteCacheRequiredError(self.path_info)
122120

123-
def _parse_path(self, remote, path):
124-
if remote:
121+
def _parse_path(self, tree, path):
122+
if tree:
125123
parsed = urlparse(path)
126-
return remote.path_info / parsed.path.lstrip("/")
124+
return tree.path_info / parsed.path.lstrip("/")
127125
return self.TREE_CLS.PATH_CLS(path)
128126

129127
def __repr__(self):
@@ -167,29 +165,29 @@ def cache_path(self):
167165

168166
@property
169167
def checksum_type(self):
170-
return self.remote.tree.PARAM_CHECKSUM
168+
return self.tree.PARAM_CHECKSUM
171169

172170
@property
173171
def checksum(self):
174-
return self.info.get(self.remote.tree.PARAM_CHECKSUM)
172+
return self.info.get(self.tree.PARAM_CHECKSUM)
175173

176174
@checksum.setter
177175
def checksum(self, checksum):
178-
self.info[self.remote.tree.PARAM_CHECKSUM] = checksum
176+
self.info[self.tree.PARAM_CHECKSUM] = checksum
179177

180178
def get_checksum(self):
181-
return self.remote.get_hash(self.path_info)
179+
return self.tree.get_hash(self.path_info)
182180

183181
@property
184182
def is_dir_checksum(self):
185-
return self.remote.is_dir_hash(self.checksum)
183+
return self.tree.is_dir_hash(self.checksum)
186184

187185
@property
188186
def exists(self):
189-
return self.remote.tree.exists(self.path_info)
187+
return self.tree.exists(self.path_info)
190188

191189
def save_info(self):
192-
return self.remote.save_info(self.path_info)
190+
return self.tree.save_info(self.path_info)
193191

194192
def changed_checksum(self):
195193
return self.checksum != self.get_checksum()
@@ -222,13 +220,13 @@ def changed(self):
222220

223221
@property
224222
def is_empty(self):
225-
return self.remote.tree.is_empty(self.path_info)
223+
return self.tree.is_empty(self.path_info)
226224

227225
def isdir(self):
228-
return self.remote.tree.isdir(self.path_info)
226+
return self.tree.isdir(self.path_info)
229227

230228
def isfile(self):
231-
return self.remote.tree.isfile(self.path_info)
229+
return self.tree.isfile(self.path_info)
232230

233231
# pylint: disable=no-member
234232

@@ -316,7 +314,7 @@ def verify_metric(self):
316314
raise DvcException(f"verify metric is not supported for {self.scheme}")
317315

318316
def download(self, to):
319-
self.remote.tree.download(self.path_info, to.path_info)
317+
self.tree.download(self.path_info, to.path_info)
320318

321319
def checkout(
322320
self,
@@ -342,7 +340,7 @@ def checkout(
342340
)
343341

344342
def remove(self, ignore_remove=False):
345-
self.remote.tree.remove(self.path_info)
343+
self.tree.remove(self.path_info)
346344
if self.scheme != "local":
347345
return
348346

@@ -354,7 +352,7 @@ def move(self, out):
354352
if self.scheme == "local" and self.use_scm_ignore:
355353
self.repo.scm.ignore_remove(self.fspath)
356354

357-
self.remote.tree.move(self.path_info, out.path_info)
355+
self.tree.move(self.path_info, out.path_info)
358356
self.def_path = out.def_path
359357
self.path_info = out.path_info
360358
self.save()
@@ -373,7 +371,7 @@ def get_files_number(self, filter_info=None):
373371

374372
def unprotect(self):
375373
if self.exists:
376-
self.remote.tree.unprotect(self.path_info)
374+
self.tree.unprotect(self.path_info)
377375

378376
def get_dir_cache(self, **kwargs):
379377
if not self.is_dir_checksum:
@@ -433,8 +431,8 @@ def collect_used_dir_cache(
433431
filter_path = str(filter_info) if filter_info else None
434432
is_win = os.name == "nt"
435433
for entry in self.dir_cache:
436-
checksum = entry[self.remote.tree.PARAM_CHECKSUM]
437-
entry_relpath = entry[self.remote.tree.PARAM_RELPATH]
434+
checksum = entry[self.tree.PARAM_CHECKSUM]
435+
entry_relpath = entry[self.tree.PARAM_RELPATH]
438436
if is_win:
439437
entry_relpath = entry_relpath.replace("/", os.sep)
440438
entry_path = os.path.join(path, entry_relpath)

dvc/output/local.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@
55
from dvc.exceptions import DvcException
66
from dvc.istextfile import istextfile
77
from dvc.output.base import BaseOutput
8-
from dvc.remote.local import LocalRemote, LocalRemoteTree
8+
from dvc.remote.local import LocalRemoteTree
99
from dvc.utils import relpath
1010
from dvc.utils.fs import path_isin
1111

1212
logger = logging.getLogger(__name__)
1313

1414

1515
class LocalOutput(BaseOutput):
16-
REMOTE_CLS = LocalRemote
1716
TREE_CLS = LocalRemoteTree
1817
sep = os.sep
1918

@@ -23,10 +22,10 @@ def __init__(self, stage, path, *args, **kwargs):
2322

2423
super().__init__(stage, path, *args, **kwargs)
2524

26-
def _parse_path(self, remote, path):
25+
def _parse_path(self, tree, path):
2726
parsed = urlparse(path)
2827
if parsed.scheme == "remote":
29-
p = remote.path_info / parsed.path.lstrip("/")
28+
p = tree.path_info / parsed.path.lstrip("/")
3029
else:
3130
# NOTE: we can path either from command line or .dvc file,
3231
# so we should expect both posix and windows style paths.

dvc/output/ssh.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from dvc.output.base import BaseOutput
2-
from dvc.remote.ssh import SSHRemote, SSHRemoteTree
2+
from dvc.remote.ssh import SSHRemoteTree
33

44

55
class SSHOutput(BaseOutput):
6-
REMOTE_CLS = SSHRemote
76
TREE_CLS = SSHRemoteTree

dvc/repo/tree.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ def _get_granular_checksum(self, path, out, remote=None):
4949
raise FileNotFoundError
5050
dir_cache = out.get_dir_cache(remote=remote)
5151
for entry in dir_cache:
52-
entry_relpath = entry[out.remote.tree.PARAM_RELPATH]
52+
entry_relpath = entry[out.tree.PARAM_RELPATH]
5353
if os.name == "nt":
5454
entry_relpath = entry_relpath.replace("/", os.sep)
5555
if path == out.path_info / entry_relpath:
56-
return entry[out.remote.tree.PARAM_CHECKSUM]
56+
return entry[out.tree.PARAM_CHECKSUM]
5757
raise FileNotFoundError
5858

5959
def open(
@@ -156,7 +156,7 @@ def _add_dir(self, top, trie, out, download_callback=None, **kwargs):
156156
download_callback(downloaded)
157157

158158
for entry in dir_cache:
159-
entry_relpath = entry[out.remote.tree.PARAM_RELPATH]
159+
entry_relpath = entry[out.tree.PARAM_RELPATH]
160160
if os.name == "nt":
161161
entry_relpath = entry_relpath.replace("/", os.sep)
162162
path_info = out.path_info / entry_relpath

tests/func/test_tree.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ def test_repotree_walk_fetch(tmp_dir, dvc, scm, local_remote):
192192

193193
assert os.path.exists(out.cache_path)
194194
for entry in out.dir_cache:
195-
hash_ = entry[out.remote.tree.PARAM_CHECKSUM]
195+
hash_ = entry[out.tree.PARAM_CHECKSUM]
196196
assert os.path.exists(dvc.cache.local.hash_to_path_info(hash_))
197197

198198

tests/unit/dependency/test_local.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ def _get_dependency(self):
1515

1616
def test_save_missing(self):
1717
d = self._get_dependency()
18-
with mock.patch.object(d.remote.tree, "exists", return_value=False):
18+
with mock.patch.object(d.tree, "exists", return_value=False):
1919
with self.assertRaises(d.DoesNotExistError):
2020
d.save()

tests/unit/output/test_local.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def _get_output(self):
1919

2020
def test_save_missing(self):
2121
o = self._get_output()
22-
with patch.object(o.remote.tree, "exists", return_value=False):
22+
with patch.object(o.tree, "exists", return_value=False):
2323
with self.assertRaises(o.DoesNotExistError):
2424
o.save()
2525

0 commit comments

Comments
 (0)