Search code examples
python-3.xworkflowsnakemake

error "positional argument follows keyword argument" in snakefile


When I run snakemake -np it says: SyntaxError in line 22 of /home/snakefile: positional argument follows keyword argument

It seems that it's a problem in the input section of rule prokka because other parts workded fine.

Belowe is my snakefile:

configfile:"config.yml"
id=config['id']
rule all:
    input:
        expand("{sample_id}/assembly/skesa/{sample_id}.fa", sample_id=id),
        directory(expand("{sample_id}/annotation/prokka/", sample_id=id))
rule skesa:
    output:
        contigs = "{sample_id}/assembly/skesa/{sample_id}.fa"
    input:
        r1 = lambda wildcards: config["reads"][wildcards.sample_id]['r1'],
        r2 = lambda wildcards: config["reads"][wildcards.sample_id]['r2']
    params:
        cpus = config['skesa']['cpus'],
        memory = config['skesa']['memory']
    shell:
        'skesa --reads {input.r1},{input.r2} --cores {params.cpus} --memory {params.memory} > {output}'
rule prokka:
    output:
        faa = "{sample_id}/annotation/prokka/{sample_id}.faa",
        directory("{sample_id}/annotation/prokka/{sample_id}}")
    input: 
        contigs = rules.skesa.output.contigs
    shell:
        "prokka --outdir {output} --prefix {wildcards.sample_id} {params.contigs}"

Solution

  • The problem is with:

    rule prokka:
        output:
            faa = "{sample_id}/annotation/prokka/{sample_id}.faa",
            directory("{sample_id}/annotation/prokka/{sample_id}}")
    

    I don't know exactly what snakemake does under the hood but I think it's going to pass the arguments of each directive (input, output, etc) as a dictionary to a function. In python, function arguments without name (positional) must come before those with name. Google positional argument follows keyword argument to learn more.

    Long story short: Either change the order of your output files:

    rule prokka:
        output:
            directory("{sample_id}/annotation/prokka/{sample_id}"),
            faa = "{sample_id}/annotation/prokka/{sample_id}.faa",
    

    Or give a name to all of them (probably better):

    rule prokka:
        output:
            faa = "{sample_id}/annotation/prokka/{sample_id}.faa",
            outdir= directory("{sample_id}/annotation/prokka/{sample_id}"),
        ...
        shell:
            "prokka --outdir {output.outdir} --prefix {wildcards.sample_id} ..."
    

    Besides, I think {sample_id}} should be {sample_id}