Report overall runtime in periodic status dumps.
[python_utils.git] / argparse_utils.py
index 0ee2be9f8017093caeff732962ad9b4d10a993e7..1c61b2460650c11872cbaaabf4e7f5a689be746c 100644 (file)
@@ -6,6 +6,9 @@ import logging
 import os
 from typing import Any
 
+from overrides import overrides
+
+
 # This module is commonly used by others in here and should avoid
 # taking any unnecessary dependencies back on them.
 
@@ -47,6 +50,7 @@ class ActionNoYes(argparse.Action):
             help=help
         )
 
+    @overrides
     def __call__(self, parser, namespace, values, option_strings=None):
         if (
                 option_strings.startswith('--no-') or
@@ -110,7 +114,7 @@ def valid_ip(ip: str) -> str:
     if s is not None:
         return s
     msg = f"{ip} is an invalid IP address"
-    logger.warning(msg)
+    logger.error(msg)
     raise argparse.ArgumentTypeError(msg)
 
 
@@ -136,7 +140,7 @@ def valid_mac(mac: str) -> str:
     if s is not None:
         return s
     msg = f"{mac} is an invalid MAC address"
-    logger.warning(msg)
+    logger.error(msg)
     raise argparse.ArgumentTypeError(msg)
 
 
@@ -162,7 +166,7 @@ def valid_percentage(num: str) -> float:
     if 0.0 <= n <= 100.0:
         return n
     msg = f"{num} is an invalid percentage; expected 0 <= n <= 100.0"
-    logger.warning(msg)
+    logger.error(msg)
     raise argparse.ArgumentTypeError(msg)
 
 
@@ -184,7 +188,7 @@ def valid_filename(filename: str) -> str:
     if os.path.exists(s):
         return s
     msg = f"{filename} was not found and is therefore invalid."
-    logger.warning(msg)
+    logger.error(msg)
     raise argparse.ArgumentTypeError(msg)
 
 
@@ -206,7 +210,7 @@ def valid_date(txt: str) -> datetime.date:
     if date is not None:
         return date
     msg = f'Cannot parse argument as a date: {txt}'
-    logger.warning(msg)
+    logger.error(msg)
     raise argparse.ArgumentTypeError(msg)
 
 
@@ -228,10 +232,32 @@ def valid_datetime(txt: str) -> datetime.datetime:
     if dt is not None:
         return dt
     msg = f'Cannot parse argument as datetime: {txt}'
-    logger.warning(msg)
+    logger.error(msg)
     raise argparse.ArgumentTypeError(msg)
 
 
+def valid_duration(txt: str) -> datetime.timedelta:
+    """If the string is a valid time duration, return a
+    datetime.timedelta representing the period of time.  Otherwise
+    maybe raise an ArgumentTypeError or potentially just treat the
+    time window as zero in length.
+
+    >>> valid_duration('3m')
+    datetime.timedelta(seconds=180)
+
+    >>> valid_duration('your mom')
+    datetime.timedelta(0)
+
+    """
+    from datetime_utils import parse_duration
+    try:
+        secs = parse_duration(txt)
+    except Exception as e:
+        raise argparse.ArgumentTypeError(e)
+    finally:
+        return datetime.timedelta(seconds=secs)
+
+
 if __name__ == '__main__':
     import doctest
     doctest.ELLIPSIS_MARKER = '-ANYTHING-'