personaze mode
This commit is contained in:
@ -27,6 +27,5 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
from .convert import RougailConvert
|
||||
from .template.systemd import RougailSystemdTemplate
|
||||
from .config import RougailConfig
|
||||
from .annotator import modes
|
||||
|
||||
__ALL__ = ('RougailConvert', 'RougailSystemdTemplate', 'RougailConfig', 'modes')
|
||||
__ALL__ = ('RougailConvert', 'RougailSystemdTemplate', 'RougailConfig')
|
||||
|
@ -31,11 +31,11 @@ from .check import CheckAnnotator
|
||||
from .value import ValueAnnotator
|
||||
from .condition import ConditionAnnotator
|
||||
from .fill import FillAnnotator
|
||||
from .family import FamilyAnnotator, modes
|
||||
from .family import FamilyAnnotator
|
||||
from .property import PropertyAnnotator
|
||||
|
||||
class SpaceAnnotator: # pylint: disable=R0903
|
||||
"""Transformations applied on a CreoleObjSpace instance
|
||||
"""Transformations applied on a object instance
|
||||
"""
|
||||
def __init__(self, objectspace, eosfunc_file):
|
||||
self.objectspace = objectspace
|
||||
@ -54,4 +54,4 @@ class SpaceAnnotator: # pylint: disable=R0903
|
||||
PropertyAnnotator(objectspace)
|
||||
|
||||
|
||||
__all__ = ('SpaceAnnotator', 'CONVERT_OPTION', 'modes')
|
||||
__all__ = ('SpaceAnnotator', 'CONVERT_OPTION')
|
||||
|
@ -50,6 +50,7 @@ class CheckAnnotator(TargetAnnotator, ParamAnnotator):
|
||||
self.only_variable = True
|
||||
self.functions = dir(load_modules(eosfunc_file))
|
||||
self.functions.extend(INTERNAL_FUNCTIONS)
|
||||
self.functions.extend(self.objectspace.rougailconfig['internal_functions'])
|
||||
self.target_is_uniq = False
|
||||
self.convert_target(self.objectspace.space.constraints.check)
|
||||
self.convert_param(self.objectspace.space.constraints.check)
|
||||
|
@ -72,13 +72,16 @@ class ConditionAnnotator(TargetAnnotator, ParamAnnotator, Walk):
|
||||
only if auto_freeze_variable is True this variable is frozen
|
||||
"""
|
||||
for variable in self.get_variables():
|
||||
if not variable.auto_freeze:
|
||||
if not variable.auto_freeze and not variable.auto_save:
|
||||
continue
|
||||
if variable.namespace != self.objectspace.rougailconfig['variable_namespace']:
|
||||
msg = _(f'auto_freeze is not allowed in extra "{variable.namespace}"')
|
||||
raise DictConsistencyError(msg, 49, variable.xmlfiles)
|
||||
new_condition = self.objectspace.condition(variable.xmlfiles)
|
||||
new_condition.name = 'auto_frozen_if_not_in'
|
||||
if variable.auto_freeze:
|
||||
new_condition.name = 'auto_frozen_if_not_in'
|
||||
else:
|
||||
new_condition.name = 'auto_saved_if_not_in'
|
||||
new_condition.namespace = variable.namespace
|
||||
new_condition.source = self.objectspace.rougailconfig['auto_freeze_variable']
|
||||
new_param = self.objectspace.param(variable.xmlfiles)
|
||||
@ -147,7 +150,9 @@ class ConditionAnnotator(TargetAnnotator, ParamAnnotator, Walk):
|
||||
if condition_name.startswith('hidden_if_'):
|
||||
return ['hidden', 'frozen', 'force_default_on_freeze']
|
||||
if condition_name == 'auto_frozen_if_not_in':
|
||||
return ['auto_frozen']
|
||||
return ['force_store_value', 'frozen']
|
||||
if condition_name == 'auto_saved_if_not_in':
|
||||
return ['force_store_value']
|
||||
return [condition_name.split('_', 1)[0]]
|
||||
|
||||
def _get_family_variables_from_target(self,
|
||||
|
@ -30,18 +30,12 @@ from ..utils import normalize_family
|
||||
from .variable import Walk
|
||||
|
||||
|
||||
#mode order is important
|
||||
modes_level = ('basic', 'normal', 'expert')
|
||||
|
||||
|
||||
class Mode: # pylint: disable=R0903
|
||||
"""Class to manage mode level
|
||||
"""
|
||||
def __init__(self,
|
||||
name: str,
|
||||
level: int,
|
||||
) -> None:
|
||||
self.name = name
|
||||
self.level = level
|
||||
|
||||
def __gt__(self,
|
||||
@ -50,9 +44,6 @@ class Mode: # pylint: disable=R0903
|
||||
return other.level < self.level
|
||||
|
||||
|
||||
modes = {name: Mode(name, idx) for idx, name in enumerate(modes_level)}
|
||||
|
||||
|
||||
class FamilyAnnotator(Walk):
|
||||
"""Annotate family
|
||||
"""
|
||||
@ -62,6 +53,7 @@ class FamilyAnnotator(Walk):
|
||||
self.objectspace = objectspace
|
||||
if not hasattr(self.objectspace.space, 'variables'):
|
||||
return
|
||||
self.modes = {name: Mode(idx) for idx, name in enumerate(self.objectspace.rougailconfig['modes_level'])}
|
||||
self.remove_empty_families()
|
||||
self.family_names()
|
||||
self.change_modes()
|
||||
@ -104,13 +96,34 @@ class FamilyAnnotator(Walk):
|
||||
def change_modes(self):
|
||||
"""change the mode of variables
|
||||
"""
|
||||
modes_level = self.objectspace.rougailconfig['modes_level']
|
||||
default_variable_mode = self.objectspace.rougailconfig['default_variable_mode']
|
||||
if default_variable_mode not in modes_level:
|
||||
msg = _(f'default variable mode "{default_variable_mode}" is not a valid mode, '
|
||||
f'valid modes are {modes_level}')
|
||||
raise DictConsistencyError(msg, 72, None)
|
||||
default_family_mode = self.objectspace.rougailconfig['default_family_mode']
|
||||
if default_family_mode not in modes_level:
|
||||
msg = _(f'default family mode "{default_family_mode}" is not a valid mode, '
|
||||
f'valid modes are {modes_level}')
|
||||
raise DictConsistencyError(msg, 73, None)
|
||||
families = list(self.get_families())
|
||||
for family in families:
|
||||
self.valid_mode(family)
|
||||
self._set_default_mode(family)
|
||||
families.reverse()
|
||||
for family in families:
|
||||
self._change_family_mode(family)
|
||||
|
||||
def valid_mode(self,
|
||||
obj,
|
||||
) -> None:
|
||||
modes_level = self.objectspace.rougailconfig['modes_level']
|
||||
if hasattr(obj, 'mode') and obj.mode not in modes_level:
|
||||
msg = _(f'mode "{obj.mode}" for "{obj.name}" is not a valid mode, '
|
||||
f'valid modes are {modes_level}')
|
||||
raise DictConsistencyError(msg, 71, obj.xmlfiles)
|
||||
|
||||
def _set_default_mode(self,
|
||||
family: 'self.objectspace.family',
|
||||
) -> None:
|
||||
@ -121,6 +134,7 @@ class FamilyAnnotator(Walk):
|
||||
if not hasattr(family, 'variable'):
|
||||
return
|
||||
for variable in family.variable.values():
|
||||
self.valid_mode(variable)
|
||||
if isinstance(variable, self.objectspace.family):
|
||||
if family_mode and not self._has_mode(variable):
|
||||
self._set_auto_mode(variable, family_mode)
|
||||
@ -143,13 +157,13 @@ class FamilyAnnotator(Walk):
|
||||
# if its mode is not defined by the user
|
||||
if not self._has_mode(variable) and \
|
||||
(variable.auto_save is True or variable.auto_freeze is True):
|
||||
self._set_auto_mode(variable, modes_level[0])
|
||||
variable.mode = self.objectspace.rougailconfig['modes_level'][0]
|
||||
# mandatory variable without value is a basic variable
|
||||
elif not self._has_mode(variable) and \
|
||||
variable.mandatory is True and \
|
||||
not hasattr(variable, 'default') and \
|
||||
not hasattr(variable, 'default_multi'):
|
||||
self._set_auto_mode(variable, modes_level[0])
|
||||
variable.mode = self.objectspace.rougailconfig['modes_level'][0]
|
||||
elif family_mode and not self._has_mode(variable):
|
||||
self._set_auto_mode(variable, family_mode)
|
||||
|
||||
@ -164,6 +178,7 @@ class FamilyAnnotator(Walk):
|
||||
) -> None:
|
||||
leader_mode = None
|
||||
for follower in leadership.variable:
|
||||
self.valid_mode(follower)
|
||||
if follower.auto_save is True:
|
||||
msg = _(f'leader/followers "{follower.name}" could not be auto_save')
|
||||
raise DictConsistencyError(msg, 29, leadership.xmlfiles)
|
||||
@ -171,14 +186,18 @@ class FamilyAnnotator(Walk):
|
||||
msg = f'leader/followers "{follower.name}" could not be auto_freeze'
|
||||
raise DictConsistencyError(_(msg), 30, leadership.xmlfiles)
|
||||
if leader_mode is not None:
|
||||
if modes[leader_mode] > modes[follower.mode]:
|
||||
if hasattr(follower, 'mode'):
|
||||
follower_mode = follower.mode
|
||||
else:
|
||||
follower_mode = self.objectspace.rougailconfig['default_variable_mode']
|
||||
if self.modes[leader_mode] > self.modes[follower_mode]:
|
||||
if self._has_mode(follower) and not self._has_mode(leadership.variable[0]):
|
||||
# if follower has mode but not the leader
|
||||
self._set_auto_mode(leadership.variable[0], follower.mode)
|
||||
self._set_auto_mode(leadership.variable[0], follower_mode)
|
||||
else:
|
||||
# leader's mode is minimum level
|
||||
if self._has_mode(follower):
|
||||
msg = _(f'the follower "{follower.name}" is in "{follower.mode}" mode '
|
||||
msg = _(f'the follower "{follower.name}" is in "{follower_mode}" mode '
|
||||
f'but leader have the higher mode "{leader_mode}"')
|
||||
raise DictConsistencyError(msg, 63, follower.xmlfiles)
|
||||
self._set_auto_mode(follower, leader_mode)
|
||||
@ -186,8 +205,13 @@ class FamilyAnnotator(Walk):
|
||||
family_mode,
|
||||
)
|
||||
if leader_mode is None:
|
||||
leader_mode = leadership.variable[0].mode
|
||||
self._set_auto_mode(leadership, leadership.variable[0].mode)
|
||||
if hasattr(leadership.variable[0], 'mode'):
|
||||
leader_mode = leadership.variable[0].mode
|
||||
else:
|
||||
leader_mode = self.objectspace.rougailconfig['default_variable_mode']
|
||||
if hasattr(leadership.variable[0], 'mode'):
|
||||
leader_mode = leadership.variable[0].mode
|
||||
self._set_auto_mode(leadership, leader_mode)
|
||||
|
||||
def _change_family_mode(self,
|
||||
family: 'self.objectspace.family',
|
||||
@ -195,8 +219,8 @@ class FamilyAnnotator(Walk):
|
||||
if hasattr(family, 'mode'):
|
||||
family_mode = family.mode
|
||||
else:
|
||||
family_mode = modes_level[1]
|
||||
min_variable_mode = modes_level[-1]
|
||||
family_mode = self.objectspace.rougailconfig['default_family_mode']
|
||||
min_variable_mode = self.objectspace.rougailconfig['modes_level'][-1]
|
||||
# change variable mode, but not if variables are not in a family
|
||||
if hasattr(family, 'variable'):
|
||||
for variable in family.variable.values():
|
||||
@ -208,9 +232,12 @@ class FamilyAnnotator(Walk):
|
||||
func(variable,
|
||||
family_mode,
|
||||
)
|
||||
if modes[min_variable_mode] > modes[variable.mode]:
|
||||
elif not hasattr(variable, 'mode'):
|
||||
variable.mode = self.objectspace.rougailconfig['default_family_mode']
|
||||
if self.modes[min_variable_mode] > self.modes[variable.mode]:
|
||||
min_variable_mode = variable.mode
|
||||
if hasattr(family, 'mode') and family.mode != min_variable_mode:
|
||||
if isinstance(family, self.objectspace.family) and \
|
||||
(not hasattr(family, 'mode') or family.mode != min_variable_mode):
|
||||
# set the lower variable mode to family
|
||||
if self._has_mode(family):
|
||||
msg = _(f'the family "{family.name}" is in "{family.mode}" mode but variables and '
|
||||
@ -222,13 +249,19 @@ class FamilyAnnotator(Walk):
|
||||
variable,
|
||||
family_mode: str,
|
||||
) -> None:
|
||||
if hasattr(variable, 'mode'):
|
||||
variable_mode = variable.mode
|
||||
else:
|
||||
variable_mode = self.objectspace.rougailconfig['default_variable_mode']
|
||||
# none basic variable in high level family has to be in high level
|
||||
if modes[variable.mode] < modes[family_mode]:
|
||||
if self.modes[variable_mode] < self.modes[family_mode]:
|
||||
if self._has_mode(variable):
|
||||
msg = _(f'the variable "{variable.name}" is in "{variable.mode}" mode '
|
||||
msg = _(f'the variable "{variable.name}" is in "{variable_mode}" mode '
|
||||
f'but family has the higher family mode "{family_mode}"')
|
||||
raise DictConsistencyError(msg, 61, variable.xmlfiles)
|
||||
self._set_auto_mode(variable, family_mode)
|
||||
if not hasattr(variable, 'mode'):
|
||||
variable.mode = variable_mode
|
||||
|
||||
def _change_variable_mode_leader(self,
|
||||
leadership,
|
||||
|
@ -29,11 +29,8 @@ from ..error import DictConsistencyError
|
||||
from .variable import Walk
|
||||
|
||||
|
||||
PROPERTIES = ('hidden', 'frozen', 'auto_freeze', 'auto_save', 'force_default_on_freeze',
|
||||
PROPERTIES = ('hidden', 'frozen', 'force_default_on_freeze',
|
||||
'force_store_value', 'disabled', 'mandatory')
|
||||
CONVERT_PROPERTIES = {'auto_save': ['force_store_value'],
|
||||
'auto_freeze': ['force_store_value', 'auto_freeze'],
|
||||
}
|
||||
|
||||
|
||||
class PropertyAnnotator(Walk):
|
||||
@ -54,7 +51,8 @@ class PropertyAnnotator(Walk):
|
||||
"""
|
||||
# hidden variable is also frozen
|
||||
if isinstance(variable, self.objectspace.variable) and variable.hidden is True:
|
||||
variable.frozen = True
|
||||
if not variable.auto_freeze:
|
||||
variable.frozen = True
|
||||
if not variable.auto_save and \
|
||||
not variable.auto_freeze and \
|
||||
'force_default_on_freeze' not in vars(variable):
|
||||
@ -64,8 +62,8 @@ class PropertyAnnotator(Walk):
|
||||
for prop in PROPERTIES:
|
||||
if hasattr(variable, prop):
|
||||
if getattr(variable, prop) is True:
|
||||
for subprop in CONVERT_PROPERTIES.get(prop, [prop]):
|
||||
variable.properties.append(subprop)
|
||||
# for subprop in CONVERT_PROPERTIES.get(prop, [prop]):
|
||||
variable.properties.append(prop)
|
||||
setattr(variable, prop, None)
|
||||
if hasattr(variable, 'mode') and variable.mode:
|
||||
variable.properties.append(variable.mode)
|
||||
|
@ -31,7 +31,7 @@ from ..i18n import _
|
||||
from ..utils import normalize_family
|
||||
from ..error import DictConsistencyError
|
||||
from ..config import RougailConfig
|
||||
# a CreoleObjSpace's attribute has some annotations
|
||||
# a object's attribute has some annotations
|
||||
# that shall not be present in the exported (flatened) XML
|
||||
ERASED_ATTRIBUTES = ('redefine', 'exists', 'optional', 'remove_check', 'namespace',
|
||||
'remove_condition', 'path', 'instance_mode', 'index',
|
||||
|
@ -43,4 +43,8 @@ RougailConfig = {'dictionaries_dir': [join(ROUGAILROOT, 'dictionaries')],
|
||||
'variable_namespace': 'rougail',
|
||||
'auto_freeze_variable': 'instanciated_module',
|
||||
'default_engine': 'creole',
|
||||
'internal_functions': [],
|
||||
'modes_level': ['basic', 'normal', 'expert'],
|
||||
'default_family_mode': 'basic',
|
||||
'default_variable_mode': 'normal',
|
||||
}
|
||||
|
@ -27,12 +27,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Sample usage::
|
||||
|
||||
>>> from rougail import Rougail
|
||||
>>> rougail = Rougail()
|
||||
>>> rougail.load_dictionaries(['/usr/share/rougail/dicos'])
|
||||
>>> rougail.load_extra_dictionaries('extra1', ['/usr/share/rougail/extra1'])
|
||||
>>> rougail.space_visitor('/usr/share/rougail/funcs.py')
|
||||
>>> tiramisu = rougail.save()
|
||||
>>> from rougail import RougailConvert
|
||||
>>> rougail = RougailConvert()
|
||||
>>> tiramisu = rougail.save('tiramisu.py')
|
||||
|
||||
The Rougail
|
||||
|
||||
|
@ -80,7 +80,7 @@
|
||||
<!ATTLIST family name CDATA #REQUIRED>
|
||||
<!ATTLIST family description CDATA #IMPLIED>
|
||||
<!ATTLIST family help CDATA #IMPLIED>
|
||||
<!ATTLIST family mode (basic|normal|expert) "basic">
|
||||
<!ATTLIST family mode CDATA #IMPLIED>
|
||||
<!ATTLIST family hidden (True|False) "False">
|
||||
<!ATTLIST family dynamic CDATA #IMPLIED>
|
||||
|
||||
@ -97,7 +97,7 @@
|
||||
<!ATTLIST variable mandatory (True|False) "False">
|
||||
<!ATTLIST variable auto_freeze (True|False) "False">
|
||||
<!ATTLIST variable auto_save (True|False) "False">
|
||||
<!ATTLIST variable mode (basic|normal|expert) "normal">
|
||||
<!ATTLIST variable mode CDATA #IMPLIED>
|
||||
<!ATTLIST variable remove_check (True|False) "False">
|
||||
<!ATTLIST variable remove_condition (True|False) "False">
|
||||
<!ATTLIST variable remove_fill (True|False) "False">
|
||||
|
@ -30,8 +30,7 @@ from .utils import normalize_family
|
||||
|
||||
|
||||
class Path:
|
||||
"""Helper class to handle the `path` attribute of a CreoleObjSpace
|
||||
instance.
|
||||
"""Helper class to handle the `path` attribute.
|
||||
|
||||
sample: path="creole.general.condition"
|
||||
"""
|
||||
|
@ -55,7 +55,7 @@ class TiramisuReflector:
|
||||
):
|
||||
self.index = 0
|
||||
self.text = []
|
||||
if isfile(funcs_path):
|
||||
if funcs_path and isfile(funcs_path):
|
||||
self.text.extend(["from importlib.machinery import SourceFileLoader",
|
||||
"from importlib.util import spec_from_loader, module_from_spec",
|
||||
f"loader = SourceFileLoader('func', '{funcs_path}')",
|
||||
|
Reference in New Issue
Block a user