mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-02 07:18:25 +01:00
Make comparisons in is_cached independent of order (#3731)
On is_cached, we used to compare two dicts: one of current stage in memory created by `run` and one that's already written to the file. As `outs` and `dicts` are lists (which is generate by `dumpd`), the comparison was dependent on the order of outs and dicts. So, the `run` before and now, can be in different order and would fail the comparisons.
This commit is contained in:
+3
-3
@@ -23,7 +23,7 @@ sort_by_path = partial(sorted, key=attrgetter("def_path"))
|
||||
|
||||
def _get_outs(stage: "PipelineStage"):
|
||||
outs_bucket = {}
|
||||
for o in stage.outs:
|
||||
for o in sort_by_path(stage.outs):
|
||||
bucket_key = ["metrics"] if o.metric else ["outs"]
|
||||
|
||||
if not o.metric and o.persist:
|
||||
@@ -32,7 +32,7 @@ def _get_outs(stage: "PipelineStage"):
|
||||
bucket_key += ["no_cache"]
|
||||
key = "_".join(bucket_key)
|
||||
outs_bucket[key] = outs_bucket.get(key, []) + [o.def_path]
|
||||
return [(key, outs_bucket[key]) for key in outs_bucket.keys()]
|
||||
return [(key, outs_bucket[key]) for key in sorted(outs_bucket.keys())]
|
||||
|
||||
|
||||
def get_params_deps(stage: "PipelineStage"):
|
||||
@@ -79,7 +79,7 @@ def to_pipeline_file(stage: "PipelineStage"):
|
||||
res = [
|
||||
(stage.PARAM_CMD, stage.cmd),
|
||||
(stage.PARAM_WDIR, stage.resolve_wdir()),
|
||||
(stage.PARAM_DEPS, [d.def_path for d in deps]),
|
||||
(stage.PARAM_DEPS, sorted([d.def_path for d in deps])),
|
||||
(stage.PARAM_PARAMS, serialized_params),
|
||||
*_get_outs(stage),
|
||||
(stage.PARAM_LOCKED, stage.locked),
|
||||
|
||||
+10
-1
@@ -5,7 +5,7 @@ import signal
|
||||
import subprocess
|
||||
import threading
|
||||
|
||||
from itertools import chain
|
||||
from itertools import chain, product
|
||||
|
||||
from funcy import project
|
||||
|
||||
@@ -387,6 +387,15 @@ class Stage(params.StageParams):
|
||||
out.pop(LocalRemote.PARAM_CHECKSUM, None)
|
||||
out.pop(S3Remote.PARAM_CHECKSUM, None)
|
||||
|
||||
# outs and deps are lists of dicts. To check equality, we need to make
|
||||
# them independent of the order, so, we convert them to dicts.
|
||||
combination = product(
|
||||
[old_d, new_d], [self.PARAM_DEPS, self.PARAM_OUTS]
|
||||
)
|
||||
for coll, key in combination:
|
||||
if coll.get(key):
|
||||
coll[key] = {item["path"]: item for item in coll[key]}
|
||||
|
||||
if old_d != new_d:
|
||||
return False
|
||||
|
||||
|
||||
Reference in New Issue
Block a user