summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorTodd Leonhardt <todd.leonhardt@gmail.com>2018-02-03 12:09:15 -0500
committerGitHub <noreply@github.com>2018-02-03 12:09:15 -0500
commit16e5f5112637736453d9d9c691b004fea79a5b7f (patch)
treef38fe65a8497e41d8a8aec3c28b263a8bb059be5 /examples
parent1a42fa1b7995b0396983942e3ec0409cdcdd635b (diff)
parent519f4384c614d5c96d25e047ed85a16ff4bd043c (diff)
downloadcmd2-git-16e5f5112637736453d9d9c691b004fea79a5b7f.tar.gz
Merge branch 'master' into feature/submenu
Diffstat (limited to 'examples')
-rwxr-xr-xexamples/arg_print.py38
-rwxr-xr-xexamples/argparse_example.py84
-rwxr-xr-xexamples/example.py58
-rwxr-xr-xexamples/pirate.py38
-rwxr-xr-xexamples/python_scripting.py35
-rwxr-xr-xexamples/subcommands.py61
-rw-r--r--examples/transcripts/exampleSession.txt (renamed from examples/exampleSession.txt)1
-rw-r--r--examples/transcripts/pirate.transcript10
-rw-r--r--examples/transcripts/transcript_regex.txt (renamed from examples/transcript_regex.txt)1
9 files changed, 236 insertions, 90 deletions
diff --git a/examples/arg_print.py b/examples/arg_print.py
index 849cf386..8b02bc51 100755
--- a/examples/arg_print.py
+++ b/examples/arg_print.py
@@ -9,9 +9,12 @@ and argument parsing is intended to work.
It also serves as an example of how to create command aliases (shortcuts).
"""
-import pyparsing
+import argparse
+
import cmd2
-from cmd2 import options, make_option
+import pyparsing
+
+from cmd2 import with_argument_list, with_argparser, with_argparser_and_unknown_args
class ArgumentAndOptionPrinter(cmd2.Cmd):
@@ -22,7 +25,7 @@ class ArgumentAndOptionPrinter(cmd2.Cmd):
# self.commentGrammars = pyparsing.Or([pyparsing.cStyleComment])
# Create command aliases which are shorter
- self.shortcuts.update({'ap': 'aprint', 'op': 'oprint'})
+ self.shortcuts.update({'$': 'aprint', '%': 'oprint'})
# Make sure to call this super class __init__ *after* setting commentGrammars and/or updating shortcuts
cmd2.Cmd.__init__(self)
@@ -33,12 +36,31 @@ class ArgumentAndOptionPrinter(cmd2.Cmd):
"""Print the argument string this basic command is called with."""
print('aprint was called with argument: {!r}'.format(arg))
- @options([make_option('-p', '--piglatin', action="store_true", help="atinLay"),
- make_option('-s', '--shout', action="store_true", help="N00B EMULATION MODE"),
- make_option('-r', '--repeat', type="int", help="output [n] times")], arg_desc='positional_arg_string')
- def do_oprint(self, arg, opts=None):
+ @with_argument_list
+ def do_lprint(self, arglist):
+ """Print the argument list this basic command is called with."""
+ print('lprint was called with the following list of arguments: {!r}'.format(arglist))
+
+ oprint_parser = argparse.ArgumentParser()
+ oprint_parser.add_argument('-p', '--piglatin', action='store_true', help='atinLay')
+ oprint_parser.add_argument('-s', '--shout', action='store_true', help='N00B EMULATION MODE')
+ oprint_parser.add_argument('-r', '--repeat', type=int, help='output [n] times')
+ oprint_parser.add_argument('words', nargs='+', help='words to print')
+
+ @with_argparser(oprint_parser)
+ def do_oprint(self, args):
+ """Print the options and argument list this options command was called with."""
+ print('oprint was called with the following\n\toptions: {!r}'.format(args))
+
+ pprint_parser = argparse.ArgumentParser()
+ pprint_parser.add_argument('-p', '--piglatin', action='store_true', help='atinLay')
+ pprint_parser.add_argument('-s', '--shout', action='store_true', help='N00B EMULATION MODE')
+ pprint_parser.add_argument('-r', '--repeat', type=int, help='output [n] times')
+ @with_argparser_and_unknown_args(pprint_parser)
+ def do_pprint(self, args, unknown):
"""Print the options and argument list this options command was called with."""
- print('oprint was called with the following\n\toptions: {!r}\n\targuments: {!r}'.format(opts, arg))
+ print('oprint was called with the following\n\toptions: {!r}\n\targuments: {}'.format(args, unknown))
+
if __name__ == '__main__':
diff --git a/examples/argparse_example.py b/examples/argparse_example.py
index 6fc2b15b..fbb2b1dc 100755
--- a/examples/argparse_example.py
+++ b/examples/argparse_example.py
@@ -1,19 +1,21 @@
#!/usr/bin/env python
# coding=utf-8
-"""A sample application for cmd2 showing how to use Argparse to process command line arguments for your application.
-It parses command line arguments looking for known arguments, but then still passes any unknown arguments onto cmd2
-to treat them as arguments at invocation.
+"""A sample application for cmd2 showing how to use argparse to
+process command line arguments for your application.
-Thanks to cmd2's built-in transcript testing capability, it also serves as a test suite for argparse_example.py when
-used with the exampleSession.txt transcript.
+Thanks to cmd2's built-in transcript testing capability, it also
+serves as a test suite for argparse_example.py when used with the
+exampleSession.txt transcript.
-Running `python argparse_example.py -t exampleSession.txt` will run all the commands in the transcript against
-argparse_example.py, verifying that the output produced matches the transcript.
+Running `python argparse_example.py -t exampleSession.txt` will run
+all the commands in the transcript against argparse_example.py,
+verifying that the output produced matches the transcript.
"""
import argparse
import sys
-from cmd2 import Cmd, make_option, options
+from cmd2 import Cmd, options, with_argparser, with_argument_list
+from optparse import make_option
class CmdLineApp(Cmd):
@@ -39,27 +41,73 @@ class CmdLineApp(Cmd):
# Setting this true makes it run a shell command if a cmd2/cmd command doesn't exist
# self.default_to_shell = True
+ speak_parser = argparse.ArgumentParser()
+ speak_parser.add_argument('-p', '--piglatin', action='store_true', help='atinLay')
+ speak_parser.add_argument('-s', '--shout', action='store_true', help='N00B EMULATION MODE')
+ speak_parser.add_argument('-r', '--repeat', type=int, help='output [n] times')
+ speak_parser.add_argument('words', nargs='+', help='words to say')
+
+ @with_argparser(speak_parser)
+ def do_speak(self, args):
+ """Repeats what you tell me to."""
+ words = []
+ for word in args.words:
+ if args.piglatin:
+ word = '%s%say' % (word[1:], word[0])
+ if args.shout:
+ word = word.upper()
+ words.append(word)
+ repetitions = args.repeat or 1
+ for i in range(min(repetitions, self.maxrepeats)):
+ self.poutput(' '.join(words))
+
+ do_say = do_speak # now "say" is a synonym for "speak"
+ do_orate = do_speak # another synonym, but this one takes multi-line input
+
+ tag_parser = argparse.ArgumentParser()
+ tag_parser.add_argument('tag', help='tag')
+ tag_parser.add_argument('content', nargs='+', help='content to surround with tag')
+
+ @with_argparser(tag_parser)
+ def do_tag(self, args):
+ """create a html tag"""
+ self.poutput('<{0}>{1}</{0}>'.format(args.tag, ' '.join(args.content)))
+
+
+ @with_argument_list
+ def do_tagg(self, arglist):
+ """verion of creating an html tag using arglist instead of argparser"""
+ if len(arglist) >= 2:
+ tag = arglist[0]
+ content = arglist[1:]
+ self.poutput('<{0}>{1}</{0}>'.format(tag, ' '.join(content)))
+ else:
+ self.perror("tagg requires at least 2 arguments")
+
+
+ # @options uses the python optparse module which has been deprecated
+ # since 2011. Use @with_argument_parser instead, which utilizes the
+ # python argparse module
@options([make_option('-p', '--piglatin', action="store_true", help="atinLay"),
make_option('-s', '--shout', action="store_true", help="N00B EMULATION MODE"),
make_option('-r', '--repeat', type="int", help="output [n] times")
])
- def do_speak(self, arg, opts=None):
+ def do_deprecated_speak(self, arg, opts=None):
"""Repeats what you tell me to."""
- arg = ''.join(arg)
- if opts.piglatin:
- arg = '%s%say' % (arg[1:], arg[0])
- if opts.shout:
- arg = arg.upper()
+ words = []
+ for word in arg:
+ if opts.piglatin:
+ word = '%s%say' % (word[1:], word[0])
+ if opts.shout:
+ arg = arg.upper()
+ words.append(word)
repetitions = opts.repeat or 1
for i in range(min(repetitions, self.maxrepeats)):
- self.stdout.write(arg)
+ self.stdout.write(' '.join(words))
self.stdout.write('\n')
# self.stdout.write is better than "print", because Cmd can be
# initialized with a non-standard output destination
- do_say = do_speak # now "say" is a synonym for "speak"
- do_orate = do_speak # another synonym, but this one takes multi-line input
-
if __name__ == '__main__':
# You can do your custom Argparse parsing here to meet your application's needs
diff --git a/examples/example.py b/examples/example.py
index 889e62c0..c66f0e60 100755
--- a/examples/example.py
+++ b/examples/example.py
@@ -12,8 +12,9 @@ the transcript.
"""
import random
+import argparse
-from cmd2 import Cmd, make_option, options, set_use_arg_list
+from cmd2 import Cmd, with_argparser
class CmdLineApp(Cmd):
@@ -37,48 +38,51 @@ class CmdLineApp(Cmd):
# Set use_ipython to True to enable the "ipy" command which embeds and interactive IPython shell
Cmd.__init__(self, use_ipython=False)
- # For option commands, pass a single argument string instead of a list of argument strings to the do_* methods
- set_use_arg_list(False)
+ speak_parser = argparse.ArgumentParser()
+ speak_parser.add_argument('-p', '--piglatin', action='store_true', help='atinLay')
+ speak_parser.add_argument('-s', '--shout', action='store_true', help='N00B EMULATION MODE')
+ speak_parser.add_argument('-r', '--repeat', type=int, help='output [n] times')
+ speak_parser.add_argument('words', nargs='+', help='words to say')
- opts = [make_option('-p', '--piglatin', action="store_true", help="atinLay"),
- make_option('-s', '--shout', action="store_true", help="N00B EMULATION MODE"),
- make_option('-r', '--repeat', type="int", help="output [n] times")]
-
- @options(opts, arg_desc='(text to say)')
- def do_speak(self, arg, opts=None):
+ @with_argparser(speak_parser)
+ def do_speak(self, args):
"""Repeats what you tell me to."""
- arg = ''.join(arg)
- if opts.piglatin:
- arg = '%s%say' % (arg[1:], arg[0])
- if opts.shout:
- arg = arg.upper()
- repetitions = opts.repeat or 1
+ words = []
+ for word in args.words:
+ if args.piglatin:
+ word = '%s%say' % (word[1:], word[0])
+ if args.shout:
+ word = word.upper()
+ words.append(word)
+ repetitions = args.repeat or 1
for i in range(min(repetitions, self.maxrepeats)):
- self.poutput(arg)
- # recommend using the poutput function instead of
- # self.stdout.write or "print", because Cmd allows the user
- # to redirect output
+ # .poutput handles newlines, and accommodates output redirection too
+ self.poutput(' '.join(words))
do_say = do_speak # now "say" is a synonym for "speak"
do_orate = do_speak # another synonym, but this one takes multi-line input
- @options([ make_option('-r', '--repeat', type="int", help="output [n] times") ])
- def do_mumble(self, arg, opts=None):
+ mumble_parser = argparse.ArgumentParser()
+ mumble_parser.add_argument('-r', '--repeat', type=int, help='how many times to repeat')
+ mumble_parser.add_argument('words', nargs='+', help='words to say')
+
+ @with_argparser(mumble_parser)
+ def do_mumble(self, args):
"""Mumbles what you tell me to."""
- repetitions = opts.repeat or 1
- arg = arg.split()
+ repetitions = args.repeat or 1
for i in range(min(repetitions, self.maxrepeats)):
output = []
- if (random.random() < .33):
+ if random.random() < .33:
output.append(random.choice(self.MUMBLE_FIRST))
- for word in arg:
- if (random.random() < .40):
+ for word in args.words:
+ if random.random() < .40:
output.append(random.choice(self.MUMBLES))
output.append(word)
- if (random.random() < .25):
+ if random.random() < .25:
output.append(random.choice(self.MUMBLE_LAST))
self.poutput(' '.join(output))
+
if __name__ == '__main__':
c = CmdLineApp()
c.cmdloop()
diff --git a/examples/pirate.py b/examples/pirate.py
index 32d7769e..cfe545d6 100755
--- a/examples/pirate.py
+++ b/examples/pirate.py
@@ -6,7 +6,8 @@ presented as part of her PyCon 2010 talk.
It demonstrates many features of cmd2.
"""
-from cmd2 import Cmd, options, make_option
+import argparse
+from cmd2 import Cmd, with_argparser
class Pirate(Cmd):
@@ -24,13 +25,13 @@ class Pirate(Cmd):
"""Initialize the base class as well as this one"""
Cmd.__init__(self)
# prompts and defaults
- self.gold = 3
+ self.gold = 0
self.initial_gold = self.gold
self.prompt = 'arrr> '
def default(self, line):
"""This handles unknown commands."""
- print('What mean ye by "{0}"?'.format(line))
+ self.poutput('What mean ye by "{0}"?'.format(line))
def precmd(self, line):
"""Runs just before a command line is parsed, but after the prompt is presented."""
@@ -40,10 +41,10 @@ class Pirate(Cmd):
def postcmd(self, stop, line):
"""Runs right before a command is about to return."""
if self.gold != self.initial_gold:
- print('Now we gots {0} doubloons'
+ self.poutput('Now we gots {0} doubloons'
.format(self.gold))
if self.gold < 0:
- print("Off to debtorrr's prison.")
+ self.poutput("Off to debtorrr's prison.")
stop = True
return stop
@@ -60,29 +61,30 @@ class Pirate(Cmd):
self.gold -= int(arg)
except ValueError:
if arg:
- print('''What's "{0}"? I'll take rrrum.'''.format(arg))
+ self.poutput('''What's "{0}"? I'll take rrrum.'''.format(arg))
self.gold -= 1
def do_quit(self, arg):
"""Quit the application gracefully."""
- print("Quiterrr!")
+ self.poutput("Quiterrr!")
return True
def do_sing(self, arg):
"""Sing a colorful song."""
- print(self.colorize(arg, self.songcolor))
-
- @options([make_option('--ho', type='int', default=2,
- help="How often to chant 'ho'"),
- make_option('-c', '--commas',
- action="store_true",
- help="Intersperse commas")])
- def do_yo(self, arg, opts):
+ self.poutput(self.colorize(arg, self.songcolor))
+
+ yo_parser = argparse.ArgumentParser()
+ yo_parser.add_argument('--ho', type=int, default=2, help="How often to chant 'ho'")
+ yo_parser.add_argument('-c', '--commas', action='store_true', help='Intersperse commas')
+ yo_parser.add_argument('beverage', help='beverage to drink with the chant')
+
+ @with_argparser(yo_parser)
+ def do_yo(self, args):
"""Compose a yo-ho-ho type chant with flexible options."""
- chant = ['yo'] + ['ho'] * opts.ho
- separator = ', ' if opts.commas else ' '
+ chant = ['yo'] + ['ho'] * args.ho
+ separator = ', ' if args.commas else ' '
chant = separator.join(chant)
- print('{0} and a bottle of {1}'.format(chant, arg))
+ self.poutput('{0} and a bottle of {1}'.format(chant, args.beverage))
if __name__ == '__main__':
diff --git a/examples/python_scripting.py b/examples/python_scripting.py
index ae04fda1..aa62007a 100755
--- a/examples/python_scripting.py
+++ b/examples/python_scripting.py
@@ -14,10 +14,11 @@ command and the "pyscript <script> [arguments]" syntax comes into play.
This application and the "scripts/conditional.py" script serve as an example for one way in which this can be done.
"""
+import argparse
import functools
import os
-from cmd2 import Cmd, options, make_option, CmdResult, set_use_arg_list
+from cmd2 import Cmd, CmdResult, with_argument_list, with_argparser_and_unknown_args
class CmdLineApp(Cmd):
@@ -27,12 +28,8 @@ class CmdLineApp(Cmd):
# Enable the optional ipy command if IPython is installed by setting use_ipython=True
Cmd.__init__(self, use_ipython=True)
self._set_prompt()
- self.autorun_on_edit = False
self.intro = 'Happy 𝛑 Day. Note the full Unicode support: 😇 (Python 3 only) 💩'
- # For option commands, pass a list of argument strings instead of a single argument string to the do_* methods
- set_use_arg_list(True)
-
def _set_prompt(self):
"""Set prompt so it displays the current working directory."""
self.cwd = os.getcwd()
@@ -49,19 +46,21 @@ class CmdLineApp(Cmd):
self._set_prompt()
return stop
- # noinspection PyUnusedLocal
- @options([], arg_desc='<new_dir>')
- def do_cd(self, arg, opts=None):
- """Change directory."""
+ @with_argument_list
+ def do_cd(self, arglist):
+ """Change directory.
+ Usage:
+ cd <new_dir>
+ """
# Expect 1 argument, the directory to change to
- if not arg or len(arg) != 1:
+ if not arglist or len(arglist) != 1:
self.perror("cd requires exactly 1 argument:", traceback_war=False)
self.do_help('cd')
self._last_result = CmdResult('', 'Bad arguments')
return
# Convert relative paths to absolute paths
- path = os.path.abspath(os.path.expanduser(arg[0]))
+ path = os.path.abspath(os.path.expanduser(arglist[0]))
# Make sure the directory exists, is a directory, and we have read access
out = ''
@@ -86,13 +85,15 @@ class CmdLineApp(Cmd):
# Enable directory completion for cd command by freezing an argument to path_complete() with functools.partialmethod
complete_cd = functools.partialmethod(Cmd.path_complete, dir_only=True)
- @options([make_option('-l', '--long', action="store_true", help="display in long format with one item per line")],
- arg_desc='')
- def do_dir(self, arg, opts=None):
+ dir_parser = argparse.ArgumentParser()
+ dir_parser.add_argument('-l', '--long', action='store_true', help="display in long format with one item per line")
+
+ @with_argparser_and_unknown_args(dir_parser)
+ def do_dir(self, args, unknown):
"""List contents of current directory."""
# No arguments for this command
- if arg:
- self.perror("dir does not take any arguments:", traceback_war=False)
+ if unknown:
+ self.perror("dir does not take any positional arguments:", traceback_war=False)
self.do_help('dir')
self._last_result = CmdResult('', 'Bad arguments')
return
@@ -101,7 +102,7 @@ class CmdLineApp(Cmd):
contents = os.listdir(self.cwd)
fmt = '{} '
- if opts.long:
+ if args.long:
fmt = '{}\n'
for f in contents:
self.stdout.write(fmt.format(f))
diff --git a/examples/subcommands.py b/examples/subcommands.py
new file mode 100755
index 00000000..e77abc61
--- /dev/null
+++ b/examples/subcommands.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+# coding=utf-8
+"""A simple example demonstrating how to use Argparse to support sub-commands.
+
+
+This example shows an easy way for a single command to have many subcommands, each of which takes different arguments
+and provides separate contextual help.
+"""
+import argparse
+
+import cmd2
+from cmd2 import with_argparser
+
+
+class SubcommandsExample(cmd2.Cmd):
+ """ Example cmd2 application where we a base command which has a couple subcommands."""
+
+ def __init__(self):
+ cmd2.Cmd.__init__(self)
+
+ # sub-command functions for the base command
+ def base_foo(self, args):
+ """foo subcommand of base command"""
+ self.poutput(args.x * args.y)
+
+ def base_bar(self, args):
+ """bar sucommand of base command"""
+ self.poutput('((%s))' % args.z)
+
+ # create the top-level parser for the base command
+ base_parser = argparse.ArgumentParser(prog='base')
+ base_subparsers = base_parser.add_subparsers(title='subcommands', help='subcommand help')
+
+ # create the parser for the "foo" sub-command
+ parser_foo = base_subparsers.add_parser('foo', help='foo help')
+ parser_foo.add_argument('-x', type=int, default=1, help='integer')
+ parser_foo.add_argument('y', type=float, help='float')
+ parser_foo.set_defaults(func=base_foo)
+
+ # create the parser for the "bar" sub-command
+ parser_bar = base_subparsers.add_parser('bar', help='bar help')
+ parser_bar.add_argument('z', help='string')
+ parser_bar.set_defaults(func=base_bar)
+
+ # Create a list of subcommand names, which is used to enable tab-completion of sub-commands
+ subcommands = ['foo', 'bar']
+
+ @with_argparser(base_parser, subcommands)
+ def do_base(self, args):
+ """Base command help"""
+ try:
+ # Call whatever sub-command function was selected
+ args.func(self, args)
+ except AttributeError:
+ # No sub-command was provided, so as called
+ self.do_help('base')
+
+
+if __name__ == '__main__':
+ app = SubcommandsExample()
+ app.cmdloop()
diff --git a/examples/exampleSession.txt b/examples/transcripts/exampleSession.txt
index ef6df857..840bee60 100644
--- a/examples/exampleSession.txt
+++ b/examples/transcripts/exampleSession.txt
@@ -4,7 +4,6 @@
# regexes on prompts just make the trailing space obvious
(Cmd) set
abbrev: False
-autorun_on_edit: False
colors: /(True|False)/
continuation_prompt: >/ /
debug: False
diff --git a/examples/transcripts/pirate.transcript b/examples/transcripts/pirate.transcript
new file mode 100644
index 00000000..570f0cd7
--- /dev/null
+++ b/examples/transcripts/pirate.transcript
@@ -0,0 +1,10 @@
+arrr> loot
+Now we gots 1 doubloons
+arrr> loot
+Now we gots 2 doubloons
+arrr> loot
+Now we gots 3 doubloons
+arrr> drink 3
+Now we gots 0 doubloons
+arrr> yo --ho 3 rum
+yo ho ho ho and a bottle of rum
diff --git a/examples/transcript_regex.txt b/examples/transcripts/transcript_regex.txt
index 27b4c639..7d017dee 100644
--- a/examples/transcript_regex.txt
+++ b/examples/transcripts/transcript_regex.txt
@@ -4,7 +4,6 @@
# regexes on prompts just make the trailing space obvious
(Cmd) set
abbrev: True
-autorun_on_edit: False
colors: /(True|False)/
continuation_prompt: >/ /
debug: False