def decorate_docopt_usage(func):
"""Handle DocoptExit exception
:param func: function
:type func: function
:return: wrapped function
:rtype: function
"""
@wraps(func)
def wrapper(*args, **kwargs):
try:
result = func(*args, **kwargs)
except docopt.DocoptExit as e:
emitter.publish("Command not recognized\n")
emitter.publish(e)
return 1
return result
return wrapper
python类DocoptExit()的实例源码
def docopt_cmd(func):
def fn(self, arg):
try:
if fn.__name__ == "do_pub":
# Fix for negative numbers
opt = docopt(fn.__doc__, arg, options_first=True)
else:
opt = docopt(fn.__doc__, arg)
except DocoptExit as e:
print('Command is invalid. See :')
print(e)
return
except SystemExit:
# The SystemExit exception prints the usage for --help
# We do not need to do the print here.
return
return func(self, opt)
fn.__name__ = func.__name__
fn.__doc__ = func.__doc__
fn.__dict__.update(func.__dict__)
return fn
def docopt_parse(doc, argv=None, version=None):
import docopt as _docopt
def extras_patch(help, version, options, doc):
"""Patch of docopt.extra handler.
Patch for docopt's 'extras' function is needed, as it is hard
sys-exiting the bot after '--help/-h' or '--version' commands
"""
exc = None
if help and any((o.name in ('-h', '--help')) and o.value
for o in options):
exc = _docopt.DocoptExit()
exc.args = (doc.strip("\n"), )
if version and any(o.name == '--version' and o.value for o in options):
exc = _docopt.DocoptExit()
exc.args = (version, )
if exc is not None:
raise exc
# Apply the patch above to docopt.extras
_docopt.extras = extras_patch
return _docopt.docopt(doc, argv=argv, version=version)
def decorate_docopt_usage(func):
"""Handle DocoptExit exception
:param func: function
:type func: function
:return: wrapped function
:rtype: function
"""
@wraps(func)
def wrapper(*args, **kwargs):
try:
result = func(*args, **kwargs)
except docopt.DocoptExit as e:
emitter.publish("Command not recognized\n")
emitter.publish(e)
return 1
return result
return wrapper
def test_without_command(self):
with self.assertRaises(DocoptExit) as context:
StateHolder.skip_docker = True
poco = Poco(home_dir=self.tmpdir, argv=[""])
poco.run()
self.assertIsNotNone(context.exception)
def test_wrong_parameters(self):
with self.assertRaises(DocoptExit) as context:
StateHolder.skip_docker = True
poco = Poco(home_dir=self.tmpdir, argv=["notexistcommand"])
poco.run()
self.assertIsNotNone(context.exception)
def cliparser(func):
"""
This decorator is used to simplify the try/except block and pass the result
of the docopt parsing to the called action.
"""
def fn(self, arg):
try:
opt = docopt(fn.__doc__, arg)
except DocoptExit as e:
# The DocoptExit is thrown when the args do not match.
# We print a message to the user and the usage block.
print('Invalid Command!')
print(e)
return
except SystemExit:
# The SystemExit exception prints the usage for --help
# We do not need to do the print here.
return
return func(self, opt)
fn.__name__ = func.__name__
fn.__doc__ = func.__doc__
fn.__dict__.update(func.__dict__)
return fn
def parse_commands(docstring):
# type: (str) -> Generator[Tuple[List[str], List[str]], None, None]
"""Parse a docopt-style string for commands and subcommands.
Args:
docstring: A docopt-style string to parse. If the string is not a valid
docopt-style string, it will not yield and values.
Yields:
All tuples of commands and subcommands found in the docopt docstring.
"""
try:
docopt.docopt(docstring, argv=())
except (TypeError, docopt.DocoptLanguageError):
return
except docopt.DocoptExit:
pass
for command in _parse_section('usage', docstring):
args = command.split()
commands = []
i = 0
for i, arg in enumerate(args):
if arg[0].isalpha() and not arg[0].isupper():
commands.append(arg)
else:
break
yield commands, args[i:]
def settable_options(doc, argv, ignore, options_first):
"""Determine which options we can set, which ones are boolean, and which ones are repeatable.
All set items are option long names.
:param str doc: Docstring from docoptcfg().
:param iter argv: CLI arguments from docoptcfg().
:param iter ignore: Options to ignore from docoptcfg().
:param bool options_first: docopt argument from docoptcfg().
:return: Settable options, boolean options, repeatable options, and short to long option name mapping.
:rtype: tuple
"""
settable, booleans, repeatable, short_map = set(), set(), set(), dict()
# Determine which options are settable by docoptcfg and which ones are flags/booleans.
options = docopt.parse_defaults(doc)
short_map.update((o.short, o.long) for o in options)
parsed_argv = docopt.parse_argv(docopt.TokenStream(argv, docopt.DocoptExit), list(options), options_first)
overridden = [o.long for o in parsed_argv if hasattr(o, 'long')]
for option in options:
if option.long in overridden or (option.long in ignore or option.short in ignore):
continue
if option.argcount == 0:
booleans.add(option.long)
settable.add(option.long)
# Determine which options are repeatable.
if settable and '...' in doc:
pattern = docopt.parse_pattern(docopt.formal_usage(docopt.DocoptExit.usage), options)
for option in pattern.fix().flat():
if not hasattr(option, 'long'):
continue # Positional argument or sub-command.
if getattr(option, 'long') not in settable:
continue # Don't care about this if we can't set it.
if getattr(option, 'long') in booleans and getattr(option, 'value') == 0:
repeatable.add(getattr(option, 'long'))
elif hasattr(getattr(option, 'value'), '__iter__'):
repeatable.add(getattr(option, 'long'))
return settable, booleans, repeatable, short_map
def docopt_cmd(func):
"""
This decorator is used to simplify the try/except block and pass the result
of the docopt parsing to the called action.
"""
def fn(self, arg):
try:
opt = docopt(fn.__doc__, arg)
except DocoptExit as e:
# The DocoptExit is thrown when the args do not match.
# We print a message to the user and the usage block.
print('Invalid Command!')
print(e)
return
except SystemExit:
# The SystemExit exception prints the usage for --help
# We do not need to do the print here.
return
return func(self, opt)
fn.__name__ = func.__name__
fn.__doc__ = func.__doc__
fn.__dict__.update(func.__dict__)
return fn
def runtest(self):
try:
result = docopt.docopt(self.doc, argv=self.argv)
except docopt.DocoptExit:
result = 'user-error'
if self.expect != result:
raise DocoptTestException(self, result)
def test_required_argument_search(self):
sys.argv = ['prog_name', '--search']
self.assertRaises(docopt.DocoptExit, docopt.docopt, __doc__)
def test_required_argument_target(self):
sys.argv = ['prog_name', '--target']
self.assertRaises(docopt.DocoptExit, docopt.docopt, __doc__)
def test_required_argument_filter(self):
sys.argv = ['prog_name', '--filter']
self.assertRaises(docopt.DocoptExit, docopt.docopt, __doc__)
def test_required_argument_results(self):
sys.argv = ['prog_name', '--results']
self.assertRaises(docopt.DocoptExit, docopt.docopt, __doc__)
def test_required_argument_quality(self):
sys.argv = ['prog_name', '--quality']
self.assertRaises(docopt.DocoptExit, docopt.docopt, __doc__)
def test_required_argument_sort_type(self):
sys.argv = ['prog_name', '--sort-type']
self.assertRaises(docopt.DocoptExit, docopt.docopt, __doc__)
def test_no_required_argument_list(self):
sys.argv = ['prog_name', '--list']
try:
docopt.docopt(__doc__)
except docopt.DocoptExit:
self.fail('--list required argument!')
def test_no_required_argument_links(self):
sys.argv = ['prog_name', '--links']
try:
docopt.docopt(__doc__)
except docopt.DocoptExit:
self.fail('--links required argument!')
def test_no_required_argument_get_list(self):
sys.argv = ['prog_name', '--get-list']
try:
docopt.docopt(__doc__)
except docopt.DocoptExit:
self.fail('--get-list required argument!')
def test_no_required_argument_version(self):
sys.argv = ['prog_name', '--version']
try:
docopt.docopt(__doc__)
except docopt.DocoptExit:
self.fail('--version required argument!')
def handle(self, arguments, user, **kwargs):
parsed = shlex.split(arguments)
try:
args = docopt.docopt(self.usage, parsed)
except docopt.DocoptExit as e:
raise exceptions.HandleError(safestring.mark_safe(str(e)), code='invalid_arg')
subcommand = arguments.split(' ')[0]
f = getattr(self, 'handle_{0}'.format(subcommand))
r = f(args, user, **kwargs)
r['parsed_arguments'] = args
r['subcommand'] = subcommand
return r
def test_noop():
"""Ensure docopt exit (displays usage)
"""
with pytest.raises(DocoptExit):
main([])
with pytest.raises(DocoptExit):
main(['foobar'])
def respond(self, cmd, msg_json):
"""Respond to a bot command."""
try:
# Create a 'fake' CLI execution of the actual bot program
argv = shlex.split(cmd.replace('``', '"'))
args = docopt_parse(C.DOC, argv=argv, version=__version__)
bot_main(self, args, msg_json)
except docopt.DocoptExit as e:
self.send("```text\n{0}```".format(str(e)))
def respond(self, cmd, msg_json, room_id=None):
"""Respond to a bot command."""
try:
# Create a 'fake' CLI execution of the actual bot program
argv = cmd.split()
args = docopt_parse(C.DOC, argv=argv)
client = GitterClient(self.token, room_id)
bot_main(client, args, msg_json)
except docopt.DocoptExit as e:
self.send("```text\n{0}```".format(str(e)))
def test_commit_status_no_args(self):
try:
githubtools.commit_status.main()
except DocoptExit as e:
self.assertTrue(str(e).startswith("Usage:"))
else:
self.assertTrue(False)
def test_create_pull_request_no_args(self):
try:
githubtools.create_pull_request.main()
except DocoptExit as e:
self.assertTrue(str(e).startswith("Usage:"))
else:
self.assertTrue(False)
def test_merge_pull_request_no_args(self):
try:
githubtools.merge_pull_request.main()
except DocoptExit as e:
self.assertTrue(str(e).startswith("Usage:"))
else:
self.assertTrue(False)
def test_merge_no_args(self):
try:
githubtools.merge.main()
except DocoptExit as e:
self.assertTrue(str(e).startswith("Usage:"))
else:
self.assertTrue(False)
def main(args=None):
args = docopt(__doc__, argv=args, version=VERSION)
# from the whole input bag, split media files from transcriptions
# media and its transcript must be paired (i.e same order)
# for example, supose a folder with a video file macri_gato.mp4 and
# its transcription is macri_gato.txt
#
# *.mp4 *.txt
# macri_gato.*
# macri_gato.mp4 macri_gato.txt
media = []
transcripts = []
for filename in chain.from_iterable(glob.iglob(pattern) for pattern in args['<input_files>']):
output_extension = os.path.splitext(filename)[1][1:]
if output_extension in extensions_dict:
media.append(filename)
else:
transcripts.append(filename)
media_str = ' \n'.join(media)
transcripts_str = ' \n'.join(transcripts)
info = "Audio/Video:\n {}\nTranscripts/subtitle:\n {}".format(media_str, transcripts_str)
logging.info(info)
if not media or len(media) != len(transcripts):
raise DocoptExit(
"Input mismatch: the quantity of inputs and transcriptions differs"
)
try:
return miau(
media,
transcripts,
args['--remix'],
args['--output'],
args['--dump'],
debug=args['--debug'],
force_language=args['--lang']
)
except ValueError as e:
raise DocoptExit(str(e))