Skip to content

Commit

Permalink
fix: recognise type from typehint and default value
Browse files Browse the repository at this point in the history
  • Loading branch information
jnoortheen committed Apr 11, 2020
1 parent de0ee49 commit 405cfad
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 9 deletions.
4 changes: 2 additions & 2 deletions arger/decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ def _add_fn(self, fn) -> (str, Optional[Callable]):
desc, args = opterate(fn)

def add_args(): # lazy adding of arguments
for arg, kw in args:
self.add_argument(*arg, **kw)
for flags, kw in args:
self.add_argument(*flags, **kw)

return desc, add_args
return "", None
Expand Down
9 changes: 6 additions & 3 deletions arger/parser/parser.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# most of this module is taken from https://github.com/dusty-phillips/opterator
from enum import Enum
from inspect import isclass
from typing import Any, List, Set, Tuple

from arger.parser.docstring import parse_docstring
Expand Down Expand Up @@ -92,15 +93,17 @@ def add_param(
option_kwargs["dest"] = param
names = get_arg_names(param, param_doc, option_generator)

if _type is UNDEFINED:
if _type is UNDEFINED and default is not None:
_type = type(default)

option_kwargs.update(
{"action": get_action(_type, default), "help": " ".join(param_doc),}
{"action": get_action(_type, default), "help": " ".join(param_doc)}
)

if issubclass(_type, Enum):
if isclass(_type) and issubclass(_type, Enum):
option_kwargs["choices"] = [e.value for e in _type]
elif (_type is not UNDEFINED) and _type != bool:
option_kwargs["type"] = _type

return (names, option_kwargs)

Expand Down
8 changes: 4 additions & 4 deletions tests/examples/1_single_function.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
1. ran with both options
```shell script
$ python 1_single_function.py 10 p2
param1 (<class 'str'>): 10
param1 (<class 'int'>): 10
param2 (<class 'str'>): p2
kw1 (<class 'NoneType'>): None
kw2 (<class 'bool'>): False
Expand Down Expand Up @@ -42,13 +42,13 @@ pytest: error: the following arguments are required: param1, param2
4. ran with invalid type
```shell script
$ python 1_single_function.py p1 p2
usage: pytest [-h] [-k KW1] [-w] param1 param2
pytest: error: unrecognized arguments: p1
usage: pytest [-h] [-k KW1] [-w] param1 param2
pytest: error: argument param1: invalid int value: 'p1'
```

5. ran with one argument missing
```shell script
$ python 1_single_function.py p1
usage: pytest [-h] [-k KW1] [-w] param1 param2
pytest: error: the following arguments are required: param2
pytest: error: argument param1: invalid int value: 'p1'
```
35 changes: 35 additions & 0 deletions tests/test_fn_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from arger.parser import opterate

from .utils import _reprint


def main(param1: int, param2: str, kw1=None, kw2=False):
"""Example function with types documented in the docstring.
:param param1: The first parameter.
:param param2: The second parameter.
"""
_reprint(**locals())


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': '',
"type": bool,
},
),
]

0 comments on commit 405cfad

Please sign in to comment.