Skip to content

Bash issue when using argparse and nargs='?' #181

@toddthegeek

Description

@toddthegeek

error received:

bash: ((: 6 + 1 - 7 - 0 >=             ? : syntax error: operand expected (error token is "? ")

output snippet of shtab completion:

_shtab_example___add_template_nargs=?
_shtab_example__a_nargs=?

program:
example.py

command ran:

example.py --ext html --ext pdf myfile.txt --add-template <TAB>

Other examples:

$ example.py --ext html --ext pdf file1.txt
outfile='file1.html' template=None
outfile='file1.pdf' template=None

$ example.py --ext html --ext pdf file1.txt --add-template
outfile='file1.html' template=html
outfile='file1.pdf' template=pdf

$ example.py --ext html --ext pdf file1.txt --add-template to_
outfile='file1.html' template=to_html
outfile='file1.pdf' template=to_pdf

shtab command:

shtab \
	--error-unimportable \
	--verbose \
	--shell=bash \
	--prog example.py \
	example.parse_arguments \
	| tee "./completions/example.py"

shtab 1.7.1
Python 3.12.6
GNU bash, version 5.2.21(1)-release (x86_64-pc-linux-gnu)

I run

export PATH=$PWD:$PATH
source completions/example.py

Then I run the command above and receive the error.

contents of example.py:

#!/usr/bin/env python3
"""Example to test shtab issue."""

import argparse
import pathlib


def parse_arguments():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument(
        '--add-template', '-a',
        nargs='?',
        default=None,
        const='',
        type=str,
        help=('Optional. If set add a template. Type string for a prefix.'),
        )
    parser.add_argument(
        '--ext', '-e',
        dest='exts',
        metavar='file_extension',
        action='extend',
        required=True,
        nargs=1,
        type=str,
        help=(''),
        )
    parser.add_argument(
        'file',
        type=pathlib.Path,
        help='Name of a file',
        )
    return parser


if __name__ == '__main__':
    parser = parse_arguments()
    args, unknown_args = parser.parse_known_args()
    for ext in args.exts:
        outfile = args.file.with_suffix(f".{ext}").name
        if args.add_template is not None:
            print(f"{outfile=} template={args.add_template + ext}")
        else:
            print(f"{outfile=} template=None")

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions