Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# y_str += "\n" + pad("description: " + pad(self.description, 1), 1)
if default_str:
y_str += "\n" + pad("default: " + pad(default_str, 0), 1)
text = pad(y_str, indents)
return text.split("\n") if str_list else text
def dont_typecheck_default(self) -> 'Type':
"""
Disable type checking the default value.
:return: self
"""
self.typecheck_default = False
return self
class Exact(Type):
"""
Checks for value equivalence.
"""
def __init__(self, exp_value):
"""
Creates an Exact object.
:param exp_value: value to check for
"""
super().__init__()
self.exp_value = exp_value
""" Expected value """
def _instancecheck_impl(self, value, info: Info = NoInfo()) -> InfoMsg:
"""
"""
if isinstance(other, str) or isinstance(other, Description):
self.description = str(other)
return self
if isinstance(other, Default):
self.default = other
if self.typecheck_default:
typecheck(self.default.default, self)
return self
if isinstance(other, CompletionHint):
for shell in other.hints:
self.completion_hints[shell] = other.hints[shell]
return self
if isinstance(other, Constraint):
return Constraint(other.constraint, self, other.description)
if isinstance(other, Type):
raise ConstraintError("{} mustn't be an instance of a Type subclass".format(other))
return Constraint(other, self)
def __str__(self) -> str:
descr = self.description
if self.description is None:
#if isinstance(self.constraint, type(fn._)):
# descr = str(self.constraint)
#else:
descr = ""
return "{}:{}".format(self.constrained_type, descr)
def string_representation(self, indents: int = 0, indentation: int = 4, str_list: bool = False, defaults = None) -> t.Union[str, t.List[str]]:
l = self.constrained_type.string_representation(indents, indentation, str_list=True, defaults=defaults) \
+ [" " * indents * indentation + "# with constrain: " + self.description]
return l if str_list else "\n".join(l)
class NonErrorConstraint(Type):
"""
Checks the passed value by an user defined constraint that fails if it raises an error.
"""
def __init__(self, constraint: t.Callable[[t.Any], t.Any], error_cls: type, constrained_type: Type = Any(),
description: str = None):
"""
Creates a new instance
:param constraint: function that doesn't raise an error if the user defined constraint is satisfied
:param error_cls: class of the errors the constraint method raises
:param constrained_type: Type that the constraint is applied on
:param description: short description of the constraint (e.g. ">0")
:raises: ConstraintError if constrained_type isn't a (typechecker) Types
"""
super().__init__()
class NonExistent(Type):
"""
Checks a key of a dictionary for existence if its associated value has this type.
"""
def _instancecheck_impl(self, value, info: Info) -> InfoMsg:
return info.errormsg_cond(type(value) == _NonExistentVal, self, "[value]")
def __str__(self) -> str:
return "non existent"
def _eq_impl(self, other: 'NonExistent') -> bool:
return True
class Dict(Type):
"""
Checks for the value to be a dictionary with expected keys and values satisfy given type constraints.
"""
def __init__(self, data: t.Dict[t.Any, Type] = None, unknown_keys: bool = False, key_type: Type = Any(),
value_type: Type = Any()):
"""
Creates a new instance.
:param data: dictionary with the expected keys and the expected types of the associated values
:param unknown_keys: accept unknown keys in value
:param key_type: expected Type of all dictionary keys
:param value_type: expected Type of all dictionary values
:raises: ConstraintError if one of the given types isn't a (typechecker) Types
"""
super().__init__()
if value == "true" :
return True
elif value == "false":
return False
elif value == "none":
return None
self.fail("{} is no valid bool or 'none'".format(value), param, ctx)
def __str__(self) -> str:
return "BoolOrNone()"
def _eq_impl(self, other: 'BoolOrNone') -> bool:
return True
class Bool(Type, click.ParamType):
"""
Like Bool but with a third value none that declares that the value no boolean value.
It has None as its default value (by default).
"""
name = "bool" # type: str
""" click.ParamType name, that makes this class usable as a click type """
def __init__(self):
super().__init__()
self.completion_hints = { # type: t.Dict[str, t.Any]
"zsh": "(true, false)",
"fish": {
"hint": ["true", "false"]
}
}
if not res:
return res
try:
self.constraint(value)
except self.error_cls as err:
return info.errormsg(self, value, msg=str(err))
return info.wrap(True)
def __str__(self) -> str:
descr = self.description
if self.description is None:
descr = ""
return "{}:{}".format(self.constrained_type, descr)
class List(Type):
"""
Checks for the value to be a list with elements of a given type.
"""
def __init__(self, elem_type: Type = Any()):
"""
Creates a new instance.
:param elem_type: type of the list elements
:raises: ConstraintError if elem_type isn't a (typechecker) Types
"""
super().__init__()
self._validate_types(elem_type)
self.elem_type = elem_type # type: Type
""" Expected type of the list elements """
return self.default.default if super().has_default() else [self.elem_type.get_default()]
def get_default_yaml(self, indents: int = 0, indentation: int = 4, str_list: bool = False, defaults = None) -> t.Union[str, t.List[str]]:
if defaults is None:
defaults = self.get_default()
else:
typecheck(defaults, self)
ind = " " * indents * indentation
ret_strs = [" " * indents * indentation + "[]"]
if len(defaults) > 0:
l = self.elem_type.get_default_yaml(str_list=True, indentation=indentation, defaults=defaults[0])
ret_strs = [ind + " " * (indentation - 3) + " - " + l[0]] + [ind + (" " * indentation) + s for s in l]
return ret_strs if str_list else "\n".join(ret_strs)
class ListOrTuple(Type):
"""
Checks for the value to be a list or tuple with elements of a given type.
"""
def __init__(self, elem_type: Type = Any()):
"""
Creates an instance.
:param elem_type: type of the list or tuple elements
:raises: ConstraintError if elem_type isn't a (typechecker) Types
"""
super().__init__()
self._validate_types(elem_type)
self.elem_type = elem_type # type: Type
""" Expected type of the list or tuple elements """
class _NonExistentVal(object):
"""
Helper class for NonExistent Type.
"""
def __str__(self) -> str:
return ""
def __repr__(self) -> str:
return self.__str__()
_non_existent_val = _NonExistentVal()
class NonExistent(Type):
"""
Checks a key of a dictionary for existence if its associated value has this type.
"""
def _instancecheck_impl(self, value, info: Info) -> InfoMsg:
return info.errormsg_cond(type(value) == _NonExistentVal, self, "[value]")
def __str__(self) -> str:
return "non existent"
def _eq_impl(self, other: 'NonExistent') -> bool:
return True
class Dict(Type):
"""
if isinstance(other, ExactEither):
other.exp_values.insert(0, self.exp_value)
return other
if isinstance(other, Exact):
return ExactEither(self.exp_value, other.exp_value)
return Either(self, other)
def E(exp_value) -> Exact:
"""
Alias for Exact.
"""
return Exact(exp_value)
class Either(Type):
"""
Checks for the value to be of one of several types.
"""
def __init__(self, *types: tuple):
"""
Creates an Either instance.
:param types: list of types (or SpecialType subclasses)
:raises: ConstraintError if some of the contraints aren't (typechecker) Types
"""
super().__init__()
self._validate_types(*types)
self.types = list(types)
""" Possible types """
}
}
""" Completion hints for supported shells for this type instance """
def _instancecheck_impl(self, value, info: Info) -> InfoMsg:
res = ExactEither(True, False).__instancecheck__(value, info)
return info.errormsg_cond(bool(res), self, str(res))
def __str__(self) -> str:
return "Bool()"
def _eq_impl(self, other: 'Bool') -> bool:
return True
class ValidTimeSpan(Type, click.ParamType):
"""
A string that is parseable as timespan by pytimeparse.
E.g. "32m" or "2h 32m".
"""
name = "valid_timespan" # type: str
""" click.ParamType name, that makes this class usable as a click type """
def __init__(self):
super().__init__()
def _instancecheck_impl(self, value, info: Info) -> InfoMsg:
res = Str().__instancecheck__(value, info)
wrong = not bool(res) or parse_timespan(value) == None
if wrong:
return info.errormsg(self, value)