Bring fixes suggested by the review on UnixCommand
This commit is contained in:
parent
916d7933aa
commit
848b4c588c
2 changed files with 119 additions and 69 deletions
|
|
@ -947,14 +947,14 @@ class CmdDummy(UnixCommand):
|
|||
|
||||
"""A dummy UnixCommand."""
|
||||
|
||||
def init(self):
|
||||
key = "dummy"
|
||||
|
||||
def init_parser(self):
|
||||
"""Fill out options."""
|
||||
self.parser.add_argument("nb1", type=int, help="the first number")
|
||||
self.parser.add_argument("nb2", type=int, help="the second number")
|
||||
self.parser.add_argument("-v", "--verbose", action="store_true")
|
||||
|
||||
key = "dummy"
|
||||
|
||||
def func(self):
|
||||
nb1 = self.opts.nb1
|
||||
nb2 = self.opts.nb2
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ options.
|
|||
|
||||
The UnixCommand can be ovverridden to have your commands parsed.
|
||||
You will need to override two methods:
|
||||
- The `init` method, which adds options to the parser.
|
||||
- The `init_parser` method, which adds options to the parser.
|
||||
- The `func` method, called to execute the command once parsed.
|
||||
|
||||
Here's a short example:
|
||||
|
|
@ -30,7 +30,7 @@ class CmdPlant(UnixCommand):
|
|||
|
||||
key = "plant"
|
||||
|
||||
def init(self):
|
||||
def init_parser(self):
|
||||
"Add the arguments to the parser."
|
||||
# 'self.parser' inherits `argparse.ArgumentParser`
|
||||
self.parser.add_argument("key",
|
||||
|
|
@ -62,6 +62,112 @@ from textwrap import dedent
|
|||
from evennia import Command, InterruptCommand
|
||||
from evennia.utils.ansi import raw
|
||||
|
||||
class ParseError(Exception):
|
||||
|
||||
"""An error occurred during parsing."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class UnixCommandParser(argparse.ArgumentParser):
|
||||
|
||||
"""A modifier command parser for unix commands.
|
||||
|
||||
This parser is used to replace `argparse.ArgumentParser`. It
|
||||
is aware of the command calling it, and can more easily report to
|
||||
the caller. Some features (like the "brutal exit" of the original
|
||||
parser) are disabled or replaced. This parser is used by UnixCommand
|
||||
and creating one directly isn't recommended nor necessary. Even
|
||||
adding a sub-command will use this replaced parser automatically.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, prog, description="", epilogue="", command=None, **kwargs):
|
||||
prog = prog or command.key
|
||||
super(UnixCommandParser, self).__init__(
|
||||
prog=prog, description=description,
|
||||
conflict_handler='resolve', add_help=False, **kwargs)
|
||||
self.command = command
|
||||
self.post_help = epilogue
|
||||
def n_exit(code=None, msg=None):
|
||||
raise ParseError(msg)
|
||||
|
||||
self.exit = n_exit
|
||||
|
||||
# Replace the -h/--help
|
||||
self.add_argument("-h", "--hel", nargs=0, action=HelpAction,
|
||||
help="display the command help")
|
||||
|
||||
def format_usage(self):
|
||||
"""Return the usage line.
|
||||
|
||||
Note:
|
||||
This method is present to return the raw-escaped usage line,
|
||||
in order to avoid unintentional color codes.
|
||||
|
||||
"""
|
||||
return raw(super(UnixCommandParser, self).format_usage())
|
||||
|
||||
def format_help(self):
|
||||
"""Return the parser help, including its epilogue.
|
||||
|
||||
Note:
|
||||
This method is present to return the raw-escaped help,
|
||||
in order to avoid unintentional color codes. Color codes
|
||||
in the epilogue (the command docstring) are supported.
|
||||
|
||||
"""
|
||||
autohelp = raw(super(UnixCommandParser, self).format_help())
|
||||
return "\n" + autohelp + "\n" + self.post_help
|
||||
|
||||
def print_usage(self, file=None):
|
||||
"""Print the usage to the caller.
|
||||
|
||||
Args:
|
||||
file (file-object): not used here, the caller is used.
|
||||
|
||||
Note:
|
||||
This method will override `argparse.ArgumentParser`'s in order
|
||||
to not display the help on stdout or stderr, but to the
|
||||
command's caller.
|
||||
|
||||
"""
|
||||
if self.command:
|
||||
self.command.msg(self.format_usage().strip())
|
||||
|
||||
def print_help(self, file=None):
|
||||
"""Print the help to the caller.
|
||||
|
||||
Args:
|
||||
file (file-object): not used here, the caller is used.
|
||||
|
||||
Note:
|
||||
This method will override `argparse.ArgumentParser`'s in order
|
||||
to not display the help on stdout or stderr, but to the
|
||||
command's caller.
|
||||
|
||||
"""
|
||||
if self.command:
|
||||
self.command.msg(self.format_help().strip())
|
||||
|
||||
|
||||
class HelpAction(argparse.Action):
|
||||
|
||||
"""Override the -h/--help action in the default parser.
|
||||
|
||||
Using the default -h/--help will call the exit function in different
|
||||
ways, preventing the entire help message to be provided. Hence
|
||||
this override.
|
||||
|
||||
"""
|
||||
|
||||
def __call__(self, parser, namespace, values, option_string=None):
|
||||
"""If asked for help, display to the caller."""
|
||||
if parser.command:
|
||||
parser.command.msg(parser.format_help().strip())
|
||||
parser.exit(0, "")
|
||||
|
||||
|
||||
class UnixCommand(Command):
|
||||
"""
|
||||
Unix-type commands, supporting short and long options.
|
||||
|
|
@ -71,7 +177,7 @@ class UnixCommand(Command):
|
|||
used to parse the command.
|
||||
|
||||
In order to use it, you should override two methods:
|
||||
- `init`: the init method is called when the command is created.
|
||||
- `init_parser`: this method is called when the command is created.
|
||||
It can be used to set options in the parser. `self.parser`
|
||||
contains the `argparse.ArgumentParser`, so you can add arguments
|
||||
here.
|
||||
|
|
@ -84,7 +190,7 @@ class UnixCommand(Command):
|
|||
slightly different way than usual: the first line of the docstring
|
||||
is used to represent the program description (the very short
|
||||
line at the top of the help message). The other lines below are
|
||||
used as the program's "epilog", displayed below the options. It
|
||||
used as the program's "epilogue", displayed below the options. It
|
||||
means in your docstring, you don't have to write the options.
|
||||
They will be automatically provided by the parser and displayed
|
||||
accordingly. The `argparse` module provides a default '-h' or
|
||||
|
|
@ -97,16 +203,16 @@ class UnixCommand(Command):
|
|||
def __init__(self, **kwargs):
|
||||
super(UnixCommand, self).__init__()
|
||||
|
||||
# Create the empty EvenniaParser, inheriting argparse.ArgumentParser
|
||||
# Create the empty UnixCommandParser, inheriting argparse.ArgumentParser
|
||||
lines = dedent(self.__doc__.strip("\n")).splitlines()
|
||||
description = lines[0].strip()
|
||||
epilog = "\n".join(lines[1:]).strip()
|
||||
self.parser = EvenniaParser(None, description, epilog, command=self)
|
||||
epilogue = "\n".join(lines[1:]).strip()
|
||||
self.parser = UnixCommandParser(None, description, epilogue, command=self)
|
||||
|
||||
# Fill the argument parser
|
||||
self.init()
|
||||
self.init_parser()
|
||||
|
||||
def init(self):
|
||||
def init_parser(self):
|
||||
"""
|
||||
Configure the argument parser, adding in options.
|
||||
|
||||
|
|
@ -143,7 +249,7 @@ class UnixCommand(Command):
|
|||
|
||||
Note:
|
||||
You should not override this method. Consider overriding
|
||||
`init` instead.
|
||||
`init_parser` instead.
|
||||
|
||||
"""
|
||||
try:
|
||||
|
|
@ -153,59 +259,3 @@ class UnixCommand(Command):
|
|||
if msg:
|
||||
self.msg(msg)
|
||||
raise InterruptCommand
|
||||
|
||||
|
||||
class ParseError(Exception):
|
||||
|
||||
"""An error occurred during parsing."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class EvenniaParser(argparse.ArgumentParser):
|
||||
|
||||
"""A parser just for Evennia."""
|
||||
|
||||
def __init__(self, prog, description="", epilog="", command=None, **kwargs):
|
||||
prog = prog or command.key
|
||||
super(EvenniaParser, self).__init__(
|
||||
prog=prog, description=description,
|
||||
conflict_handler='resolve', add_help=False, **kwargs)
|
||||
self.command = command
|
||||
self.post_help = epilog
|
||||
def n_exit(code=None, msg=None):
|
||||
raise ParseError(msg)
|
||||
|
||||
self.exit = n_exit
|
||||
|
||||
# Replace the -h/--help
|
||||
self.add_argument("-h", "--hel", nargs=0, action=HelpAction, help="display heeeelp")
|
||||
|
||||
def format_usage(self):
|
||||
"""Return the usage line."""
|
||||
return raw(super(EvenniaParser, self).format_usage())
|
||||
|
||||
def format_help(self):
|
||||
"""Return the parser help, including its epilog."""
|
||||
autohelp = raw(super(EvenniaParser, self).format_help())
|
||||
return "\n" + autohelp + "\n" + self.post_help
|
||||
|
||||
def print_usage(self, file=None):
|
||||
"""Print the usage to the caller."""
|
||||
if self.command:
|
||||
self.command.msg(self.format_usage().strip())
|
||||
|
||||
def print_help(self, file=None):
|
||||
"""Print the help to the caller."""
|
||||
if self.command:
|
||||
self.command.msg(self.format_help().strip())
|
||||
|
||||
|
||||
class HelpAction(argparse.Action):
|
||||
|
||||
"""Override the -h/--he.p."""
|
||||
|
||||
def __call__(self, parser, namespace, values, option_string=None):
|
||||
if parser.command:
|
||||
parser.command.msg(parser.format_help().strip())
|
||||
parser.exit(0, "")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue