can add extra annotators

This commit is contained in:
Emmanuel Garette 2021-04-12 15:04:38 +02:00
parent b7cedd85fb
commit f4471c4875
14 changed files with 114 additions and 82 deletions

View File

@ -24,34 +24,44 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
""" """
from .group import GroupAnnotator from .variable import CONVERT_OPTION
from .service import ServiceAnnotator import importlib.resources
from .variable import VariableAnnotator, CONVERT_OPTION from ..utils import load_modules
from .check import CheckAnnotator
from .value import ValueAnnotator
from .condition import ConditionAnnotator ANNOTATORS = None
from .fill import FillAnnotator
from .family import FamilyAnnotator
from .property import PropertyAnnotator def get_level(module):
return module.level
def get_annotators(annotators, module_name):
annotators[module_name] = []
for pathobj in importlib.resources.files(module_name).iterdir():
path = str(pathobj)
if not path.endswith('__') and not path.endswith('__.py'):
module = load_modules(path)
if 'Annotator' in dir(module):
annotators[module_name].append(module.Annotator)
class SpaceAnnotator: # pylint: disable=R0903 class SpaceAnnotator: # pylint: disable=R0903
"""Transformations applied on a object instance """Transformations applied on a object instance
""" """
def __init__(self, objectspace, eosfunc_file): def __init__(self, objectspace, eosfunc_file):
self.objectspace = objectspace global ANNOTATORS
GroupAnnotator(objectspace) if ANNOTATORS is None:
ServiceAnnotator(objectspace) ANNOTATORS = {}
VariableAnnotator(objectspace) get_annotators(ANNOTATORS, 'rougail.annotator')
CheckAnnotator(objectspace, for extra_annotator in objectspace.rougailconfig['extra_annotators']:
eosfunc_file, get_annotators(ANNOTATORS, extra_annotator)
) annotators = ANNOTATORS['rougail.annotator'].copy()
ConditionAnnotator(objectspace) for extra_annotator in objectspace.rougailconfig['extra_annotators']:
FillAnnotator(objectspace, annotators.extend(ANNOTATORS[extra_annotator])
eosfunc_file, annotators = sorted(annotators, key=get_level)
) for annotator in annotators:
ValueAnnotator(objectspace) annotator(objectspace, eosfunc_file)
FamilyAnnotator(objectspace)
PropertyAnnotator(objectspace)
__all__ = ('SpaceAnnotator', 'CONVERT_OPTION') __all__ = ('SpaceAnnotator', 'CONVERT_OPTION')

View File

@ -26,21 +26,23 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
""" """
from typing import List, Any from typing import List, Any
from .target import TargetAnnotator from rougail.annotator.target import TargetAnnotator
from .param import ParamAnnotator from rougail.annotator.param import ParamAnnotator
from ..utils import load_modules from rougail.utils import load_modules
from ..i18n import _ from rougail.i18n import _
from ..error import DictConsistencyError, display_xmlfiles from rougail.error import DictConsistencyError, display_xmlfiles
INTERNAL_FUNCTIONS = ['valid_enum', 'valid_in_network', 'valid_differ', 'valid_entier'] INTERNAL_FUNCTIONS = ['valid_enum', 'valid_in_network', 'valid_differ', 'valid_entier']
class CheckAnnotator(TargetAnnotator, ParamAnnotator): class Annotator(TargetAnnotator, ParamAnnotator):
"""Annotate check """Annotate check
""" """
level = 40
def __init__(self, def __init__(self,
objectspace, objectspace,
eosfunc_file, eosfunc_file,
*args,
): ):
if not hasattr(objectspace.space, 'constraints') or \ if not hasattr(objectspace.space, 'constraints') or \
not hasattr(objectspace.space.constraints, 'check'): not hasattr(objectspace.space.constraints, 'check'):

View File

@ -27,19 +27,21 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
from typing import List from typing import List
from ..i18n import _ from rougail.i18n import _
from ..error import DictConsistencyError from rougail.error import DictConsistencyError
from .target import TargetAnnotator from rougail.annotator.target import TargetAnnotator
from .param import ParamAnnotator from rougail.annotator.param import ParamAnnotator
from .variable import Walk from rougail.annotator.variable import Walk
class ConditionAnnotator(TargetAnnotator, ParamAnnotator, Walk): class Annotator(TargetAnnotator, ParamAnnotator, Walk):
"""Annotate condition """Annotate condition
""" """
level = 50
def __init__(self, def __init__(self,
objectspace, objectspace,
*args,
): ):
self.objectspace = objectspace self.objectspace = objectspace
self.force_service_value = {} self.force_service_value = {}

View File

@ -24,9 +24,9 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
""" """
from ..i18n import _ from rougail.i18n import _
from ..error import DictConsistencyError from rougail.error import DictConsistencyError
from .variable import Walk from rougail.annotator.variable import Walk
class Mode: # pylint: disable=R0903 class Mode: # pylint: disable=R0903
@ -43,11 +43,13 @@ class Mode: # pylint: disable=R0903
return other.level < self.level return other.level < self.level
class FamilyAnnotator(Walk): class Annotator(Walk):
"""Annotate family """Annotate family
""" """
level = 80
def __init__(self, def __init__(self,
objectspace, objectspace,
*args,
): ):
self.objectspace = objectspace self.objectspace = objectspace
if not hasattr(self.objectspace.space, 'variables'): if not hasattr(self.objectspace.space, 'variables'):
@ -74,6 +76,7 @@ class FamilyAnnotator(Walk):
def remove_empty_families(self) -> None: def remove_empty_families(self) -> None:
"""Remove all families without any variable """Remove all families without any variable
""" """
#FIXME pas sous family
for families in self.objectspace.space.variables.values(): for families in self.objectspace.space.variables.values():
removed_families = [] removed_families = []
for family_name, family in families.variable.items(): for family_name, family in families.variable.items():

View File

@ -24,28 +24,30 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
""" """
from ..utils import load_modules from rougail.utils import load_modules
from ..i18n import _ from rougail.i18n import _
from ..error import DictConsistencyError from rougail.error import DictConsistencyError
from .target import TargetAnnotator from rougail.annotator.target import TargetAnnotator
from .param import ParamAnnotator from rougail.annotator.param import ParamAnnotator
CALC_MULTI = ('calc_value', 'calc_list', 'get_range', 'calc_val_first_value', 'unbound_filename') CALC_MULTI = ('calc_value', 'calc_list', 'get_range', 'calc_val_first_value', 'unbound_filename')
class FillAnnotator(TargetAnnotator, ParamAnnotator): class Annotator(TargetAnnotator, ParamAnnotator):
"""Fill annotator """Fill annotator
""" """
level = 60
def __init__(self, def __init__(self,
objectspace, objectspace,
eosfunc_file, eosfunc_file,
*args,
): ):
self.objectspace = objectspace
if not hasattr(objectspace.space, 'constraints') or \ if not hasattr(objectspace.space, 'constraints') or \
not hasattr(self.objectspace.space.constraints, 'fill'): not hasattr(objectspace.space.constraints, 'fill'):
return return
self.objectspace = objectspace
self.functions = dir(load_modules(eosfunc_file)) self.functions = dir(load_modules(eosfunc_file))
self.functions.extend(self.objectspace.rougailconfig['internal_functions']) self.functions.extend(self.objectspace.rougailconfig['internal_functions'])
self.target_is_uniq = True self.target_is_uniq = True
@ -68,12 +70,11 @@ class FillAnnotator(TargetAnnotator, ParamAnnotator):
"""valid and manage <fill> """valid and manage <fill>
""" """
for fill in self.objectspace.space.constraints.fill: for fill in self.objectspace.space.constraints.fill:
# test if the function exists
if fill.name not in self.functions:
msg = _(f'cannot find fill function "{fill.name}"')
raise DictConsistencyError(msg, 25, fill.xmlfiles)
for target in fill.target: for target in fill.target:
# test if the function exists
if fill.name not in self.functions:
msg = _(f'cannot find fill function "{fill.name}"')
raise DictConsistencyError(msg, 25, fill.xmlfiles)
# create an object value # create an object value
value = self.objectspace.value(fill.xmlfiles) value = self.objectspace.value(fill.xmlfiles)
value.type = 'calculation' value.type = 'calculation'
@ -87,7 +88,6 @@ class FillAnnotator(TargetAnnotator, ParamAnnotator):
target.name.default = value target.name.default = value
else: else:
target.name.value = [value] target.name.value = [value]
# manage params # manage params
if hasattr(fill, 'param') and fill.param: if hasattr(fill, 'param') and fill.param:
value.param = fill.param value.param = fill.param

View File

@ -24,16 +24,18 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
""" """
from ..i18n import _ from rougail.i18n import _
from ..error import DictConsistencyError from rougail.error import DictConsistencyError
from ..utils import normalize_family from rougail.utils import normalize_family
class GroupAnnotator: class Annotator:
"""Annotate group """Annotate group
""" """
level = 10
def __init__(self, def __init__(self,
objectspace, objectspace,
*args,
): ):
self.objectspace = objectspace self.objectspace = objectspace
if not hasattr(self.objectspace.space, 'constraints') or \ if not hasattr(self.objectspace.space, 'constraints') or \

View File

@ -29,10 +29,10 @@ try:
except ModuleNotFoundError: except ModuleNotFoundError:
import tiramisu import tiramisu
from .variable import CONVERT_OPTION from rougail.annotator.variable import CONVERT_OPTION
from ..i18n import _ from rougail.i18n import _
from ..error import DictConsistencyError from rougail.error import DictConsistencyError
class ParamAnnotator: class ParamAnnotator:

View File

@ -24,19 +24,23 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
""" """
from ..i18n import _ from rougail.i18n import _
from ..error import DictConsistencyError from rougail.error import DictConsistencyError
from .variable import Walk from rougail.annotator.variable import Walk
PROPERTIES = ('hidden', 'frozen', 'force_default_on_freeze', PROPERTIES = ('hidden', 'frozen', 'force_default_on_freeze',
'force_store_value', 'disabled', 'mandatory') 'force_store_value', 'disabled', 'mandatory')
class PropertyAnnotator(Walk): class Annotator(Walk):
"""Annotate properties """Annotate properties
""" """
def __init__(self, objectspace): level = 90
def __init__(self,
objectspace,
*args
) -> None:
self.objectspace = objectspace self.objectspace = objectspace
if hasattr(self.objectspace.space, 'services'): if hasattr(self.objectspace.space, 'services'):
self.convert_services() self.convert_services()

View File

@ -27,9 +27,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
from os.path import basename from os.path import basename
from typing import Tuple from typing import Tuple
from ..i18n import _ from rougail.i18n import _
from ..utils import normalize_family from rougail.utils import normalize_family
from ..error import DictConsistencyError from rougail.error import DictConsistencyError
# a object's attribute has some annotations # a object's attribute has some annotations
# that shall not be present in the exported (flatened) XML # that shall not be present in the exported (flatened) XML
ERASED_ATTRIBUTES = ('redefine', 'exists', 'optional', 'remove_check', 'namespace', ERASED_ATTRIBUTES = ('redefine', 'exists', 'optional', 'remove_check', 'namespace',
@ -39,7 +39,7 @@ ERASED_ATTRIBUTES = ('redefine', 'exists', 'optional', 'remove_check', 'namespac
ALLOW_ATTRIBUT_NOT_MANAGE = ['file'] ALLOW_ATTRIBUT_NOT_MANAGE = ['file']
class ServiceAnnotator: class Annotator:
"""Manage service's object """Manage service's object
for example:: for example::
<services> <services>
@ -49,7 +49,11 @@ class ServiceAnnotator:
</service> </service>
</services> </services>
""" """
def __init__(self, objectspace): level = 20
def __init__(self,
objectspace,
*args,
) -> None:
self.objectspace = objectspace self.objectspace = objectspace
self.uniq_overrides = [] self.uniq_overrides = []
if 'network_type' not in self.objectspace.types: if 'network_type' not in self.objectspace.types:

View File

@ -24,8 +24,8 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
""" """
from ..i18n import _ from rougail.i18n import _
from ..error import DictConsistencyError from rougail.error import DictConsistencyError
class TargetAnnotator: class TargetAnnotator:

View File

@ -24,16 +24,18 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
""" """
from .variable import Walk from rougail.annotator.variable import Walk
from ..i18n import _ from rougail.i18n import _
from ..error import DictConsistencyError from rougail.error import DictConsistencyError
class ValueAnnotator(Walk): # pylint: disable=R0903 class Annotator(Walk): # pylint: disable=R0903
"""Annotate value """Annotate value
""" """
level = 70
def __init__(self, def __init__(self,
objectspace, objectspace,
*args,
) -> None: ) -> None:
if not hasattr(objectspace.space, 'variables'): if not hasattr(objectspace.space, 'variables'):
return return

View File

@ -25,9 +25,9 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
""" """
from ..i18n import _ from rougail.i18n import _
from ..error import DictConsistencyError from rougail.error import DictConsistencyError
from ..objspace import convert_boolean from rougail.objspace import convert_boolean
CONVERT_OPTION = {'number': dict(opttype="IntOption", func=int), CONVERT_OPTION = {'number': dict(opttype="IntOption", func=int),
@ -111,11 +111,13 @@ class Walk:
yield from self._get_families(fam) yield from self._get_families(fam)
class VariableAnnotator(Walk): # pylint: disable=R0903 class Annotator(Walk): # pylint: disable=R0903
"""Annotate variable """Annotate variable
""" """
level = 30
def __init__(self, def __init__(self,
objectspace, objectspace,
*args,
): ):
if not hasattr(objectspace.space, 'variables'): if not hasattr(objectspace.space, 'variables'):
return return

View File

@ -43,6 +43,7 @@ RougailConfig = {'dictionaries_dir': [join(ROUGAILROOT, 'dictionaries')],
'variable_namespace': 'rougail', 'variable_namespace': 'rougail',
'auto_freeze_variable': 'server_deployed', 'auto_freeze_variable': 'server_deployed',
'internal_functions': [], 'internal_functions': [],
'extra_annotators': [],
'modes_level': ['basic', 'normal', 'expert'], 'modes_level': ['basic', 'normal', 'expert'],
'default_family_mode': 'basic', 'default_family_mode': 'basic',
'default_variable_mode': 'normal', 'default_variable_mode': 'normal',

View File

@ -83,7 +83,7 @@
<!ATTLIST family mode CDATA #IMPLIED> <!ATTLIST family mode CDATA #IMPLIED>
<!ATTLIST family hidden (True|False) "False"> <!ATTLIST family hidden (True|False) "False">
<!ATTLIST family dynamic CDATA #IMPLIED> <!ATTLIST family dynamic CDATA #IMPLIED>
<!ATTLIST family public CDATA #IMPLIED> <!ATTLIST family provider CDATA #IMPLIED>
<!ELEMENT variable (value*)> <!ELEMENT variable (value*)>
<!ATTLIST variable name CDATA #REQUIRED> <!ATTLIST variable name CDATA #REQUIRED>
@ -102,7 +102,7 @@
<!ATTLIST variable remove_check (True|False) "False"> <!ATTLIST variable remove_check (True|False) "False">
<!ATTLIST variable remove_condition (True|False) "False"> <!ATTLIST variable remove_condition (True|False) "False">
<!ATTLIST variable remove_fill (True|False) "False"> <!ATTLIST variable remove_fill (True|False) "False">
<!ATTLIST variable public CDATA #IMPLIED> <!ATTLIST variable provider CDATA #IMPLIED>
<!ATTLIST variable test CDATA #IMPLIED> <!ATTLIST variable test CDATA #IMPLIED>
<!ELEMENT value (#PCDATA)> <!ELEMENT value (#PCDATA)>