# Buggy code
def summary(self, detailed=False):
    if detailed:
        yield "output_file\tdate\trule\tversion\tlog-file(s)\tinput-file(s)\tshellcmd\tstatus\tplan"
    else:
        yield "output_file\tdate\trule\tversion\tlog-file(s)\tstatus\tplan"

    for job in self.jobs:
        output = job.rule.output if self.dynamic(job) else job.expanded_output
        for f in output:
            rule = self.workflow.persistence.rule(f)
            rule = "-" if rule is None else rule

            version = self.workflow.persistence.version(f)
            version = "-" if version is None else str(version)

            date = time.ctime(f.mtime) if f.exists else "-"

            pending = "update pending" if self.reason(job) else "no update"

            log = self.workflow.persistence.log(f)
            log = "-" if log is None else ",".join(log)

            input = self.workflow.persistence.input(f)
            input = "-" if input is None else ",".join(input)

            shellcmd = self.workflow.persistence.shellcmd(f)
            shellcmd = "-" if shellcmd is None else shellcmd
            # remove new line characters, leading and trailing whitespace
            shellcmd = shellcmd.strip().replace("\n", "; ")

            status = "ok"
            if not f.exists:
                status = "missing"
            elif self.reason(job).updated_input:
                status = "updated input files"
            elif self.workflow.persistence.version_changed(job, file=f):
                status = "version changed to {}".format(job.rule.version)
            elif self.workflow.persistence.code_changed(job, file=f):
                status = "rule implementation changed"
            elif self.workflow.persistence.input_changed(job, file=f):
                status = "set of input files changed"
            elif self.workflow.persistence.params_changed(job, file=f):
                status = "params changed"
            if detailed:
                yield "\t".join(
                    (f, date, rule, version, log, input, shellcmd, status, pending)
                )
            else:
                yield "\t".join((f, date, rule, version, log, status, pending))


# Traceback (FileNotFoundError)
Building DAG of jobs...
Traceback (most recent call last):
File "<base_path>/software/miniconda/envs/snakemake/lib/python3.7/site-packages/snakemake/__init__.py", line 709, in snakemake
keepincomplete=keep_incomplete,
File "<base_path>/software/miniconda/envs/snakemake/lib/python3.7/site-packages/snakemake/workflow.py", line 670, in execute
dag.init()
File "<base_path>/software/miniconda/envs/snakemake/lib/python3.7/site-packages/snakemake/dag.py", line 177, in init
job = self.update(self.file2jobs(file), file=file, progress=progress)
File "<base_path>/software/miniconda/envs/snakemake/lib/python3.7/site-packages/snakemake/dag.py", line 715, in update
progress=progress,
File "<base_path>/software/miniconda/envs/snakemake/lib/python3.7/site-packages/snakemake/dag.py", line 792, in update_
file.inventory()
File "<base_path>/software/miniconda/envs/snakemake/lib/python3.7/site-packages/snakemake/io.py", line 210, in inventory
self._local_inventory(cache)
File "<base_path>/software/miniconda/envs/snakemake/lib/python3.7/site-packages/snakemake/io.py", line 224, in _local_inventory
with os.scandir(path) as scan:
FileNotFoundError: [Errno 2] No such file or directory: '<analysis_patch>/tmp_batch113/codons'

# Fixed code
def summary(self, detailed=False):
    if detailed:
        yield "output_file\tdate\trule\tversion\tlog-file(s)\tinput-file(s)\tshellcmd\tstatus\tplan"
    else:
        yield "output_file\tdate\trule\tversion\tlog-file(s)\tstatus\tplan"

    for job in self.jobs:
        output = job.rule.output if self.dynamic(job) else job.expanded_output
        for f in output:
            rule = self.workflow.persistence.rule(f)
            rule = "-" if rule is None else rule

            version = self.workflow.persistence.version(f)
            version = "-" if version is None else str(version)

            date = time.ctime(f.mtime.local_or_remote()) if f.exists else "-"

            pending = "update pending" if self.reason(job) else "no update"

            log = self.workflow.persistence.log(f)
            log = "-" if log is None else ",".join(log)

            input = self.workflow.persistence.input(f)
            input = "-" if input is None else ",".join(input)

            shellcmd = self.workflow.persistence.shellcmd(f)
            shellcmd = "-" if shellcmd is None else shellcmd
            # remove new line characters, leading and trailing whitespace
            shellcmd = shellcmd.strip().replace("\n", "; ")

            status = "ok"
            if not f.exists:
                status = "missing"
            elif self.reason(job).updated_input:
                status = "updated input files"
            elif self.workflow.persistence.version_changed(job, file=f):
                status = "version changed to {}".format(job.rule.version)
            elif self.workflow.persistence.code_changed(job, file=f):
                status = "rule implementation changed"
            elif self.workflow.persistence.input_changed(job, file=f):
                status = "set of input files changed"
            elif self.workflow.persistence.params_changed(job, file=f):
                status = "params changed"
            if detailed:
                yield "\t".join(
                    (f, date, rule, version, log, input, shellcmd, status, pending)
                )
            else:
                yield "\t".join((f, date, rule, version, log, status, pending))