- it's better to let another library handle constraint types
- the name types.py was too generic; special_types.py is a bit more
specific
---
.builds/unittest.yml | 2 ++
tests/test_integration.py | 6 ++++--
typed_flags/__init__.py | 2 +-
typed_flags/flags.py | 14 ++++++------
typed_flags/special_types.py | 23 ++++++++++++++++++++
typed_flags/types.py | 42 ------------------------------------
6 files changed, 37 insertions(+), 52 deletions(-)
create mode 100644 typed_flags/special_types.py
delete mode 100644 typed_flags/types.py
diff --git a/.builds/unittest.yml b/.builds/unittest.yml
index 3e8c5eb..72e78c1 100644
--- a/.builds/unittest.yml
+++ b/.builds/unittest.yml
@@ -5,6 +5,8 @@ packages:
sources:
- https://git.sr.ht/~tmk/typed-flags
tasks:
+ - setup: |
+ python -m pip install teext==0.1.1
- test: |
cd typed-flags
python -m unittest -v
diff --git a/tests/test_integration.py b/tests/test_integration.py
index ade6fc2..ae58b8c 100644
--- a/tests/test_integration.py
+++ b/tests/test_integration.py
@@ -3,7 +3,9 @@ import unittest
from typing import List, Literal, Optional, Set, Dict
from unittest import TestCase
-from typed_flags import TypedFlags, PositiveInt
+from teext import PositiveInt
+
+from typed_flags import TypedFlags
class EdgeCaseTests(TestCase):
@@ -105,7 +107,7 @@ class RequiredClassVariableTests(TestCase):
pos_num: PositiveInt
args = ConstraintViolation()
- with self.assertRaises(SystemExit):
+ with self.assertRaises(AssertionError):
args.parse_args(["--pos-num", "0"])
def tearDown(self) -> None:
diff --git a/typed_flags/__init__.py b/typed_flags/__init__.py
index 1e7a3e9..29eea89 100644
--- a/typed_flags/__init__.py
+++ b/typed_flags/__init__.py
@@ -1,2 +1,2 @@
from .flags import *
-from .types import *
+from .special_types import *
diff --git a/typed_flags/flags.py b/typed_flags/flags.py
index c74eff1..a0069cb 100644
--- a/typed_flags/flags.py
+++ b/typed_flags/flags.py
@@ -25,10 +25,9 @@ from .utils import (
is_literal_type,
is_option_arg,
is_optional_type,
- is_union_type,
type_to_str,
)
-from .types import StoreDictKeyPair, maybe_convert
+from .special_types import StoreDictKeyPair
__all__ = ["TypedFlags"]
@@ -140,7 +139,7 @@ class TypedFlags(ArgumentParser):
kwargs["nargs"] = kwargs.get("nargs", "*")
else:
# If List type, extract type of elements in list and set nargs
- kwargs["type"] = maybe_convert(arg)
+ kwargs["type"] = arg
kwargs["nargs"] = kwargs.get("nargs", "*")
elif origin is dict:
@@ -148,8 +147,8 @@ class TypedFlags(ArgumentParser):
kwargs["action"] = StoreDictKeyPair
kwargs["nargs"] = kwargs.get("nargs", "*")
kwargs["type"] = str
- kwargs["key_type"] = maybe_convert(key_type)
- kwargs["value_type"] = maybe_convert(value_type)
+ kwargs["key_type"] = key_type
+ kwargs["value_type"] = value_type
elif origin is None:
# If bool then set action, otherwise set type
@@ -157,7 +156,7 @@ class TypedFlags(ArgumentParser):
kwargs["type"] = eval
kwargs["choices"] = [True, False]
else:
- kwargs["type"] = maybe_convert(var_type)
+ kwargs["type"] = var_type
if var_type == float:
kwargs["metavar"] = "FLOAT"
elif var_type == int:
@@ -167,7 +166,8 @@ class TypedFlags(ArgumentParser):
f'Variable "{variable}" has type "{var_type}" which is not supported by default.\n'
f"Please explicitly add the argument to the parser by writing:\n\n"
f"def add_arguments(self) -> None:\n"
- f' self.add_argument("--{variable}", type=func, {"required=True" if kwargs["required"] else f"default={getattr(self, variable)}"})\n\n'
+ f' self.add_argument("--{variable}", type=func, '
+ f'{"required=True" if kwargs["required"] else f"default={getattr(self, variable)}"})\n\n'
f'where "func" maps from str to {var_type}.'
)
diff --git a/typed_flags/special_types.py b/typed_flags/special_types.py
new file mode 100644
index 0000000..76739cc
--- /dev/null
+++ b/typed_flags/special_types.py
@@ -0,0 +1,23 @@
+"""Custom types for use with TypedFlags."""
+from argparse import Action
+from typing import Any
+
+__all__ = ["StoreDictKeyPair"]
+
+
+class StoreDictKeyPair(Action):
+ """Action for parsing dictionaries on the commandline."""
+
+ def __init__(
+ self, option_strings: Any, key_type: type, value_type: type, *args: Any, **kwargs: Any
+ ):
+ self._key_type = key_type
+ self._value_type = value_type
+ super().__init__(option_strings, *args, **kwargs)
+
+ def __call__(self, parser: Any, namespace: Any, values: Any, option_string: Any = None) -> None:
+ my_dict = {}
+ for key_value in values:
+ key, value = key_value.split("=")
+ my_dict[self._key_type(key.strip())] = self._value_type(value.strip())
+ setattr(namespace, self.dest, my_dict)
diff --git a/typed_flags/types.py b/typed_flags/types.py
deleted file mode 100644
index cc9b4a9..0000000
--- a/typed_flags/types.py
@@ -1,42 +0,0 @@
-"""Custom types for use with TypedFlags."""
-from argparse import Action, ArgumentTypeError
-from typing import Any, Callable, NewType, Mapping, Union
-
-__all__ = ["StoreDictKeyPair", "PositiveInt", "maybe_convert"]
-
-
-class StoreDictKeyPair(Action):
- """Action for parsing dictionaries on the commandline."""
-
- def __init__(
- self, option_strings: Any, key_type: type, value_type: type, *args: Any, **kwargs: Any
- ):
- self._key_type = key_type
- self._value_type = value_type
- super().__init__(option_strings, *args, **kwargs)
-
- def __call__(self, parser: Any, namespace: Any, values: Any, option_string: Any = None) -> None:
- my_dict = {}
- for kv in values:
- k, v = kv.split("=")
- my_dict[self._key_type(k.strip())] = self._value_type(v.strip())
- setattr(namespace, self.dest, my_dict)
-
-
-PositiveInt = NewType("PositiveInt", int)
-
-
-def _to_positive_int(arg: str) -> PositiveInt:
- num = int(arg)
- if num > 0:
- return PositiveInt(num)
- raise ArgumentTypeError(f"{num} is not positive")
-
-
-TYPE_TO_CONSTRUCTOR: Mapping[type, Callable[[str], Any]] = {
- PositiveInt: _to_positive_int,
-}
-
-
-def maybe_convert(arg_type: type) -> Union[type, Callable]:
- return TYPE_TO_CONSTRUCTOR.get(arg_type, arg_type)
--
2.24.3 (Apple Git-128)