summaryrefslogtreecommitdiff
path: root/argparse_utils.py
diff options
context:
space:
mode:
authorScott Gasch <[email protected]>2021-09-15 09:32:08 -0700
committerScott Gasch <[email protected]>2021-09-15 09:32:08 -0700
commit4c315e387f18010ba0b5661744ad3c792f21d2d1 (patch)
treea5657340bea356aa3aaf2c24b7f2be98bb4bc302 /argparse_utils.py
parent83c1e0d04fe2e78963c8b508e8b7d0ae03bfcb16 (diff)
Adding doctests. Also added a logging filter.
Diffstat (limited to 'argparse_utils.py')
-rw-r--r--argparse_utils.py120
1 files changed, 118 insertions, 2 deletions
diff --git a/argparse_utils.py b/argparse_utils.py
index 3799a47..0ee2be9 100644
--- a/argparse_utils.py
+++ b/argparse_utils.py
@@ -4,6 +4,7 @@ import argparse
import datetime
import logging
import os
+from typing import Any
# This module is commonly used by others in here and should avoid
# taking any unnecessary dependencies back on them.
@@ -56,14 +57,54 @@ class ActionNoYes(argparse.Action):
setattr(namespace, self.dest, True)
-def valid_bool(v):
+def valid_bool(v: Any) -> bool:
+ """
+ If the string is a valid bool, return its value.
+
+ >>> valid_bool(True)
+ True
+
+ >>> valid_bool("true")
+ True
+
+ >>> valid_bool("yes")
+ True
+
+ >>> valid_bool("on")
+ True
+
+ >>> valid_bool("1")
+ True
+
+ >>> valid_bool(12345)
+ Traceback (most recent call last):
+ ...
+ argparse.ArgumentTypeError: 12345
+
+ """
if isinstance(v, bool):
return v
from string_utils import to_bool
- return to_bool(v)
+ try:
+ return to_bool(v)
+ except Exception:
+ raise argparse.ArgumentTypeError(v)
def valid_ip(ip: str) -> str:
+ """
+ If the string is a valid IPv4 address, return it. Otherwise raise
+ an ArgumentTypeError.
+
+ >>> valid_ip("1.2.3.4")
+ '1.2.3.4'
+
+ >>> valid_ip("localhost")
+ Traceback (most recent call last):
+ ...
+ argparse.ArgumentTypeError: localhost is an invalid IP address
+
+ """
from string_utils import extract_ip_v4
s = extract_ip_v4(ip.strip())
if s is not None:
@@ -74,6 +115,22 @@ def valid_ip(ip: str) -> str:
def valid_mac(mac: str) -> str:
+ """
+ If the string is a valid MAC address, return it. Otherwise raise
+ an ArgumentTypeError.
+
+ >>> valid_mac('12:23:3A:4F:55:66')
+ '12:23:3A:4F:55:66'
+
+ >>> valid_mac('12-23-3A-4F-55-66')
+ '12-23-3A-4F-55-66'
+
+ >>> valid_mac('big')
+ Traceback (most recent call last):
+ ...
+ argparse.ArgumentTypeError: big is an invalid MAC address
+
+ """
from string_utils import extract_mac_address
s = extract_mac_address(mac)
if s is not None:
@@ -84,6 +141,22 @@ def valid_mac(mac: str) -> str:
def valid_percentage(num: str) -> float:
+ """
+ If the string is a valid percentage, return it. Otherwise raise
+ an ArgumentTypeError.
+
+ >>> valid_percentage("15%")
+ 15.0
+
+ >>> valid_percentage('40')
+ 40.0
+
+ >>> valid_percentage('115')
+ Traceback (most recent call last):
+ ...
+ argparse.ArgumentTypeError: 115 is an invalid percentage; expected 0 <= n <= 100.0
+
+ """
num = num.strip('%')
n = float(num)
if 0.0 <= n <= 100.0:
@@ -94,6 +167,19 @@ def valid_percentage(num: str) -> float:
def valid_filename(filename: str) -> str:
+ """
+ If the string is a valid filename, return it. Otherwise raise
+ an ArgumentTypeError.
+
+ >>> valid_filename('/tmp')
+ '/tmp'
+
+ >>> valid_filename('wfwefwefwefwefwefwefwefwef')
+ Traceback (most recent call last):
+ ...
+ argparse.ArgumentTypeError: wfwefwefwefwefwefwefwefwef was not found and is therefore invalid.
+
+ """
s = filename.strip()
if os.path.exists(s):
return s
@@ -103,6 +189,18 @@ def valid_filename(filename: str) -> str:
def valid_date(txt: str) -> datetime.date:
+ """If the string is a valid date, return it. Otherwise raise
+ an ArgumentTypeError.
+
+ >>> valid_date('6/5/2021')
+ datetime.date(2021, 6, 5)
+
+ # Note: dates like 'next wednesday' work fine, they are just
+ # hard to test for without knowing when the testcase will be
+ # executed...
+ >>> valid_date('next wednesday') # doctest: +ELLIPSIS
+ -ANYTHING-
+ """
from string_utils import to_date
date = to_date(txt)
if date is not None:
@@ -113,6 +211,18 @@ def valid_date(txt: str) -> datetime.date:
def valid_datetime(txt: str) -> datetime.datetime:
+ """If the string is a valid datetime, return it. Otherwise raise
+ an ArgumentTypeError.
+
+ >>> valid_datetime('6/5/2021 3:01:02')
+ datetime.datetime(2021, 6, 5, 3, 1, 2)
+
+ # Again, these types of expressions work fine but are
+ # difficult to test with doctests because the answer is
+ # relative to the time the doctest is executed.
+ >>> valid_datetime('next christmas at 4:15am') # doctest: +ELLIPSIS
+ -ANYTHING-
+ """
from string_utils import to_datetime
dt = to_datetime(txt)
if dt is not None:
@@ -120,3 +230,9 @@ def valid_datetime(txt: str) -> datetime.datetime:
msg = f'Cannot parse argument as datetime: {txt}'
logger.warning(msg)
raise argparse.ArgumentTypeError(msg)
+
+
+if __name__ == '__main__':
+ import doctest
+ doctest.ELLIPSIS_MARKER = '-ANYTHING-'
+ doctest.testmod()