Compare commits
3 Commits
e2333b8916
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 4f8e111729 | |||
| 326e1bbfa0 | |||
| f93588f4bf |
18
.drone.yml
18
.drone.yml
@@ -3,12 +3,30 @@ type: docker
|
|||||||
name: test
|
name: test
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
- name: black
|
||||||
|
image: pyfound/black:21.7b0
|
||||||
|
commands:
|
||||||
|
- black --check --diff --quiet .
|
||||||
|
depends_on: []
|
||||||
|
|
||||||
|
- name: pyflakes
|
||||||
|
image: alpine/flake8:3.9.2
|
||||||
|
commands:
|
||||||
|
- pyflakes .
|
||||||
|
depends_on: []
|
||||||
|
|
||||||
- name: test-python-3.8
|
- name: test-python-3.8
|
||||||
image: python:3.8-slim
|
image: python:3.8-slim
|
||||||
commands:
|
commands:
|
||||||
- python test.py
|
- python test.py
|
||||||
|
depends_on:
|
||||||
|
- black
|
||||||
|
- pyflakes
|
||||||
|
|
||||||
- name: test-python-3.9
|
- name: test-python-3.9
|
||||||
image: python:3.9-slim
|
image: python:3.9-slim
|
||||||
commands:
|
commands:
|
||||||
- python test.py
|
- python test.py
|
||||||
|
depends_on:
|
||||||
|
- black
|
||||||
|
- pyflakes
|
||||||
|
|||||||
37
argclass.py
37
argclass.py
@@ -10,18 +10,18 @@ def make_gnu_option(name):
|
|||||||
def decide_default(field_):
|
def decide_default(field_):
|
||||||
arg_cfg = {}
|
arg_cfg = {}
|
||||||
if field_.default != MISSING:
|
if field_.default != MISSING:
|
||||||
arg_cfg['default'] = field_.default
|
arg_cfg["default"] = field_.default
|
||||||
elif field_.default_factory != MISSING:
|
elif field_.default_factory != MISSING:
|
||||||
arg_cfg['default'] = field_.default_factory()
|
arg_cfg["default"] = field_.default_factory()
|
||||||
else:
|
else:
|
||||||
arg_cfg['required'] = True
|
arg_cfg["required"] = True
|
||||||
return arg_cfg
|
return arg_cfg
|
||||||
|
|
||||||
|
|
||||||
def get_choices(field_):
|
def get_choices(field_):
|
||||||
arg_cfg = {}
|
arg_cfg = {}
|
||||||
try:
|
try:
|
||||||
arg_cfg['choices'] = field_.metadata['choices']
|
arg_cfg["choices"] = field_.metadata["choices"]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
return arg_cfg
|
return arg_cfg
|
||||||
@@ -38,16 +38,16 @@ def compute_arg_names(name, field_):
|
|||||||
|
|
||||||
def _prepare_bool(ap: ArgumentParser, name, field_):
|
def _prepare_bool(ap: ArgumentParser, name, field_):
|
||||||
arg_cfg = decide_default(field_)
|
arg_cfg = decide_default(field_)
|
||||||
required = 'required' in arg_cfg
|
required = "required" in arg_cfg
|
||||||
bool_parser = ap.add_mutually_exclusive_group(required=required)
|
bool_parser = ap.add_mutually_exclusive_group(required=required)
|
||||||
bool_parser.add_argument(make_gnu_option(name),
|
bool_parser.add_argument(
|
||||||
action='store_true',
|
make_gnu_option(name), action="store_true", dest=name
|
||||||
dest=name)
|
)
|
||||||
bool_parser.add_argument(make_gnu_option(f'no_{name}'),
|
bool_parser.add_argument(
|
||||||
action='store_false',
|
make_gnu_option(f"no_{name}"), action="store_false", dest=name
|
||||||
dest=name)
|
)
|
||||||
if not required:
|
if not required:
|
||||||
ap.set_defaults(**{name: arg_cfg['default']})
|
ap.set_defaults(**{name: arg_cfg["default"]})
|
||||||
|
|
||||||
|
|
||||||
def _prepare_list_cfg(name, field_):
|
def _prepare_list_cfg(name, field_):
|
||||||
@@ -57,14 +57,14 @@ def _prepare_list_cfg(name, field_):
|
|||||||
}
|
}
|
||||||
subtype = typing.get_args(field_.type)
|
subtype = typing.get_args(field_.type)
|
||||||
if not subtype:
|
if not subtype:
|
||||||
arg_cfg['type'] = str
|
arg_cfg["type"] = str
|
||||||
else:
|
else:
|
||||||
arg_cfg['type'] = subtype[0]
|
arg_cfg["type"] = subtype[0]
|
||||||
|
|
||||||
if field_.metadata.get('allow_empty', False):
|
if field_.metadata.get("allow_empty", False):
|
||||||
arg_cfg['nargs'] = '*'
|
arg_cfg["nargs"] = "*"
|
||||||
else:
|
else:
|
||||||
arg_cfg['nargs'] = '+'
|
arg_cfg["nargs"] = "+"
|
||||||
return arg_cfg
|
return arg_cfg
|
||||||
|
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ def _prepare_trivial_cfg(name, field_):
|
|||||||
**decide_default(field_),
|
**decide_default(field_),
|
||||||
**get_choices(field_),
|
**get_choices(field_),
|
||||||
}
|
}
|
||||||
arg_cfg['type'] = field_.type
|
arg_cfg["type"] = field_.type
|
||||||
return arg_cfg
|
return arg_cfg
|
||||||
|
|
||||||
|
|
||||||
@@ -99,7 +99,6 @@ def prepare_field(ap, name, field_):
|
|||||||
|
|
||||||
|
|
||||||
def argclass(cls):
|
def argclass(cls):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def parse_args(cls, argv):
|
def parse_args(cls, argv):
|
||||||
ap = ArgumentParser()
|
ap = ArgumentParser()
|
||||||
|
|||||||
@@ -4,3 +4,7 @@ requires = [
|
|||||||
"wheel"
|
"wheel"
|
||||||
]
|
]
|
||||||
build-backend = "setuptools.build_meta"
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[tool.black]
|
||||||
|
line-length = 79
|
||||||
|
target-version = ["py38"]
|
||||||
|
|||||||
55
test.py
55
test.py
@@ -1,4 +1,3 @@
|
|||||||
from argparse import ArgumentError, ArgumentTypeError
|
|
||||||
import unittest
|
import unittest
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
@@ -6,17 +5,14 @@ from argclass import argclass
|
|||||||
|
|
||||||
|
|
||||||
class TestArgClass(unittest.TestCase):
|
class TestArgClass(unittest.TestCase):
|
||||||
|
|
||||||
def test__required_argument(self):
|
def test__required_argument(self):
|
||||||
|
|
||||||
@argclass
|
@argclass
|
||||||
class A:
|
class A:
|
||||||
arg1: str
|
arg1: str
|
||||||
|
|
||||||
assert A.parse_args(['--arg1', 'hello']) == A(arg1='hello')
|
assert A.parse_args(["--arg1", "hello"]) == A(arg1="hello")
|
||||||
|
|
||||||
def test__required_argument_missing(self):
|
def test__required_argument_missing(self):
|
||||||
|
|
||||||
@argclass
|
@argclass
|
||||||
class A:
|
class A:
|
||||||
arg1: str
|
arg1: str
|
||||||
@@ -24,101 +20,86 @@ class TestArgClass(unittest.TestCase):
|
|||||||
self.assertRaises(SystemExit, A.parse_args, [])
|
self.assertRaises(SystemExit, A.parse_args, [])
|
||||||
|
|
||||||
def test__required_argument_wrong_given(self):
|
def test__required_argument_wrong_given(self):
|
||||||
|
|
||||||
@argclass
|
@argclass
|
||||||
class A:
|
class A:
|
||||||
arg1: str
|
arg1: str
|
||||||
|
|
||||||
self.assertRaises(SystemExit, A.parse_args, ['--arg2', 'hello'])
|
self.assertRaises(SystemExit, A.parse_args, ["--arg2", "hello"])
|
||||||
|
|
||||||
def test__optional_argument_missing(self):
|
def test__optional_argument_missing(self):
|
||||||
|
|
||||||
@argclass
|
@argclass
|
||||||
class A:
|
class A:
|
||||||
arg2: str = 'world'
|
arg2: str = "world"
|
||||||
|
|
||||||
assert A.parse_args([]) == A(arg2='world')
|
assert A.parse_args([]) == A(arg2="world")
|
||||||
|
|
||||||
def test__optional_argument_given(self):
|
def test__optional_argument_given(self):
|
||||||
|
|
||||||
@argclass
|
@argclass
|
||||||
class A:
|
class A:
|
||||||
arg2: str = 'world'
|
arg2: str = "world"
|
||||||
|
|
||||||
assert A.parse_args(['--arg2', 'welt']) == A(arg2='welt')
|
assert A.parse_args(["--arg2", "welt"]) == A(arg2="welt")
|
||||||
|
|
||||||
def test__optional_argument_wrong_given(self):
|
def test__optional_argument_wrong_given(self):
|
||||||
|
|
||||||
@argclass
|
@argclass
|
||||||
class A:
|
class A:
|
||||||
arg2: str = 'world'
|
arg2: str = "world"
|
||||||
|
|
||||||
self.assertRaises(SystemExit, A.parse_args, ['--arg3', 'welt'])
|
self.assertRaises(SystemExit, A.parse_args, ["--arg3", "welt"])
|
||||||
|
|
||||||
def test__boolean_true(self):
|
def test__boolean_true(self):
|
||||||
|
|
||||||
@argclass
|
@argclass
|
||||||
class A:
|
class A:
|
||||||
arg3: bool
|
arg3: bool
|
||||||
|
|
||||||
assert A.parse_args(['--arg3']) == A(arg3=True)
|
assert A.parse_args(["--arg3"]) == A(arg3=True)
|
||||||
|
|
||||||
def test__boolean_false(self):
|
def test__boolean_false(self):
|
||||||
|
|
||||||
@argclass
|
@argclass
|
||||||
class A:
|
class A:
|
||||||
arg3: bool
|
arg3: bool
|
||||||
|
|
||||||
assert A.parse_args(['--no-arg3']) == A(arg3=False)
|
assert A.parse_args(["--no-arg3"]) == A(arg3=False)
|
||||||
|
|
||||||
def test__int(self):
|
def test__int(self):
|
||||||
|
|
||||||
@argclass
|
@argclass
|
||||||
class A:
|
class A:
|
||||||
arg4: int
|
arg4: int
|
||||||
|
|
||||||
assert A.parse_args(['--arg4', '42']) == A(arg4=42)
|
assert A.parse_args(["--arg4", "42"]) == A(arg4=42)
|
||||||
|
|
||||||
def test__int_malformed(self):
|
def test__int_malformed(self):
|
||||||
|
|
||||||
@argclass
|
@argclass
|
||||||
class A:
|
class A:
|
||||||
arg4: int
|
arg4: int
|
||||||
|
|
||||||
self.assertRaises(SystemExit, A.parse_args, ['--arg4', '4e2'])
|
self.assertRaises(SystemExit, A.parse_args, ["--arg4", "4e2"])
|
||||||
|
|
||||||
def test__list(self):
|
def test__list(self):
|
||||||
|
|
||||||
@argclass
|
@argclass
|
||||||
class A:
|
class A:
|
||||||
arg5: List
|
arg5: List
|
||||||
|
|
||||||
assert (
|
assert A.parse_args(["--arg5", "hello", "world"]) == A(
|
||||||
A.parse_args(['--arg5', 'hello', 'world'])
|
arg5=["hello", "world"]
|
||||||
==
|
|
||||||
A(arg5=['hello', 'world'])
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def test__list_str(self):
|
def test__list_str(self):
|
||||||
|
|
||||||
@argclass
|
@argclass
|
||||||
class A:
|
class A:
|
||||||
arg5: List[str]
|
arg5: List[str]
|
||||||
|
|
||||||
assert (
|
assert A.parse_args(["--arg5", "hello", "world"]) == A(
|
||||||
A.parse_args(['--arg5', 'hello', 'world'])
|
arg5=["hello", "world"]
|
||||||
==
|
|
||||||
A(arg5=['hello', 'world'])
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def test__list_int(self):
|
def test__list_int(self):
|
||||||
|
|
||||||
@argclass
|
@argclass
|
||||||
class A:
|
class A:
|
||||||
arg5: List[int]
|
arg5: List[int]
|
||||||
|
|
||||||
assert A.parse_args(['--arg5', '23', '42']) == A(arg5=[23, 42])
|
assert A.parse_args(["--arg5", "23", "42"]) == A(arg5=[23, 42])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
Reference in New Issue
Block a user