question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow continuation on nargs=argparse.REMAINDER

See original GitHub issue

This is somewhere between a feature and a possible bug due to inconsistency with argparse; bear with me. Essentially I believe the argcomplete process should drop out without exiting if we fall into the scope of an argparse.REMAINDER. Right now it doesn’t understand that with a REMAINDER argument specified, any options after the last positional argument wouldn’t be interpreted by argparse. Since argparse won’t interpret them, there’s no sense trying to suggest autocompletions - right now I’m getting option suggestions which won’t work.

This is important for my use-case as I’m trying to use argcomplete with a cli which is broken into multiple functions and works like this:

        parser.add_argument(
            '--host', dest='host', type=str, default=None,
            help='The service host'
        )
        parser.add_argument(
            '--port', dest='port', type=int, default=None,
            help='The service port'
        )
       #...

        parser.add_argument(
            'command', nargs=1, choices=command_names,
            help='The command you wish to invoke'
        )
        parser.add_argument(
            'command_flags', nargs=argparse.REMAINDER, help=argparse.SUPPRESS
        )
        argcomplete.autocomplete(parser)

        args = parser.parse_args()

        Command = commands_by_name.get(args.command[0])

        if not Command:
            raise CommandError('Unknown command: %s' % args.command)

        return Command(
            host=args.host,
            port=args.port,
            url_prefix=args.prefix,
            logger=self.logger,
            args=args.command_flags
        )

Essentially I’m passing any remaining arguments after a command name to a Command class which then specifies its own secondary argparser, and I want to then run argcomplete.autocomplete again so that I can autocomplete the arguments to that subcommand.

I suspect this isn’t actually too difficult to do, just needs a little bit of logic to check if the next argument would be interpreted as a REMAINDER, and a flag to allow dropping out at that point if desired (there are probably some cases where you could want to complete an indefinite number of arguments, if you were taking a file list or something, though it should never suggest options at this point). If I get a spare moment I’ll see if I can implement it myself and create a pull request; I haven’t looked at the codebase yet.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:7

github_iconTop GitHub Comments

2reactions
evanunderscorecommented, Dec 2, 2017

I think this demonstrates one of the problems:

$ cat ac.py
#!/usr/bin/env python
import argparse
import argcomplete

parser = argparse.ArgumentParser()
parser.add_argument('--foo', action='store_true')
parser.add_argument('bar', choices=['bar'])
parser.add_argument('baz', choices=['baz'], nargs=argparse.REMAINDER)

argcomplete.autocomplete(parser)
print(parser.parse_args())
$ eval "$(PYTHONPATH=. scripts/register-python-argcomplete ./ac.py)"
$ ./ac.py bar --foo baz
Namespace(bar='bar', baz=['--foo', 'baz'], foo=False)
$ ./ac.py bar <tab>
baz     --foo   -h      --help  
$ ./ac.py bar --foo <tab>baz

While argparse knows that --foo belongs to the REMAINDER argument, argcomplete doesn’t figure that out until one argument has been given for it. Since the intent of argcomplete is to match argparse semantics, I agree this is a bug and should be fixed.

For your other problem, you can put whatever logic you want into the completer for that argument. Is there a reason that doesn’t work for you, or does dropping out just make for simpler code?

0reactions
evanunderscorecommented, Dec 3, 2017

Sounds good. I’ve opened a new issue for the bug I outlined above and I’ll leave this issue for the feature request you’ve described. Let us know if you run into any problems with the InterruptCompleter solution you’re using.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Python argparse: Combine optional parameters with nargs ...
REMAINDER ). The simple solution is to not mix them - give the optionals first, then all the positionals afterwards. Here's what's going...
Read more >
Issue 35495: argparse does not honor default argument for ...
For the purpose of facilitating continuing conversation, here are two tests that contrast the use of * versus REMAINDER import argparse parser = ......
Read more >
15.4. argparse — Parser for command-line options, arguments ...
The first step in using the argparse is creating an ArgumentParser object: ... nargs - The number of command-line arguments that should be...
Read more >
git-clang-format - Apple Open Source
(Setting nargs='*' throws away the '--', while # nargs=argparse.REMAINDER ... """Delete every key in `dictionary` that doesn't have an allowed extension.
Read more >
argparse.REMAINDER Example - Program Talk
parser.add_argument('command', nargs=argparse.REMAINDER, metavar='COMMAND', help='Command to run and its argument.') return parser.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found