Skip to content

Commit 3e42e01

Browse files
authored
dvc: redefine is_callback as cmd and no outs/deps (#5187)
1 parent 257f584 commit 3e42e01

File tree

7 files changed

+9
-51
lines changed

7 files changed

+9
-51
lines changed

dvc/stage/__init__.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ def is_callback(self):
231231
A callback stage is always considered as changed,
232232
so it runs on every `dvc repro` call.
233233
"""
234-
return not self.is_data_source and len(self.deps) == 0
234+
return self.cmd and not any((self.deps, self.outs))
235235

236236
@property
237237
def is_import(self):
@@ -268,13 +268,7 @@ def changed_deps(self):
268268
if self.frozen:
269269
return False
270270

271-
if self.is_callback:
272-
logger.debug(
273-
"%s has a command but no dependencies", self.addressing
274-
)
275-
return True
276-
277-
if self.always_changed or self.is_checkpoint:
271+
if self.is_callback or self.always_changed or self.is_checkpoint:
278272
return True
279273

280274
return self._changed_deps()

dvc/stage/run.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,7 @@ def _run(stage, executable, cmd, checkpoint_func, **kwargs):
113113

114114

115115
def cmd_run(stage, dry=False, checkpoint_func=None):
116-
logger.info(
117-
"Running %s" "stage '%s':",
118-
"callback " if stage.is_callback else "",
119-
stage.addressing,
120-
)
116+
logger.info("Running stage '%s':", stage.addressing)
121117
commands = _enforce_cmd_list(stage.cmd)
122118
kwargs = prepare_kwargs(stage, checkpoint_func=checkpoint_func)
123119
executable = get_executable()

tests/func/test_lockfile.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,7 @@ def v1_repo_lock(tmp_dir, dvc):
189189

190190
def test_can_read_v1_lockfile(tmp_dir, dvc, v1_repo_lock):
191191
assert dvc.status() == {
192-
"bar": [
193-
{"changed outs": {"bar.txt": "not in cache"}},
194-
"always changed",
195-
],
192+
"bar": [{"changed outs": {"bar.txt": "not in cache"}}],
196193
"foo": ["always changed"],
197194
}
198195

tests/func/test_repro.py

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -266,28 +266,6 @@ def test(self):
266266
self.assertEqual(len(stages), 2)
267267

268268

269-
class TestReproNoDeps(TestRepro):
270-
def test(self):
271-
out = "out"
272-
code_file = "out.py"
273-
stage_file = "out.dvc"
274-
code = (
275-
'import uuid\nwith open("{}", "w+") as fd:\n'
276-
"\tfd.write(str(uuid.uuid4()))\n".format(out)
277-
)
278-
with open(code_file, "w+") as fd:
279-
fd.write(code)
280-
stage = self._run(
281-
fname=stage_file,
282-
outs=[out],
283-
cmd=f"python {code_file}",
284-
name="uuid",
285-
)
286-
287-
stages = self.dvc.reproduce(self._get_stage_target(stage))
288-
self.assertEqual(len(stages), 1)
289-
290-
291269
class TestReproForce(TestRepro):
292270
def test(self):
293271
stages = self.dvc.reproduce(
@@ -572,11 +550,10 @@ class TestReproFrozenCallback(SingleStageRun, TestDvc):
572550
def test(self):
573551
file1 = "file1"
574552
file1_stage = file1 + ".dvc"
575-
# NOTE: purposefully not specifying dependencies
553+
# NOTE: purposefully not specifying deps or outs
576554
# to create a callback stage.
577555
stage = self._run(
578556
fname=file1_stage,
579-
outs=[file1],
580557
cmd=f"python {self.CODE} {self.FOO} {file1}",
581558
name="copy-FOO-file1",
582559
)
@@ -864,6 +841,7 @@ class TestReproAlreadyCached(TestRepro):
864841
def test(self):
865842
stage = self._run(
866843
fname="datetime.dvc",
844+
always_changed=True,
867845
deps=[],
868846
outs=["datetime.txt"],
869847
cmd='python -c "import time; print(time.time())" > datetime.txt',

tests/func/test_repro_multistage.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,6 @@ class TestReproDepDirWithOutputsUnderItMultiStage(
5656
pass
5757

5858

59-
class TestReproNoDepsMultiStage(MultiStageRun, test_repro.TestReproNoDeps):
60-
pass
61-
62-
6359
class TestReproForceMultiStage(MultiStageRun, test_repro.TestReproForce):
6460
pass
6561

tests/func/test_run_single_stage.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -679,11 +679,7 @@ def test_rerun_deterministic_ignore_cache(tmp_dir, run_copy):
679679
def test_rerun_callback(dvc):
680680
def run_callback(force=False):
681681
return dvc.run(
682-
cmd="echo content > out",
683-
outs=["out"],
684-
deps=[],
685-
force=force,
686-
single_stage=True,
682+
cmd="echo content > out", force=force, single_stage=True,
687683
)
688684

689685
assert run_callback() is not None
@@ -768,6 +764,7 @@ def run_command(self, file, file_content):
768764
[
769765
"run",
770766
"--single-stage",
767+
"--always-changed",
771768
self.outs_command,
772769
file,
773770
f"echo {file_content} >> {file}",

tests/unit/stage/test_run.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@ def test_run_stage_dry(caplog, cmd, expected):
1919
run_stage(stage, dry=True)
2020

2121
expected.insert(
22-
0, "Running callback stage 'stage.dvc':",
22+
0, "Running stage 'stage.dvc':",
2323
)
2424
assert caplog.messages == expected

0 commit comments

Comments
 (0)