Skip to content

Instantly share code, notes, and snippets.

@roganartu
Last active April 22, 2020 21:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save roganartu/7c2ec129d868ecda95acfbd655ef0ab2 to your computer and use it in GitHub Desktop.
Save roganartu/7c2ec129d868ecda95acfbd655ef0ab2 to your computer and use it in GitHub Desktop.
Example for extend_const addition to argparse stdlib
import argparse
class ExtendConstAction(argparse._AppendConstAction):
# This class is bad because it references private argparse functions/classes.
# Don't use it in production! It only exists here for demonstration purposes.
def __call__(self, parser, namespace, values, option_string=None):
# Copied almost verbatim from _AppendConstAction.__call__
# https://github.com/python/cpython/blob/39652cd8bdf7c82b7c6055089a4ed90ee546a448/Lib/argparse.py#L1028
items = getattr(namespace, self.dest, None)
items = argparse._copy_items(items)
items.extend(self.const) # This is the only line changed from super().__call__
setattr(namespace, self.dest, items)
def example(to_parse):
parser = argparse.ArgumentParser()
parser.add_argument("--filter-by", action="append")
parser.add_argument("--by-foo", action="append_const", dest="filter_by", const="foo")
parser.add_argument("--by-bar", action="append_const", dest="filter_by", const="bar")
# This is the action I am proposing be added
# parser.add_argument("--by-both", action="extend_const", dest="filter_by", const=["foo", "bar"])
parser.add_argument("--by-both", action=ExtendConstAction, dest="filter_by", const=["foo", "bar"])
return parser.parse_args(to_parse)
example("--filter-by foo --filter-by bar".split())
example("--by-foo".split())
example("--by-bar".split())
example("--by-foo --by-bar".split())
example("--by-both".split())
$ python example.py
--filter-by foo --filter-by bar: Namespace(filter_by=['foo', 'bar'])
--by-foo: Namespace(filter_by=['foo'])
--by-bar: Namespace(filter_by=['bar'])
--by-foo --by-bar: Namespace(filter_by=['foo', 'bar'])
--by-both: Namespace(filter_by=['foo', 'bar'])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment