Skip to content

Commit

Permalink
fix: using option to define arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
jnoortheen committed Apr 14, 2020
1 parent a7b63c7 commit ed87eec
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 48 deletions.
32 changes: 14 additions & 18 deletions arger/parser/classes.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import argparse
from enum import Enum
from inspect import isclass
from typing import Any, List, Optional, Tuple
from typing import Any, List, Tuple

from arger.parser.utils import generate_flags

from ..types import UNDEFINED
from ..typing_utils import match_types
Expand All @@ -21,14 +23,7 @@ def get_action(

class Option:
def __init__(
self,
flags: Tuple[str, ...] = (),
type_: Any = UNDEFINED,
default: Any = UNDEFINED,
help_: str = "",
metavar: Optional[str] = None,
required=False,
**kwargs,
self, flags: List[str], default: Any = UNDEFINED, **kwargs,
):
"""Represent optional arguments to the command.
Expand Down Expand Up @@ -69,6 +64,7 @@ def __init__(

self.flags = flags

type_ = kwargs.pop('type', UNDEFINED)
if default is not UNDEFINED:
kwargs["default"] = default

Expand All @@ -82,20 +78,20 @@ def __init__(
elif (type_ is not UNDEFINED) and type_ != bool:
kwargs.setdefault("type", type_)

kwargs.setdefault('help', help_)
kwargs.setdefault('metavar', metavar)
kwargs.setdefault('required', required)
self.kwargs = kwargs

def add(self, parser: argparse.ArgumentParser):
return parser.add_argument(*self.flags, **self.kwargs)

def __repr__(self):
return f'{self.__class__.__name__}: {self.flags}, {repr(self.kwargs)}'

def set_flags(self, option_generator):
hlp = self.kwargs.pop('help').split()
# generate flags
self.flags = generate_flags(self.flags[0], hlp, option_generator)
self.kwargs['help'] = " ".join(hlp)


class Argument(Option):
"""Represent positional argument that are required."""

def __init__(
self, **kwargs,
):
"""See Option.__init__'s doc for more info."""
super().__init__(required=True, **kwargs)
34 changes: 17 additions & 17 deletions arger/parser/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from ..types import UNDEFINED
from .classes import Argument, Option
from .utils import generate_flags, generate_options
from .utils import generate_options


def prepare_arguments(func, param_docs,) -> Dict[str, Option]:
Expand Down Expand Up @@ -42,26 +42,26 @@ def prepare_arguments(func, param_docs,) -> Dict[str, Option]:
option_generator = generate_options()
next(option_generator)

arguments: Dict[str, Option] = OrderedDict()
for param in positional_params:
arguments[param] = Argument(
help_=param_docs.get(param, ""),
def get_args(param):
return dict(
flags=[param],
dest=param,
type_=annotations.get(param, UNDEFINED),
help=param_docs.get(param, ""),
type=annotations.get(param, UNDEFINED),
)

arguments: Dict[str, Option] = OrderedDict()
for param in positional_params:
arguments[param] = Argument(**get_args(param))

for param, default in kw_params.items():
hlp = param_docs.get(param, "")
flags = generate_flags(param, hlp, option_generator)
hlp = " ".join(hlp)
arguments[param] = Option(
help_=hlp,
flags=flags,
dest=param,
type_=annotations.get(param, UNDEFINED),
default=default,
)
if isinstance(default, Argument):
default.flags = [param]
elif isinstance(default, Option):
default.set_flags(option_generator)
else:
default = Option(dest=param, default=default, **get_args(param))
default.set_flags(option_generator)
arguments[param] = default
return arguments


Expand Down
4 changes: 2 additions & 2 deletions arger/parser/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Set
from typing import List, Set


def generate_options():
Expand All @@ -25,7 +25,7 @@ def generate_options():


def generate_flags(
param, param_doc, option_generator,
param: str, param_doc: List[str], option_generator,
):
names = []

Expand Down
28 changes: 17 additions & 11 deletions tests/test_fn_parser.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from collections import OrderedDict

from arger.parser import opterate
from arger.parser.classes import Argument

from .utils import _reprint

Expand All @@ -15,15 +18,18 @@ def main(param1: int, param2: str, kw1=None, kw2=False):
def test_opterate():
doc, args = opterate(func=main)
assert doc == "Example function with types documented in the docstring."
assert args == [
(['param1'], {'action': 'store', 'help': 'The first parameter.', 'type': int}),
(['param2'], {'action': 'store', 'help': 'The second parameter.', 'type': str}),
(
['-k', '--kw1'],
{'action': 'store', 'default': None, 'dest': 'kw1', 'help': ''},
),
(
['-w', '--kw2'],
{'action': 'store_true', 'default': False, 'dest': 'kw2', 'help': '',},
),
assert list(args) == ['param1', 'param2', 'kw1', 'kw2']

assert [v.flags for v in args.values()] == [
['param1'],
['param2'],
['-k', '--kw1'],
['-w', '--kw2'],
]

assert [v.kwargs for v in args.values()] == [
{'action': 'store', 'help': 'The first parameter.', 'type': int,},
{'action': 'store', 'help': 'The second parameter.', 'type': str,},
{'action': 'store', 'default': None, 'dest': 'kw1', 'help': '',},
{'action': 'store_true', 'default': False, 'dest': 'kw2', 'help': '',},
]

0 comments on commit ed87eec

Please sign in to comment.