jonathanhaigh / multiconfparse

Python 3 library for obtaining configuration from multiple sources
MIT License
1 stars 1 forks source link

Allow Argparse actions (with a wrapper) as multiconfparse actions? #88

Open jonathanhaigh opened 4 years ago

jonathanhaigh commented 4 years ago

Step 1: make Multiconfparse actions more like Argparse actions by:

jonathanhaigh commented 4 years ago

Let's see what values look like when they get to an Argparse Action class:

>>> import argparse as ap
>>> class A(ap.Action):
...     def __init__(self, option_strings, dest, **kwargs):
...              super().__init__(option_strings, dest, **kwargs)
...     def __call__(self, parser, namespace, values, option_string):
...             print(f"__call__(parser, namespace, {values}, {option_string})")
... 
>>> p = ap.ArgumentParser()
>>> p.add_argument("--c0", action=A, nargs=0)
A(option_strings=['--c0'], dest='c0', nargs=0, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> p.add_argument("--cn", action=A)
A(option_strings=['--cn'], dest='cn', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> p.add_argument("--cq", action=A, nargs="?")
A(option_strings=['--cq'], dest='cq', nargs='?', const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> p.add_argument("--c1", action=A, nargs=1)
A(option_strings=['--c1'], dest='c1', nargs=1, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> p.add_argument("--c2", action=A, nargs=2)
A(option_strings=['--c2'], dest='c2', nargs=2, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> p.add_argument("--cp", action=A, nargs="+")
A(option_strings=['--cp'], dest='cp', nargs='+', const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> p.add_argument("--cs", action=A, nargs="*")
A(option_strings=['--cs'], dest='cs', nargs='*', const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> p.parse_args("--c0 --cn cnv --cq --cq cqv --c1 c1v --c2 c2v1 c2v2 --cp cpv1 --cp cpv1 cpv2 --cs --cs csv1 csv2".split())
__call__(parser, namespace, [], --c0)
__call__(parser, namespace, cnv, --cn)
__call__(parser, namespace, None, --cq)
__call__(parser, namespace, cqv, --cq)
__call__(parser, namespace, ['c1v'], --c1)
__call__(parser, namespace, ['c2v1', 'c2v2'], --c2)
__call__(parser, namespace, ['cpv1'], --cp)
__call__(parser, namespace, ['cpv1', 'cpv2'], --cp)
__call__(parser, namespace, [], --cs)
__call__(parser, namespace, ['csv1', 'csv2'], --cs)
Namespace(c0=None, c1=None, c2=None, cn=None, cp=None, cq=None, cs=None)
>>>

It's a bit strange that in the nargs == 0 case, [] is the value rather than None like in the nargs == "?" case when no argument is provided, but I guess it's just following the other cases where nargs is an integer.

jonathanhaigh commented 4 years ago

Using [] for nargs == 0 values does mean that something like multiconfparse's MENTIONED_WITHOUT_VALUE isn't necessary for nargs == 0, but it would still be required for the nargs == "+" case without a value if we want to distinguish that case from the case where the value is None.