diff --git a/src/rougail/annotator.py b/src/rougail/annotator.py
index c914acba..e3334c11 100644
--- a/src/rougail/annotator.py
+++ b/src/rougail/annotator.py
@@ -987,20 +987,24 @@ class ConstraintAnnotator:
elif name == 'valid_network_netmask':
params_len = 1
if len(check.param) != params_len:
- raise DictConsistencyError(_('{} must have {} param').format(name, params_len))
+ xmlfiles = self.objectspace.display_xmlfiles(check.xmlfiles)
+ raise DictConsistencyError(_(f'{name} must have {params_len} param in {xmlfiles}'))
elif name == 'valid_ipnetmask':
params_len = 1
if len(check.param) != params_len:
- raise DictConsistencyError(_('{} must have {} param').format(name, params_len))
+ xmlfiles = self.objectspace.display_xmlfiles(check.xmlfiles)
+ raise DictConsistencyError(_(f'{name} must have {params_len} param in {xmlfiles}'))
name = 'valid_ip_netmask'
elif name == 'valid_broadcast':
params_len = 2
if len(check.param) != params_len:
- raise DictConsistencyError(_('{} must have {} param').format(name, params_len))
+ xmlfiles = self.objectspace.display_xmlfiles(check.xmlfiles)
+ raise DictConsistencyError(_(f'{name} must have {params_len} param in {xmlfiles}'))
elif name == 'valid_in_network':
- params_len = 2
- if len(check.param) != params_len:
- raise DictConsistencyError(_('{} must have {} param').format(name, params_len))
+ if len(check.param) not in (1, 2):
+ params_len = 2
+ xmlfiles = self.objectspace.display_xmlfiles(check.xmlfiles)
+ raise DictConsistencyError(_(f'{name} must have {params_len} param in {xmlfiles}'))
check_.name = name
check_.warnings_only = check.warnings_only
if hasattr(check, 'param'):
diff --git a/src/rougail/xmlreflector.py b/src/rougail/xmlreflector.py
index 81cc5d75..a2ebcc90 100644
--- a/src/rougail/xmlreflector.py
+++ b/src/rougail/xmlreflector.py
@@ -37,7 +37,7 @@ class XMLReflector(object):
# document = parse(BytesIO(xmlfile), XMLParser(remove_blank_text=True))
document = parse(xmlfile)
if not self.dtd.validate(document):
- raise DictConsistencyError(_("not a valid xml file: {}").format(xmlfile))
+ raise DictConsistencyError(_(f'"{xmlfile}" not a valid xml file: {self.dtd.error_log.filter_from_errors()[0]}'))
return document.getroot()
def load_xml_from_folders(self, xmlfolders):
diff --git a/tests/dictionaries/10check_valid_in_network/00-base.xml b/tests/dictionaries/10check_valid_in_network/00-base.xml
new file mode 100644
index 00000000..43cc2898
--- /dev/null
+++ b/tests/dictionaries/10check_valid_in_network/00-base.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+ oui
+
+
+
+
+
+
+
+
+
+
+ adresse_ip_eth0
+ adresse_netmask_eth0
+
+
+
+
+
+
+
diff --git a/tests/dictionaries/10check_valid_in_network/__init__.py b/tests/dictionaries/10check_valid_in_network/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/dictionaries/10check_valid_in_network/makedict/base.json b/tests/dictionaries/10check_valid_in_network/makedict/base.json
new file mode 100644
index 00000000..b82b5b43
--- /dev/null
+++ b/tests/dictionaries/10check_valid_in_network/makedict/base.json
@@ -0,0 +1 @@
+{"rougail.general.mode_conteneur_actif": "oui", "rougail.general.adresse_ip_eth0": null, "rougail.general.adresse_netmask_eth0": null, "rougail.general.adresse_ip": null}
diff --git a/tests/dictionaries/10check_valid_in_network/tiramisu/__init__.py b/tests/dictionaries/10check_valid_in_network/tiramisu/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/dictionaries/10check_valid_in_network/tiramisu/base.py b/tests/dictionaries/10check_valid_in_network/tiramisu/base.py
new file mode 100644
index 00000000..c5e87cc1
--- /dev/null
+++ b/tests/dictionaries/10check_valid_in_network/tiramisu/base.py
@@ -0,0 +1,17 @@
+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 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default='oui', values=('oui', 'non'))
+option_4 = IPOption(private_only=True, warnings_only=True, properties=frozenset({'basic', 'mandatory'}), name='adresse_ip_eth0', doc='Adresse IP de la carte', multi=False)
+option_5 = NetmaskOption(properties=frozenset({'basic', 'mandatory'}), name='adresse_netmask_eth0', doc='Masque de sous réseau de la carte', multi=False)
+option_6 = IPOption(private_only=True, warnings_only=True, properties=frozenset({'basic', 'mandatory'}), validators=[Calculation(func.valid_in_network, Params((ParamSelfOption(), ParamOption(option_4, notraisepropertyerror=False, todict=False), ParamOption(option_5, notraisepropertyerror=False, todict=False)), kwargs={}), warnings_only=True)], name='adresse_ip', doc='IP', multi=False)
+option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'basic'}), children=[option_3, option_4, option_5, option_6])
+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/10check_valid_in_network_cidr/00-base.xml b/tests/dictionaries/10check_valid_in_network_cidr/00-base.xml
new file mode 100644
index 00000000..f11b495b
--- /dev/null
+++ b/tests/dictionaries/10check_valid_in_network_cidr/00-base.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+ oui
+
+
+
+
+
+
+
+
+
+ adresse_ip_eth0
+
+
+
+
+
+
+
diff --git a/tests/dictionaries/10check_valid_in_network_cidr/__init__.py b/tests/dictionaries/10check_valid_in_network_cidr/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/dictionaries/10check_valid_in_network_cidr/makedict/base.json b/tests/dictionaries/10check_valid_in_network_cidr/makedict/base.json
new file mode 100644
index 00000000..3d0e2f80
--- /dev/null
+++ b/tests/dictionaries/10check_valid_in_network_cidr/makedict/base.json
@@ -0,0 +1 @@
+{"rougail.general.mode_conteneur_actif": "oui", "rougail.general.adresse_ip_eth0": null, "rougail.general.adresse_ip": null}
diff --git a/tests/dictionaries/10check_valid_in_network_cidr/tiramisu/__init__.py b/tests/dictionaries/10check_valid_in_network_cidr/tiramisu/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/dictionaries/10check_valid_in_network_cidr/tiramisu/base.py b/tests/dictionaries/10check_valid_in_network_cidr/tiramisu/base.py
new file mode 100644
index 00000000..c994c75d
--- /dev/null
+++ b/tests/dictionaries/10check_valid_in_network_cidr/tiramisu/base.py
@@ -0,0 +1,16 @@
+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 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default='oui', values=('oui', 'non'))
+option_4 = IPOption(cidr=True, properties=frozenset({'basic', 'mandatory'}), name='adresse_ip_eth0', doc='Adresse IP de la carte', multi=False)
+option_5 = IPOption(private_only=True, warnings_only=True, properties=frozenset({'basic', 'mandatory'}), validators=[Calculation(func.valid_in_network, Params((ParamSelfOption(), ParamOption(option_4, notraisepropertyerror=False, todict=False)), kwargs={}), warnings_only=True)], name='adresse_ip', doc='IP', multi=False)
+option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'basic'}), children=[option_3, option_4, option_5])
+option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])
+option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
diff --git a/tests/eosfunc/test.py b/tests/eosfunc/test.py
index d258ac45..ec3de625 100644
--- a/tests/eosfunc/test.py
+++ b/tests/eosfunc/test.py
@@ -1,4 +1,4 @@
-from tiramisu import valid_not_equal, valid_ip_netmask, calc_value
+from tiramisu import valid_not_equal, valid_ip_netmask, calc_value, valid_in_network
def calc_val(*args, **kwargs):
if len(args) > 0: