From 7299ed24c69ac9c8acdee4a46dd9cdab6365d40f Mon Sep 17 00:00:00 2001 From: Pedro Silva Date: Tue, 22 Oct 2013 17:48:49 +0200 Subject: [PATCH 1/2] Add vararg_callback utility function to beets.ui Optparse doesn't support argparse nargs='+' style arguments. This patch adds a callback utility function that allows that idiom. The function is taken from the page at http://docs.python.org/2/library/optparse.html#callback-example-6-variable-arguments. Here's an example of how to use it: from beets.ui import vararg_callback parser.add_option("-c", "--callback", dest="vararg_attr", action="callback", callback=vararg_callback) --- beets/ui/__init__.py | 27 +++++++++++++++++++++++++++ docs/changelog.rst | 4 ++++ docs/dev/plugins.rst | 2 ++ 3 files changed, 33 insertions(+) diff --git a/beets/ui/__init__.py b/beets/ui/__init__.py index cdc29cc28..cdcf778e2 100644 --- a/beets/ui/__init__.py +++ b/beets/ui/__init__.py @@ -695,6 +695,33 @@ class SubcommandsOptionParser(optparse.OptionParser): return options, subcommand, suboptions, subargs +# callback for an option with variable arguments +# parser.add_option("-c", "--callback", dest="vararg_attr", +# action="callback", callback=vararg_callback) + +def vararg_callback(option, opt_str, value, parser): + assert value is None + value = [] + + def floatable(str): + try: + float(str) + return True + except ValueError: + return False + + for arg in parser.rargs: + # stop on --foo like options + if arg[:2] == "--" and len(arg) > 2: + break + # stop on -a, but not on -3 or -3.0 + if arg[:1] == "-" and len(arg) > 1 and not floatable(arg): + break + value.append(arg) + + del parser.rargs[:len(value)] + setattr(parser.values, option.dest, value) + # The root parser and its main function. def _raw_main(args): diff --git a/docs/changelog.rst b/docs/changelog.rst index b3679293d..4ba970a5f 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -6,6 +6,10 @@ Changelog New features: +* :ref:`add_subcommands`: Added ``optparse`` callback utility function, allowing + plugin developers to add options with ``action=callback`` and + ``callback=beets.ui.varargs_callback`` and a variable number of arguments. + * :doc:`/plugins/duplicates`: The new ``keys`` option allows you to specify arbitrary fields over which to consider potential duplicates. diff --git a/docs/dev/plugins.rst b/docs/dev/plugins.rst index eacd3c271..6feb73326 100644 --- a/docs/dev/plugins.rst +++ b/docs/dev/plugins.rst @@ -44,6 +44,8 @@ containing your plugin). .. _virtualenv: http://pypi.python.org/pypi/virtualenv +.. _add_subcommands: + Add Commands to the CLI ^^^^^^^^^^^^^^^^^^^^^^^ From 48b963a66e368454e0ac78da682edb1651a37de8 Mon Sep 17 00:00:00 2001 From: Pedro Silva Date: Tue, 22 Oct 2013 21:46:46 +0200 Subject: [PATCH 2/2] Add docstring to new varargs callback ui function --- beets/ui/__init__.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/beets/ui/__init__.py b/beets/ui/__init__.py index cdcf778e2..d550d05a4 100644 --- a/beets/ui/__init__.py +++ b/beets/ui/__init__.py @@ -695,11 +695,19 @@ class SubcommandsOptionParser(optparse.OptionParser): return options, subcommand, suboptions, subargs -# callback for an option with variable arguments -# parser.add_option("-c", "--callback", dest="vararg_attr", -# action="callback", callback=vararg_callback) - def vararg_callback(option, opt_str, value, parser): + """Callback for an option with variable arguments. + Manually collect arguments right of a callback-action + option (ie. with action="callback"), and add the resulting + list to the destination var. + + Usage: + parser.add_option("-c", "--callback", dest="vararg_attr", + action="callback", callback=vararg_callback) + + Details: + http://docs.python.org/2/library/optparse.html#callback-example-6-variable-arguments + """ assert value is None value = []