From 7f54c391f2821655ed168bcdafad6d07b96fcec7 Mon Sep 17 00:00:00 2001 From: dkuzminov Date: Mon, 23 Aug 2021 06:38:35 -0400 Subject: [PATCH] fix: AmbiguousRuleException bug caused by weak ordering of rules (#1124) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Link to the issue: https://github.com/snakemake/snakemake/issues/1106 Co-authored-by: Johannes Köster --- snakemake/dag.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/snakemake/dag.py b/snakemake/dag.py index 6035aad68..44e4081d0 100755 --- a/snakemake/dag.py +++ b/snakemake/dag.py @@ -731,9 +731,8 @@ def update( visited = set() if known_producers is None: known_producers = dict() - producer = None + producers = [] exceptions = list() - jobs = sorted(jobs, reverse=not self.ignore_ambiguity) cycles = list() for job in jobs: @@ -756,12 +755,7 @@ def update( ) # TODO this might fail if a rule discarded here is needed # elsewhere - if producer: - if job < producer or self.ignore_ambiguity: - break - elif producer is not None: - raise AmbiguousRuleException(file, job, producer) - producer = job + producers.append(job) except ( MissingInputException, CyclicGraphException, @@ -783,7 +777,7 @@ def update( if file else "", ) - if producer is None: + if not producers: if cycles: job = cycles[0] raise CyclicGraphException(job.rule, file, rule=job.rule) @@ -791,21 +785,27 @@ def update( raise WorkflowError(*exceptions) elif len(exceptions) == 1: raise exceptions[0] - else: - logger.dag_debug(dict(status="selected", job=producer)) - logger.dag_debug( - dict( - file=file, - msg="Producer found, hence exceptions are ignored.", - exception=WorkflowError(*exceptions), - ) - ) n = len(self.dependencies) if progress and n % 1000 == 0 and n and self._progress != n: logger.info("Processed {} potential jobs.".format(n)) self._progress = n + producers.sort(reverse=True) + producer = producers[0] + ambiguities = list( + filter(lambda x: not x < producer and not producer < x, producers[1:]) + ) + if ambiguities and not self.ignore_ambiguity: + raise AmbiguousRuleException(file, producer, ambiguities[0]) + logger.dag_debug(dict(status="selected", job=producer)) + logger.dag_debug( + dict( + file=file, + msg="Producer found, hence exceptions are ignored.", + exception=WorkflowError(*exceptions), + ) + ) return producer def update_(