Is there a way for Snakemake to evaluate dynamic Snakefile constructs like `eval` does in GNU Make?

Question:

I would like to have various dynamic "shortcuts" (rule names) in my Snakemake workflow without needing marker files. The method I have in mind is similar to eval in GNU Make, but it doesn’t seem like Snakemake can evaluate variable-expanded code in the Snakefile syntax. Is there a way to accomplish this?

Here’s a simplified example Snakefile. I want to have a rule name corresponding to each output "stage", and right now I have to define them manually. Imagine if I had more "stages" and "steps" and wanted to have a rule that could make all "b", "d", or "z" files if I add those stages. It would be far more concise to dynamically define the rule name than to define every single combination, updated each time I add a new stage.

stages = ['a', 'b']
steps = [1, 2]

rule all:
    input:
        expand('{stage}{step}_file', stage=stages, step=steps)

rule:
    output:
        touch('{stage}{step}_file')

# Can these two be combined so that I don't have to add more
# rules for each new "stage" above while retaining the shorthand
# rule name corresponding to the stage?
rule a:
    input: expand('a{step}_file', step=steps)

rule b:
    input: expand('b{step}_file', step=steps)
Asked By: sappjw

||

Answers:

Since Snakefile is a Python file, the following might help to achieve what you are after:

for stage in stages:
    rule:
        name: f'{stage}'
        input: expand(f'{stage}{{step}}_file', step=steps)
Answered By: SultanOrazbayev