Source code for code_aster.Cata.Language.Validators

# coding=utf-8
# --------------------------------------------------------------------
# Copyright (C) 1991 - 2026 - EDF - www.code-aster.org
# This file is part of code_aster.
#
# code_aster is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# code_aster is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with code_aster.  If not, see <http://www.gnu.org/licenses/>.
# --------------------------------------------------------------------


from functools import partial

from .SyntaxUtils import force_list


[docs]class Validator: """Abstract class for validators."""
[docs] def __init__(self, *args, **kwargs): """Initialization""" self.args = args
[docs] def __repr__(self): """Simple representation""" return "%s %r " % (self.__class__.__name__, self.args)
[docs] def check(self, values): """Check values""" raise NotImplementedError("must be defined in a subclass")
[docs]class NoRepeat(Validator): """Check that all values are different."""
[docs] def check(self, values): """Check values""" values = force_list(values) if len(set(values)) != len(values): raise ValueError("All the values must be different: " "{0!r}".format(values))
[docs]class AtMostOneStartsWith(Validator): """Check that there is at most one value that starts with a given keyword. Usage: AtMostOneStartsWith("ELAS"): Check that keyword ELAS is used at most once. """
[docs] def __init__(self, *args, **kwargs): super().__init__(*args) assert len(args) == 1, "Exactly one argument is required for AtMostOneStartsWith."
[docs] def check(self, values): """Check values""" values = force_list(values) occurences = list(set(i for i in values if i.startswith(self.args[0]))) if len(occurences) > 1: raise ValueError( "At most one occurrence of '{0}' is accepted. " "Found {1}: {2}".format(self.args[0], len(occurences), occurences) )
[docs]class LongStr(Validator): """Check that the length of string."""
[docs] def __init__(self, *args, **kwargs): super().__init__(*args) assert len(args) == 2, "Exactly two arguments required for LongStr." assert (type(args[0]), type(args[1])) == (int, int), "LongStr arguments must be 'int'"
[docs] def check(self, values): """Check values""" values = force_list(values) for string in values: if not (self.args[0] <= len(string) <= self.args[1]): raise ValueError( "String length must be in [{0[0]}, {0[1]}]: " "length of '{1}' is {2}".format(self.args, string, len(string)) )
[docs]class AndVal(Validator): """Check that all validators are checked."""
[docs] def __init__(self, *args, **kwargs): if type(args) in (list, tuple) and len(args) == 1: args = args[0] super().__init__(*args) for i in self.args: assert isinstance(i, Validator), "Arguments of AndVal must be Validator objects."
[docs] def check(self, values): """Check values""" values = force_list(values) for i in self.args: i.check(values)
[docs]class OrVal(Validator): """Check that at least one of the validators in argument is checked."""
[docs] def __init__(self, *args, **kwargs): if type(args) in (list, tuple) and len(args) == 1: args = args[0] super().__init__(*args) for i in self.args: assert isinstance(i, Validator), "Arguments of OrVal must be Validator objects."
[docs] def check(self, values): """Check values""" values = force_list(values) ok = False err = [] for i in self.args: try: i.check(values) except ValueError as exc: err.append(str(exc)) else: ok = True if not ok: raise ValueError("Validator 'OR' is invalid: {0}".format(err))
[docs]def ordlist_predicate(a, b, reverse): """Predicate to check order of elements in a list.""" if None not in (a, b): if not reverse: return a <= b else: return a >= b return True
[docs]class OrdList(Validator): """Check that the values are ordered. Usage: OrdList(): Check that order of values is increasing. OrdList(reverse=True): Check that order is decreasing. Old usage: OrdList('croissant') """
[docs] def __init__(self, *args, **kwargs): super().__init__() assert len(args) <= 1, "At most one argument is required for OrdList." reverse = kwargs.get("reverse", False) if len(args) == 1 and args[0] != "croissant": reverse = True self._predicate = partial(ordlist_predicate, reverse=reverse)
[docs] def check(self, values): """Check values""" values = list(force_list(values)) if not values: return previous = values.pop(0) while len(values) > 0: current = values.pop(0) if not self._predicate(previous, current): raise ValueError( "The values are not ordered as " "expected: {0} followed by {1}".format(previous, current) ) previous = current
[docs]class Together(Validator): """Check that if one of the values is used, all must be defined. Usage: Together([expected values]) """
[docs] def __init__(self, *args, **kwargs): super().__init__(*args) assert len(args) == 1, "Exactly one argument is required for Together."
[docs] def check(self, values): """Check values""" missing = set(self.args[0]).difference(force_list(values)) if missing and len(missing) != len(self.args[0]): raise ValueError("Missing values: {0}".format(_lstr(missing)))
[docs]class Absent(Validator): """Check that if none of the values is defined. Usage: Absent([unexpected values]) """
[docs] def __init__(self, *args, **kwargs): super().__init__(*args) assert len(args) == 1, "Exactly one argument is required for Absent."
[docs] def check(self, values): """Check values""" invalid = set(self.args[0]).intersection(force_list(values)) if invalid: raise ValueError("Unexpected values: {0}".format(_lstr(invalid)))
[docs]class Compulsory(Validator): """Check that all the values are defined. Usage: Compulsory([expected values]) """
[docs] def __init__(self, *args, **kwargs): super().__init__(*args) assert len(args) == 1, "Exactly one argument is required for Compulsory."
[docs] def check(self, values): """Check values""" missing = set(self.args[0]).difference(force_list(values)) if missing: raise ValueError( "Required values: {0}, missing {1}".format(_lstr(*self.args), _lstr(missing)) )
[docs]class NotEqualTo(Validator): """Check that the value is not equal to something. Usage: NotEqualTo(value) """
[docs] def __init__(self, *args, **kwargs): super().__init__(*args) assert len(args) == 1, "Exactly one argument is required " "for NotEqualTo."
[docs] def check(self, values): """Check values""" ref = self.args[0] values = force_list(values) for val in values: if val == ref: raise ValueError("Unauthorized value: {0[0]}".format(self.args))
def _lstr(list_): return [str(i) for i in list_]