diff --git a/src/rougail/annotator.py b/src/rougail/annotator.py
index 2f77c789..77cb5f94 100644
--- a/src/rougail/annotator.py
+++ b/src/rougail/annotator.py
@@ -34,6 +34,33 @@ def mode_factory():
modes = mode_factory()
+CONVERT_OPTION = {'number': dict(opttype="IntOption", func=int),
+ 'float': dict(opttype="FloatOption", func=float),
+ 'choice': dict(opttype="ChoiceOption"),
+ 'string': dict(opttype="StrOption"),
+ 'password': dict(opttype="PasswordOption"),
+ 'mail': dict(opttype="EmailOption"),
+ 'boolean': dict(opttype="BoolOption"),
+ 'symlink': dict(opttype="SymLinkOption"),
+ 'filename': dict(opttype="FilenameOption"),
+ 'date': dict(opttype="DateOption"),
+ 'unix_user': dict(opttype="UsernameOption"),
+ 'ip': dict(opttype="IPOption", initkwargs={'allow_reserved': True}),
+ 'local_ip': dict(opttype="IPOption", initkwargs={'private_only': True, 'warnings_only': True}),
+ 'netmask': dict(opttype="NetmaskOption"),
+ 'network': dict(opttype="NetworkOption"),
+ 'broadcast': dict(opttype="BroadcastOption"),
+ 'netbios': dict(opttype="DomainnameOption", initkwargs={'type': 'netbios', 'warnings_only': True}),
+ 'domain': dict(opttype="DomainnameOption", initkwargs={'type': 'domainname', 'allow_ip': False}),
+ 'hostname': dict(opttype="DomainnameOption", initkwargs={'type': 'hostname', 'allow_ip': False}),
+ 'web_address': dict(opttype="URLOption", initkwargs={'allow_ip': True, 'allow_without_dot': True}),
+ 'port': dict(opttype="PortOption", initkwargs={'allow_private': True}),
+ 'mac': dict(opttype="MACOption"),
+ 'cidr': dict(opttype="IPOption", initkwargs={'cidr': True}),
+ 'network_cidr': dict(opttype="NetworkOption", initkwargs={'cidr': True}),
+ }
+
+
# a CreoleObjSpace's attribute has some annotations
# that shall not be present in the exported (flatened) XML
ERASED_ATTRIBUTES = ('redefine', 'exists', 'fallback', 'optional', 'remove_check', 'namespace',
@@ -56,8 +83,6 @@ KEY_TYPE = {'variable': 'symlink',
'URLOption': 'web_address',
'FilenameOption': 'filename'}
-CONVERSION = {'number': int}
-
FREEZE_AUTOFREEZE_VARIABLE = 'module_instancie'
PROPERTIES = ('hidden', 'frozen', 'auto_freeze', 'auto_save', 'force_default_on_freeze',
@@ -465,7 +490,7 @@ class VariableAnnotator:
for value in variable.value:
if not hasattr(value, 'type'):
value.type = variable.type
- value.name = CONVERSION.get(value.type, str)(value.name)
+ value.name = CONVERT_OPTION.get(value.type, {}).get('func', str)(value.name)
for key, value in RENAME_ATTIBUTES.items():
setattr(variable, value, getattr(variable, key))
setattr(variable, key, None)
@@ -497,6 +522,11 @@ class VariableAnnotator:
self.objectspace.space.constraints.check.append(check)
variable.type = 'string'
+ def _valid_type(variable):
+ if variable.type not in CONVERT_OPTION:
+ xmlfiles = self.objectspace.display_xmlfiles(variable.xmlfiles)
+ raise DictConsistencyError(_(f'unvalid type "{variable.type}" for variable "{variable.name}" in {xmlfiles}'))
+
if not hasattr(self.objectspace.space, 'variables'):
return
for families in self.objectspace.space.variables.values():
@@ -526,6 +556,7 @@ class VariableAnnotator:
follower,
path,
)
+ _valid_type(follower)
else:
path = '{}.{}.{}'.format(namespace, normalize_family(family.name), variable.name)
_convert_variable(variable,
@@ -535,6 +566,7 @@ class VariableAnnotator:
variable,
path,
)
+ _valid_type(variable)
def convert_helps(self):
if not hasattr(self.objectspace.space, 'help'):
@@ -941,7 +973,7 @@ class ConstraintAnnotator:
choice = self.objectspace.choice(variable.xmlfiles)
try:
if value is not None:
- choice.name = CONVERSION.get(type_, str)(value)
+ choice.name = CONVERT_OPTION[type_].get('func', str)(value)
else:
choice.name = value
except:
@@ -956,7 +988,7 @@ class ConstraintAnnotator:
for value in variable.value:
value.type = type_
try:
- cvalue = CONVERSION.get(type_, str)(value.name)
+ cvalue = CONVERT_OPTION[type_].get('func', str)(value.name)
except:
raise DictConsistencyError(_(f'unable to change type of value "{value}" is not a valid "{type_}" for "{variable.name}"'))
if cvalue not in choices:
diff --git a/src/rougail/tiramisureflector.py b/src/rougail/tiramisureflector.py
index 30754662..80f37257 100644
--- a/src/rougail/tiramisureflector.py
+++ b/src/rougail/tiramisureflector.py
@@ -4,7 +4,7 @@ flattened XML specific
from .config import Config
from .i18n import _
from .error import LoaderError
-from .annotator import ERASED_ATTRIBUTES
+from .annotator import ERASED_ATTRIBUTES, CONVERT_OPTION
FUNC_TO_DICT = ['valid_not_equal']
@@ -12,32 +12,6 @@ FORCE_INFORMATIONS = ['help', 'test', 'separator', 'manage']
ATTRIBUTES_ORDER = ('name', 'doc', 'default', 'multi')
-CONVERT_OPTION = {'number': dict(opttype="IntOption", func=int),
- 'choice': dict(opttype="ChoiceOption"),
- 'string': dict(opttype="StrOption"),
- 'password': dict(opttype="PasswordOption"),
- 'mail': dict(opttype="EmailOption"),
- 'boolean': dict(opttype="BoolOption"),
- 'symlink': dict(opttype="SymLinkOption"),
- 'filename': dict(opttype="FilenameOption"),
- 'date': dict(opttype="DateOption"),
- 'unix_user': dict(opttype="UsernameOption"),
- 'ip': dict(opttype="IPOption", initkwargs={'allow_reserved': True}),
- 'local_ip': dict(opttype="IPOption", initkwargs={'private_only': True, 'warnings_only': True}),
- 'netmask': dict(opttype="NetmaskOption"),
- 'network': dict(opttype="NetworkOption"),
- 'broadcast': dict(opttype="BroadcastOption"),
- 'netbios': dict(opttype="DomainnameOption", initkwargs={'type': 'netbios', 'warnings_only': True}),
- 'domain': dict(opttype="DomainnameOption", initkwargs={'type': 'domainname', 'allow_ip': False}),
- 'hostname': dict(opttype="DomainnameOption", initkwargs={'type': 'hostname', 'allow_ip': False}),
- 'web_address': dict(opttype="URLOption", initkwargs={'allow_ip': True, 'allow_without_dot': True}),
- 'port': dict(opttype="PortOption", initkwargs={'allow_private': True}),
- 'mac': dict(opttype="MACOption"),
- 'cidr': dict(opttype="IPOption", initkwargs={'cidr': True}),
- 'network_cidr': dict(opttype="NetworkOption", initkwargs={'cidr': True}),
- }
-
-
class TiramisuReflector:
def __init__(self,
xmlroot,
@@ -344,6 +318,8 @@ class Variable(Common):
value = value.split(',')
if self.object_type == 'IntOption':
value = [int(v) for v in value]
+ elif self.object_type == 'FloatOption':
+ value = [float(v) for v in value]
self.informations[key] = value
else:
self.attrib[key] = value
@@ -443,7 +419,7 @@ class Variable(Common):
self.attrib['default'].append(value)
if not self.is_leader:
self.attrib['default_multi'] = value
- elif isinstance(value, int):
+ elif isinstance(value, (int, float)):
self.attrib['default'].append(value)
else:
self.attrib['default'].append("'" + value + "'")
diff --git a/tests/dictionaries/01base_float/00-base.xml b/tests/dictionaries/01base_float/00-base.xml
new file mode 100644
index 00000000..94eb6303
--- /dev/null
+++ b/tests/dictionaries/01base_float/00-base.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ 0.527
+
+
+ 0.527
+
+
+
+
+
+
diff --git a/tests/dictionaries/01base_float/__init__.py b/tests/dictionaries/01base_float/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/dictionaries/01base_float/makedict/base.json b/tests/dictionaries/01base_float/makedict/base.json
new file mode 100644
index 00000000..113d425d
--- /dev/null
+++ b/tests/dictionaries/01base_float/makedict/base.json
@@ -0,0 +1 @@
+{"rougail.general.float": 0.527, "rougail.general.float_multi": [0.527]}
diff --git a/tests/dictionaries/01base_float/tiramisu/__init__.py b/tests/dictionaries/01base_float/tiramisu/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/dictionaries/01base_float/tiramisu/base.py b/tests/dictionaries/01base_float/tiramisu/base.py
new file mode 100644
index 00000000..792415e7
--- /dev/null
+++ b/tests/dictionaries/01base_float/tiramisu/base.py
@@ -0,0 +1,15 @@
+import imp
+func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
+for key, value in dict(locals()).items():
+ if key != ['imp', 'func']:
+ setattr(func, key, value)
+try:
+ from tiramisu3 import *
+except:
+ from tiramisu import *
+from rougail.tiramisu import ConvertDynOptionDescription
+option_3 = FloatOption(properties=frozenset({'mandatory', 'normal'}), name='float', doc='Description', multi=False, default=0.527)
+option_4 = FloatOption(properties=frozenset({'mandatory', 'normal'}), name='float_multi', doc='Description', multi=True, default=[0.527], default_multi=0.527)
+option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3, option_4])
+option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])
+option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
diff --git a/tests/dictionaries/80unknown_type/00-base.xml b/tests/dictionaries/80unknown_type/00-base.xml
new file mode 100644
index 00000000..deb50aeb
--- /dev/null
+++ b/tests/dictionaries/80unknown_type/00-base.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
diff --git a/tests/dictionaries/80unknown_type/__init__.py b/tests/dictionaries/80unknown_type/__init__.py
new file mode 100644
index 00000000..e69de29b