Source code for json_configparser.bounds

"""
The Bounds module implements the Bounds class, which can be used to represent bounds for certain arguments.
"""

from typing import Union


[docs]class Bounds(object): """ Represents the Bounds of an argument. A Bounds instance is defined by lower and upper bounds, and flags indicating if the bounds are inclusive or exclusive. The supported argument types are integer, float, or lists/dictionaries of those types. """
[docs] def __init__(self, arg_name: str, lower_bound: Union[int, float, None] = None, lower_inclusive: bool = True, upper_bound: Union[int, float, None] = None, upper_inclusive: bool = True): """ At least one bound must be provided. :param arg_name: The name of the argument. :param lower_bound: The lower bound value. :param lower_inclusive: Flag indicating if the lower bound is inclusive. :param upper_bound: The upper bound value. :param upper_inclusive: Flag indicating if the lower bound is inclusive. """ self._validate_init_args(arg_name, lower_bound, lower_inclusive, upper_bound, upper_inclusive) self.arg_name = arg_name self.lower_bound = lower_bound self.lower_inclusive = lower_inclusive self.upper_bound = upper_bound self.upper_inclusive = upper_inclusive
@staticmethod def _validate_init_args(arg_name: str, lower_bound: Union[int, float, None], lower_inclusive: bool, upper_bound: Union[int, float, None], upper_inclusive: bool): if not isinstance(arg_name, str): raise TypeError("The arg_name parameter should be a string " "(arg_name: {})".format(arg_name)) if len(arg_name.strip()) == 0: raise ValueError("The arg_name parameter should be a non-empty string " "(arg_name: {})".format(arg_name)) if lower_bound is not None and type(lower_bound) not in [int, float]: raise TypeError("The lower_bound parameter should be an integer, float, or None " "(lower_bound: {}".format(lower_bound)) if upper_bound is not None and type(upper_bound) not in [int, float]: raise TypeError("The upper_bound parameter should be an integer, float, or None " "(upper_bound: {}".format(upper_bound)) if not isinstance(lower_inclusive, bool): raise TypeError("The lower_inclusive parameter should be a boolean value " "(lower_inclusive: {})".format(lower_inclusive)) if not isinstance(upper_inclusive, bool): raise TypeError("The upper_inclusive parameter should be a boolean value " "(upper_inclusive: {})".format(upper_inclusive)) if lower_bound is not None and upper_bound is not None and lower_bound >= upper_bound: raise ValueError("The lower_bound parameter should be less than the upper_bound parameter " "(lower_bound: {}, upper_bound: {})".format(lower_bound, upper_bound))
[docs] def validate_value(self, arg_value: Union[int, float]): """ Validates a value against the provided bounds. :param arg_value: The value of the argument to validate. :raises ValueError: If the value is out of bounds. """ if self.lower_bound is not None: if self.lower_inclusive and arg_value < self.lower_bound: raise ValueError("The {name} argument should be greater than or " "equal to {lbound} ({name}: {value})".format(name=self.arg_name, lbound=self.lower_bound, value=arg_value)) if not self.lower_inclusive and arg_value <= self.lower_bound: raise ValueError("The {name} argument should be greater than " "{lbound} ({name}: {value})".format(name=self.arg_name, lbound=self.lower_bound, value=arg_value)) if self.upper_bound is not None: if self.upper_inclusive and arg_value > self.upper_bound: raise ValueError("The {name} argument should be less than or " "equal to {ubound} ({name}: {value})".format(name=self.arg_name, ubound=self.upper_bound, value=arg_value)) if not self.upper_inclusive and arg_value >= self.upper_bound: raise ValueError("The {name} argument should be less than " "{ubound} ({name}: {value})".format(name=self.arg_name, ubound=self.upper_bound, value=arg_value))
def __str__(self): start = "[" if self.lower_inclusive else "]" end = "]" if self.upper_inclusive else "[" return start + str(self.lower_bound) + ", " + str(self.upper_bound) + end