Source code for code_aster.Cata.Language.Rules

# 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 wraps

from .SyntaxUtils import mixedcopy, remove_none


[docs]def work_on_copy(func): """Decorator to automatically copy the keywords dict argument and remove None (that means undefined) values before calling a function.""" @wraps(func) def wrapper(self, dict_orig): """wrapper""" dict_arg = mixedcopy(dict_orig) remove_none(dict_arg) return func(self, dict_arg) return wrapper
[docs]class Rule: """Abstract class for rules. Arguments: *args: list of keywords. """
[docs] def __init__(self, *args): """Initialization""" self.ruleArgs = args
[docs] def __repr__(self): """Simple representation""" return "%s( %r )" % (self.__class__, self.ruleArgs)
[docs] def check(self, dictSyntax): """Check the rule""" if not isinstance(dictSyntax, dict): raise TypeError("'dict' is expected")
[docs] def _firstExists(self, dictSyntax): """Filter that tells if the first keyword exists""" return self.ruleArgs[0] in dictSyntax
[docs] def _nbValues(self, dictSyntax): """Returns the number of defined (not None) values""" return sum([i in dictSyntax for i in self.ruleArgs if dictSyntax.get(i) is not None])
[docs]class RuleWithDefaults(Rule): """Abstract class for rules with default values. Arguments: *args: list of keywords. **kwargs: default values. """
[docs] def __init__(self, *args, **kwargs): """Initialization""" self.ruleArgs = args unknown = [key for key in kwargs if key not in args] if unknown: raise ValueError("Default values must be in arguments, not exist: {}".format(unknown)) self.ruleKwargs = kwargs
[docs]class AtLeastOne(RuleWithDefaults): """Check that at least one keyword from a list is defined. If no keyword from the list exist, default values may be inserted if provided in ``kwargs``. """
[docs] def check(self, dictSyntax): """Check the rule""" super().check(dictSyntax) if self._nbValues(dictSyntax) < 1: if self.ruleKwargs: dictSyntax.update(self.ruleKwargs) else: raise ValueError( "At least one argument of {} must be defined".format(self.ruleArgs) )
[docs]class ExactlyOne(RuleWithDefaults): """Check that exactly one keyword from a list is defined. If no keyword from the list exist, a default value may be inserted if provided in ``kwargs``. """
[docs] def check(self, dictSyntax): """Check the rule""" super().check(dictSyntax) if self._nbValues(dictSyntax) == 0 and self.ruleKwargs: dictSyntax.update(self.ruleKwargs) if self._nbValues(dictSyntax) != 1: raise ValueError("Exactly one argument of {} is required".format(self.ruleArgs))
[docs]class AtMostOne(Rule): """Check that at most one keyword from a list is defined."""
[docs] @work_on_copy def check(self, dictSyntax): """Check the rule""" super().check(dictSyntax) if self._nbValues(dictSyntax) > 1: raise ValueError("At most one argument of {} can be defined".format(self.ruleArgs))
[docs]class IfFirstAllPresent(Rule): """Check that if a keyword is defined all others from the list are defined."""
[docs] @work_on_copy def check(self, dictSyntax): """Check the rule""" super().check(dictSyntax) if self._firstExists(dictSyntax) and self._nbValues(dictSyntax) != len(self.ruleArgs): raise ValueError("{} must be all defined".format(self.ruleArgs[1:]))
[docs]class OnlyFirstPresent(Rule): """Check that if a keyword is defined no of the others from the list is defined."""
[docs] @work_on_copy def check(self, dictSyntax): """Check the rule""" super().check(dictSyntax) if self._firstExists(dictSyntax) and self._nbValues(dictSyntax) != 1: raise ValueError("{} must be all undefined".format(self.ruleArgs[1:]))
[docs]class AllTogether(Rule): """Check that if all the keywords from the list are defined or all undefined."""
[docs] @work_on_copy def check(self, dictSyntax): """Check the rule""" super().check(dictSyntax) if self._nbValues(dictSyntax) not in (0, len(self.ruleArgs)): raise ValueError("{} must be all defined or all undefined".format(self.ruleArgs))
[docs]class NotEmpty(Rule): """Check that at least one keyword is provided."""
[docs] @work_on_copy def check(self, dictSyntax): """Check the rule""" super().check(dictSyntax) if not dictSyntax: raise ValueError("At least one argument must be defined")