4

I am making a terminal game using Python's wonderful Cmd library. But i was curious if i could somehow put argparse code into it. Like use argparse to handle the 'args' from my cmd.Cmd() class. To do this, i was really hoping that argparse had a way to manually pass args into it. I skimmed over the docs, but didn't notice anything like that.

Kieee
  • 126
  • 2
  • 15
  • As in [`parse_args(args)`](https://docs.python.org/2/library/argparse.html#argparse.ArgumentParser.parse_args)? – dhke Feb 20 '17 at 18:01
  • @dhke Can i just pass strings in like that? – Kieee Feb 20 '17 at 18:05
  • See the linked documentation. They use it all throughout. – glibdud Feb 20 '17 at 18:06
  • @Cyanite It takes a sequence (list, tuple) of arguments like those in `sys.argv`. `parse_args()` is equal to `parse_args(sys.argv)`. If you want to pass a single shell-like string (with quoting), you might want to use [`shlex.split()`](https://docs.python.org/2/library/shlex.html), first. – dhke Feb 20 '17 at 18:09
  • @dhke do i have to import `shlex`? – Kieee Feb 20 '17 at 18:10
  • @Cyanite Yes, and: Why don't you try it? – dhke Feb 20 '17 at 18:11
  • @dhke works just like i wanted. If you can just add it as an answer so i can close this question. Thank you so much. ^~^ – Kieee Feb 20 '17 at 18:19
  • For the testing I do the simple string split on white space is enough, e.g. `'--foo 1 bar'.split()`. `shlex.split` is needed if you have quoted strings or special characters. – hpaulj Feb 20 '17 at 18:44

2 Answers2

6

parse_args() takes an optional argument args with a list (or tuple) of to parse. parse_args() (without arguments) is equivalent to parse_args(sys.argv[1:]):

In a script, parse_args() will typically be called with no arguments, and the ArgumentParser will automatically determine the command-line arguments from sys.argv.

If you do not have a tuple, but a single string, shell-like argument splitting can be accomplished using shlex.split()

>>> shlex.split('"A" B C\\ D')
['A', 'B', 'C D']   

Note that argparse will print usage and help messages as well as exit() on fatal errors. You can override .error() to handle errors yourself:

class ArgumentParserNoExit(argparse.ArgumentParser):
    def error(self, message):
        raise ValueError(message) # or whatever you like
dhke
  • 15,008
  • 2
  • 39
  • 56
  • Side note for anyone else taking this as an answer: if you imput an invalid command (like 'help' instead of '--help') argparse will give you an error(visually) and THEN raise an error. So if you `except` the error the user will still see the error, but the script wont crash. – Kieee Feb 20 '17 at 18:30
  • @Cyanite `argparse` will also `exit()` on fatal errors. Override `.error()` on the parser to fix that. – dhke Feb 20 '17 at 18:42
  • I do not understand the part about overriding the `.error()` can i not just `except SystemExit: pass`? It's a game - I don't want it to crash everytime players typo a command in `Cmd()` – Kieee Feb 20 '17 at 18:56
0

You could also try namedtuple to manually provide the input arguments,

from collections import namedtuple
ManualInput = namedtuple("ManualInput", ["arg1", "arg2"])
args = ManualInput(1, 4)

you will get

In [1]: print(args.arg2)
Out[1]: 4
Lorry
  • 382
  • 2
  • 7