valid Option is an unicode or a string if needed
authorEmmanuel Garette <egarette@cadoles.com>
Sun, 19 Apr 2015 07:15:18 +0000 (09:15 +0200)
committerEmmanuel Garette <egarette@cadoles.com>
Sun, 19 Apr 2015 07:15:18 +0000 (09:15 +0200)
ChangeLog
test/test_config_api.py
tiramisu/option/baseoption.py
tiramisu/option/option.py
translations/fr/tiramisu.po
translations/tiramisu.pot

index 4ccc2f8..95bf8fd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+Sun Apr 19 09:14:21 2015 +0200 Emmanuel Garette <egarette@cadoles.com>
+       * valid Option is an unicode or a string if needed
+
 Sat Apr 18 22:42:53 2015 +0200 Emmanuel Garette <egarette@cadoles.com>
        * refactor validation, build a fake context (with new Values and
        Settings) to validate value with those object. Now value with
index 488e7b8..920b7e5 100644 (file)
@@ -289,3 +289,4 @@ def test_invalid_option():
     raises(ValueError, "DomainnameOption('a', '', type_='string')")
     raises(ValueError, "DomainnameOption('a', '', allow_ip='string')")
     raises(ValueError, "DomainnameOption('a', '', allow_without_dot='string')")
+    raises(ValueError, "DomainnameOption('a', '', 1)")
index dba4ba6..500b348 100644 (file)
@@ -387,6 +387,10 @@ class BaseOption(Base):
     def impl_getproperties(self):
         return self._properties
 
+    def _impl_valid_unicode(self, value):
+        if not isinstance(value, unicode) and not isinstance(value, str):
+            raise ValueError(_('invalid unicode or string'))
+
 
 class OnlyOption(BaseOption):
     __slots__ = tuple()
index d1927ea..75b419e 100644 (file)
@@ -172,6 +172,7 @@ class IPOption(Option):
     def _validate(self, value, context=undefined):
         # sometimes an ip term starts with a zero
         # but this does not fit in some case, for example bind does not like it
+        self._impl_valid_unicode(value)
         try:
             for val in value.split('.'):
                 if val.startswith("0") and len(val) > 1:
@@ -273,6 +274,9 @@ class PortOption(Option):
                                          extra=extra)
 
     def _validate(self, value, context=undefined):
+        if isinstance(value, int):
+            value = unicode(value)
+        self._impl_valid_unicode(value)
         if self._get_extra('_allow_range') and ":" in str(value):  # pragma: optional cover
             value = str(value).split(':')
             if len(value) != 2:
@@ -300,6 +304,7 @@ class NetworkOption(Option):
     __slots__ = tuple()
 
     def _validate(self, value, context=undefined):
+        self._impl_valid_unicode(value)
         try:
             IP(value)
         except ValueError:  # pragma: optional cover
@@ -320,6 +325,7 @@ class NetmaskOption(Option):
     __slots__ = tuple()
 
     def _validate(self, value, context=undefined):
+        self._impl_valid_unicode(value)
         try:
             IP('0.0.0.0/{0}'.format(value))
         except ValueError:  # pragma: optional cover
@@ -367,6 +373,7 @@ class BroadcastOption(Option):
     __slots__ = tuple()
 
     def _validate(self, value, context=undefined):
+        self._impl_valid_unicode(value)
         try:
             IP('{0}/32'.format(value))
         except ValueError:  # pragma: optional cover
@@ -424,6 +431,7 @@ class DomainnameOption(Option):
                                                extra=extra)
 
     def _validate(self, value, context=undefined):
+        self._impl_valid_unicode(value)
         def _valid_length(val):
             if len(val) < 2:
                 raise ValueError(_("invalid domainname's length (min 2)"))
@@ -479,6 +487,7 @@ class EmailOption(DomainnameOption):
     username_re = re.compile(r"^[\w!#$%&'*+\-/=?^`{|}~.]+$")
 
     def _validate(self, value, context=undefined):
+        self._impl_valid_unicode(value)
         splitted = value.split('@', 1)
         try:
             username, domain = splitted
@@ -500,6 +509,7 @@ class URLOption(DomainnameOption):
     path_re = re.compile(r"^[a-z0-9\-\._~:/\?#\[\]@!%\$&\'\(\)\*\+,;=]+$")
 
     def _validate(self, value, context=undefined):
+        self._impl_valid_unicode(value)
         match = self.proto_re.search(value)
         if not match:  # pragma: optional cover
             raise ValueError(_('invalid url, must start with http:// or '
@@ -540,6 +550,7 @@ class UsernameOption(Option):
     username_re = re.compile(r"^[a-z_][a-z0-9_-]{0,30}[$a-z0-9_-]{0,1}$")
 
     def _validate(self, value, context=undefined):
+        self._impl_valid_unicode(value)
         match = self.username_re.search(value)
         if not match:
             raise ValueError(_('invalid username'))  # pragma: optional cover
@@ -550,6 +561,7 @@ class FilenameOption(Option):
     path_re = re.compile(r"^[a-zA-Z0-9\-\._~/+]+$")
 
     def _validate(self, value, context=undefined):
+        self._impl_valid_unicode(value)
         match = self.path_re.search(value)
         if not match:
             raise ValueError(_('invalid filename'))  # pragma: optional cover
index f782bb7..71a1b69 100644 (file)
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Tiramisu\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-04-18 22:40+CEST\n"
+"POT-Creation-Date: 2015-04-18 23:52+CEST\n"
 "PO-Revision-Date: \n"
 "Last-Translator: Emmanuel Garette <egarette@cadoles.com>\n"
 "Language-Team: Tiramisu's team <egarette@cadoles.com>\n"
@@ -29,8 +29,8 @@ msgstr "descr doit être une optiondescription pas un {0}"
 msgid "unknown group_type: {0}"
 msgstr "group_type inconnu: {0}"
 
-#: tiramisu/config.py:181 tiramisu/setting.py:320 tiramisu/value.py:54
-#: tiramisu/value.py:616
+#: tiramisu/config.py:181 tiramisu/setting.py:323 tiramisu/value.py:54
+#: tiramisu/value.py:621
 msgid "the context does not exist anymore"
 msgstr "le context n'existe plus"
 
@@ -194,101 +194,106 @@ msgstr "ne peut serialiser une Option, seulement via une OptionDescription"
 msgid "'{0}' ({1}) object attribute '{2}' is read-only"
 msgstr "l'attribut {2} de l'objet '{0}' ({1}) est en lecture seule"
 
-#: tiramisu/option/baseoption.py:545 tiramisu/option/baseoption.py:588
+#: tiramisu/option/baseoption.py:392
+#, fuzzy
+msgid "invalid unicode or string"
+msgstr "invalide unicode ou string"
+
+#: tiramisu/option/baseoption.py:549 tiramisu/option/baseoption.py:594
 msgid "invalid value for option {0}: {1}"
 msgstr "valeur invalide pour l'option {0} : {1}"
 
-#: tiramisu/option/baseoption.py:558
+#: tiramisu/option/baseoption.py:562
 msgid "do_validation for {0}: error in value"
 msgstr "do_validation for {0} : erreur dans un la valeur"
 
-#: tiramisu/option/baseoption.py:564
+#: tiramisu/option/baseoption.py:568
 msgid "do_validation for {0}: warning in value"
 msgstr "do_validation for {0} : warning dans un la valeur"
 
-#: tiramisu/option/baseoption.py:574
+#: tiramisu/option/baseoption.py:578
 msgid "do_validation for {0}: error in consistency"
 msgstr "do_validation for {0} : erreur dans un test de consistance"
 
-#: tiramisu/option/baseoption.py:578
+#: tiramisu/option/baseoption.py:582
 msgid "do_validation for {0}: warning in consistency"
 msgstr "do_validation for {0} : warning dans un test de consistance"
 
-#: tiramisu/option/baseoption.py:582
+#: tiramisu/option/baseoption.py:586
 msgid "warning on the value of the option {0}: {1}"
 msgstr "avertissement sur la valeur de l'option {0} : {1}"
 
-#: tiramisu/option/baseoption.py:600 tiramisu/option/baseoption.py:609
+#: tiramisu/option/baseoption.py:606 tiramisu/option/baseoption.py:615
 msgid "invalid value {0} for option {1} which must be a list"
 msgstr "valeur invalide pour l'option {0} : {1} laquelle doit être une liste"
 
-#: tiramisu/option/baseoption.py:615
+#: tiramisu/option/baseoption.py:621
 msgid "invalid value {0} for option {1} which must be a list of list"
 msgstr ""
 "valeur invalide pour l'option {0} : {1} laquelle doit être une liste de liste"
 
-#: tiramisu/option/baseoption.py:668
+#: tiramisu/option/baseoption.py:674
 msgid "'{0}' ({1}) cannot add consistency, option is read-only"
 msgstr ""
 "'{0}' ({1}) ne peut ajouter de consistency, l'option est en lecture seul"
 
-#: tiramisu/option/baseoption.py:680
+#: tiramisu/option/baseoption.py:686
 msgid "unknow parameter {0} in consistency"
 msgstr "paramètre inconnu {0} dans un test de consistance"
 
-#: tiramisu/option/baseoption.py:687
+#: tiramisu/option/baseoption.py:693
 msgid "consistency must be set with an option"
 msgstr "consistency doit être configuré avec une option"
 
-#: tiramisu/option/baseoption.py:690 tiramisu/option/baseoption.py:697
+#: tiramisu/option/baseoption.py:696 tiramisu/option/baseoption.py:703
 msgid ""
 "almost one option in consistency is in a dynoptiondescription but not all"
 msgstr ""
 "au moins une option dans le test de consistance est dans une "
 "dynoptiondescription mais pas toutes"
 
-#: tiramisu/option/baseoption.py:693
+#: tiramisu/option/baseoption.py:699
 msgid "option in consistency must be in same dynoptiondescription"
 msgstr ""
 "option dans une consistency doit être dans le même dynoptiondescription"
 
-#: tiramisu/option/baseoption.py:700
+#: tiramisu/option/baseoption.py:706
 msgid "cannot add consistency with itself"
 msgstr "ne peut ajouter une consistency avec lui même"
 
-#: tiramisu/option/baseoption.py:702
+#: tiramisu/option/baseoption.py:708
 msgid "every options in consistency must be multi or none"
 msgstr ""
 "toutes les options d'une consistency doivent être multi ou ne pas l'être"
 
-#: tiramisu/option/baseoption.py:706
+#: tiramisu/option/baseoption.py:712
 msgid "consistency {0} not available for this option"
 msgstr "consistency {0} non valable pour cette option"
 
-#: tiramisu/option/baseoption.py:735
+#: tiramisu/option/baseoption.py:741
 msgid "same value for {0} and {1}, should be different"
 msgstr "même valeur pour {0} et {1}, devrait être différent"
 
-#: tiramisu/option/baseoption.py:737
+#: tiramisu/option/baseoption.py:743
 msgid "same value for {0} and {1}, must be different"
 msgstr "même valeur pour {0} et {1}, doit être différent"
 
-#: tiramisu/option/baseoption.py:794
+#: tiramisu/option/baseoption.py:800
 msgid "default value not allowed if option: {0} is calculated"
 msgstr "la valeur par défaut n'est pas possible si l'option {0} est calculée"
 
-#: tiramisu/option/baseoption.py:816
+#: tiramisu/option/baseoption.py:822
 msgid "malformed requirements type for option: {0}, must be a dict"
 msgstr ""
 "type requirements malformé pour l'option : {0}, doit être un dictionnaire"
 
-#: tiramisu/option/baseoption.py:822
+#: tiramisu/option/baseoption.py:828
 msgid "malformed requirements for option: {0} unknown keys {1}, must only {2}"
 msgstr ""
 "requirements mal formés pour l'option : {0} clefs inconnues {1}, doit "
 "seulement avoir {2}"
 
-#: tiramisu/option/baseoption.py:833
+#: tiramisu/option/baseoption.py:839
 msgid ""
 "malformed requirements for option: {0} require must have option, expected "
 "and action keys"
@@ -296,49 +301,49 @@ msgstr ""
 "requirements malformé pour l'option : {0} l'exigence doit avoir les clefs "
 "option, expected et action"
 
-#: tiramisu/option/baseoption.py:837
+#: tiramisu/option/baseoption.py:843
 msgid ""
 "malformed requirements for option: {0} action cannot be force_store_value"
 msgstr ""
 "requirements mal formés pour l'option : {0} action ne peut pas être "
 "force_store_value"
 
-#: tiramisu/option/baseoption.py:842
+#: tiramisu/option/baseoption.py:848
 msgid "malformed requirements for option: {0} inverse must be boolean"
 msgstr ""
 "requirements mal formés pour l'option : {0} inverse doit être un booléen"
 
-#: tiramisu/option/baseoption.py:846
+#: tiramisu/option/baseoption.py:852
 msgid "malformed requirements for option: {0} transitive must be boolean"
 msgstr ""
 "requirements mal formés pour l'option : {0} transitive doit être booléen"
 
-#: tiramisu/option/baseoption.py:850
+#: tiramisu/option/baseoption.py:856
 msgid "malformed requirements for option: {0} same_action must be boolean"
 msgstr ""
 "requirements mal formés pour l'option : {0} same_action doit être un booléen"
 
-#: tiramisu/option/baseoption.py:854
+#: tiramisu/option/baseoption.py:860
 msgid "malformed requirements must be an option in option {0}"
 msgstr "requirements mal formés doit être une option dans l'option {0}"
 
-#: tiramisu/option/baseoption.py:857
+#: tiramisu/option/baseoption.py:863
 msgid "malformed requirements option {0} must not be a multi for {1}"
 msgstr ""
 "requirements mal formés pour l'option {0} ne doit pas être une multi pour {1}"
 
-#: tiramisu/option/baseoption.py:864
+#: tiramisu/option/baseoption.py:870
 msgid ""
 "malformed requirements second argument must be valid for option {0}: {1}"
 msgstr ""
 "requirements mal formés deuxième argument doit être valide pour l'option "
 "{0} : {1}"
 
-#: tiramisu/option/baseoption.py:869
+#: tiramisu/option/baseoption.py:875
 msgid "inconsistency in action types for option: {0} action: {1}"
 msgstr "incohérence dans les types action pour l'option : {0} action {1}"
 
-#: tiramisu/option/baseoption.py:897
+#: tiramisu/option/baseoption.py:903
 msgid "malformed symlinkoption must be an option for symlink {0}"
 msgstr "symlinkoption mal formé, doit être une option pour symlink {0}"
 
@@ -406,172 +411,172 @@ msgstr "invalide caractère"
 msgid "invalid unicode"
 msgstr "invalide unicode"
 
-#: tiramisu/option/option.py:178 tiramisu/option/option.py:181
-#: tiramisu/option/option.py:186
+#: tiramisu/option/option.py:179 tiramisu/option/option.py:182
+#: tiramisu/option/option.py:187
 msgid "invalid IP"
 msgstr "adresse IP invalide"
 
-#: tiramisu/option/option.py:192
+#: tiramisu/option/option.py:193
 msgid "IP is in reserved class"
 msgstr "l'adresse IP est dans une plage d'adresse réservée"
 
-#: tiramisu/option/option.py:194
+#: tiramisu/option/option.py:195
 msgid "invalid IP, mustn't be in reserved class"
 msgstr "adresse IP invalide, ne doit pas être dans une classe réservée"
 
-#: tiramisu/option/option.py:198
+#: tiramisu/option/option.py:199
 msgid "IP is not in private class"
 msgstr "l'adresse IP n'est pas dans une plage d'adressage privée"
 
-#: tiramisu/option/option.py:200
+#: tiramisu/option/option.py:201
 msgid "invalid IP, must be in private class"
 msgstr "adresse IP invalide, doit être dans la classe privée"
 
-#: tiramisu/option/option.py:205 tiramisu/option/option.py:377
+#: tiramisu/option/option.py:206 tiramisu/option/option.py:384
 msgid "invalid len for vals"
 msgstr "longueur invalide pour vals"
 
-#: tiramisu/option/option.py:211
+#: tiramisu/option/option.py:212
 msgid "IP {0} ({1}) not in network {2} ({3}) with netmask {4} ({5})"
 msgstr "IP {0} ({1}) pas dans le réseau {2} ({3}) avec le masque {4} ({5})"
 
-#: tiramisu/option/option.py:214
+#: tiramisu/option/option.py:215
 msgid "invalid IP {0} ({1}) not in network {2} ({3}) with netmask {4} ({5})"
 msgstr ""
 "IP invalide {0} ({1}) pas dans le réseau {2} ({3}) avec le masque {4} ({5})"
 
-#: tiramisu/option/option.py:256
+#: tiramisu/option/option.py:257
 msgid "inconsistency in allowed range"
 msgstr "inconsistence dans la plage autorisée"
 
-#: tiramisu/option/option.py:261
+#: tiramisu/option/option.py:262
 msgid "max value is empty"
 msgstr "la valeur maximum est vide"
 
-#: tiramisu/option/option.py:279
+#: tiramisu/option/option.py:283
 msgid "invalid port, range must have two values only"
 msgstr "port invalide, une plage doit avoir deux valeurs seulement"
 
-#: tiramisu/option/option.py:282
+#: tiramisu/option/option.py:286
 msgid "invalid port, first port in range must be smaller than the second one"
 msgstr ""
 "port invalide, le premier port d'une plage doit être plus petit que le second"
 
-#: tiramisu/option/option.py:291
+#: tiramisu/option/option.py:295
 msgid "invalid port"
 msgstr "port invalide"
 
-#: tiramisu/option/option.py:293
+#: tiramisu/option/option.py:297
 msgid "invalid port, must be an integer between {0} and {1}"
 msgstr "port invalide, port doit être nombre entre {0} et {1}"
 
-#: tiramisu/option/option.py:306
+#: tiramisu/option/option.py:311
 msgid "invalid network address"
 msgstr "adresse réseau invalide"
 
-#: tiramisu/option/option.py:312
+#: tiramisu/option/option.py:317
 msgid "network address is in reserved class"
 msgstr "l'adresse réseau est pas dans une plage d'adresse réservée"
 
-#: tiramisu/option/option.py:314
+#: tiramisu/option/option.py:319
 msgid "invalid network address, mustn't be in reserved class"
 msgstr "adresse réseau invalide, ne doit pas être dans la classe réservée"
 
-#: tiramisu/option/option.py:326
+#: tiramisu/option/option.py:332
 msgid "invalid netmask address"
 msgstr "masque de sous-réseau invalide"
 
-#: tiramisu/option/option.py:343
+#: tiramisu/option/option.py:349
 msgid "invalid len for opts"
 msgstr "longueur invalide pour opts"
 
-#: tiramisu/option/option.py:352
+#: tiramisu/option/option.py:358
 msgid "invalid IP {0} ({1}) with netmask {2}, this IP is a network"
 msgstr "IP invalide {0} ({1}) avec masque {2}, cette IP est un réseau"
 
-#: tiramisu/option/option.py:355
+#: tiramisu/option/option.py:361
 msgid "invalid IP {0} ({1}) with netmask {2}, this IP is a broadcast"
 msgstr "IP invalide {0} ({1}) avec masque {2}, cette IP est un broadcast"
 
-#: tiramisu/option/option.py:360
+#: tiramisu/option/option.py:366
 msgid "invalid network {0} ({1}) with netmask {2}"
 msgstr "réseau invalide {0} ({1}) avec masque {2}"
 
-#: tiramisu/option/option.py:373
+#: tiramisu/option/option.py:380
 msgid "invalid broadcast address"
 msgstr "adresse de broadcast invalide"
 
-#: tiramisu/option/option.py:382
+#: tiramisu/option/option.py:389
 msgid ""
 "invalid broadcast {0} ({1}) with network {2} ({3}) and netmask {4} ({5})"
 msgstr ""
 "Broadcast invalide {0} ({1}) avec le réseau {2} ({3}) et le masque {4} ({5})"
 
-#: tiramisu/option/option.py:403
+#: tiramisu/option/option.py:410
 msgid "unknown type_ {0} for hostname"
 msgstr "type_ inconnu {0} pour le nom d'hôte"
 
-#: tiramisu/option/option.py:406
+#: tiramisu/option/option.py:413
 msgid "allow_ip must be a boolean"
 msgstr "allow_ip doit être un booléen"
 
-#: tiramisu/option/option.py:408
+#: tiramisu/option/option.py:415
 msgid "allow_without_dot must be a boolean"
 msgstr "allow_without_dot doit être un booléen"
 
-#: tiramisu/option/option.py:429
+#: tiramisu/option/option.py:437
 msgid "invalid domainname's length (min 2)"
 msgstr "longueur du nom de domaine invalide (minimum 2)"
 
-#: tiramisu/option/option.py:431
+#: tiramisu/option/option.py:439
 msgid "invalid domainname's length (max {0})"
 msgstr "longueur du nom de domaine invalide (maximum {0})"
 
-#: tiramisu/option/option.py:446
+#: tiramisu/option/option.py:454
 msgid "invalid domainname, must have dot"
 msgstr "nom de domaine invalide, doit avoir un point"
 
-#: tiramisu/option/option.py:448
+#: tiramisu/option/option.py:456
 msgid "invalid domainname's length (max 255)"
 msgstr "longueur du nom de domaine invalide (maximum {1})"
 
-#: tiramisu/option/option.py:457
+#: tiramisu/option/option.py:465
 msgid "some characters are uppercase"
 msgstr "des caractères sont en majuscule"
 
-#: tiramisu/option/option.py:460
+#: tiramisu/option/option.py:468
 msgid "some characters may cause problems"
 msgstr "des caractères peuvent poser problèmes"
 
-#: tiramisu/option/option.py:462
+#: tiramisu/option/option.py:470
 msgid "invalid domainname"
 msgstr "nom de domaine invalide"
 
-#: tiramisu/option/option.py:486
+#: tiramisu/option/option.py:495
 msgid "invalid email address, must contains one @"
 msgstr "adresse email invalide, doit contenir un @"
 
-#: tiramisu/option/option.py:489
+#: tiramisu/option/option.py:498
 msgid "invalid username in email address"
 msgstr "nom d'utilisateur invalide dans une adresse email"
 
-#: tiramisu/option/option.py:505
+#: tiramisu/option/option.py:515
 msgid "invalid url, must start with http:// or https://"
 msgstr "URL invalide, doit démarrer avec http:// ou https://"
 
-#: tiramisu/option/option.py:524
+#: tiramisu/option/option.py:534
 msgid "invalid url, port must be an between 0 and 65536"
 msgstr "URL invalide, port doit être entre 0 et 65536"
 
-#: tiramisu/option/option.py:531
+#: tiramisu/option/option.py:541
 msgid "invalid url, must ends with filename"
 msgstr "URL invalide, doit finir avec un nom de fichier"
 
-#: tiramisu/option/option.py:545
+#: tiramisu/option/option.py:556
 msgid "invalid username"
 msgstr "utilisateur invalide"
 
-#: tiramisu/option/option.py:555
+#: tiramisu/option/option.py:567
 msgid "invalid filename"
 msgstr "nom de fichier invalide"
 
@@ -620,55 +625,55 @@ msgstr "impossible de placer un symlinkoption dans un dynoptiondescription"
 msgid "callback is mandatory for dynoptiondescription"
 msgstr "callback est obligatoire pour un dynoptiondescription"
 
-#: tiramisu/setting.py:121
+#: tiramisu/setting.py:124
 msgid "can't rebind {0}"
 msgstr "ne peut redéfinir ({0})"
 
-#: tiramisu/setting.py:126
+#: tiramisu/setting.py:129
 msgid "can't unbind {0}"
 msgstr "ne peut supprimer ({0})"
 
-#: tiramisu/setting.py:254
+#: tiramisu/setting.py:257
 msgid "cannot append {0} property for option {1}: this property is calculated"
 msgstr ""
 "ne peut ajouter la propriété {0} dans l'option {1}: cette propriété est "
 "calculée"
 
-#: tiramisu/setting.py:343
+#: tiramisu/setting.py:346
 msgid "you should only append/remove properties"
 msgstr "pour pouvait seulement ajouter/supprimer des propriétés"
 
-#: tiramisu/setting.py:347
+#: tiramisu/setting.py:350
 msgid "opt and all_properties must not be set together in reset"
 msgstr "opt et all_properties ne doit pas être renseigné ensemble dans reset"
 
-#: tiramisu/setting.py:368
+#: tiramisu/setting.py:371
 msgid "if opt is not None, path should not be None in _getproperties"
 msgstr ""
 "si opt n'est pas None, path devrait ne pas être à None dans _getproperties"
 
-#: tiramisu/setting.py:412
+#: tiramisu/setting.py:415
 msgid "cannot add those properties: {0}"
 msgstr "ne peut pas ajouter ces propriétés : {0}"
 
-#: tiramisu/setting.py:477
+#: tiramisu/setting.py:480
 msgid "cannot change the value for option {0} this option is frozen"
 msgstr ""
 "ne peut modifier la valeur de l'option {0} cette option n'est pas modifiable"
 
-#: tiramisu/setting.py:483
+#: tiramisu/setting.py:486
 msgid "trying to access to an option named: {0} with properties {1}"
 msgstr "tentative d'accès à une option nommée : {0} avec les propriétés {1}"
 
-#: tiramisu/setting.py:501
+#: tiramisu/setting.py:504
 msgid "permissive must be a tuple"
 msgstr "permissive doit être un tuple"
 
-#: tiramisu/setting.py:508 tiramisu/value.py:437
+#: tiramisu/setting.py:511 tiramisu/value.py:442
 msgid "invalid generic owner {0}"
 msgstr "invalide owner générique {0}"
 
-#: tiramisu/setting.py:596
+#: tiramisu/setting.py:599
 msgid ""
 "malformed requirements imbrication detected for option: '{0}' with "
 "requirement on: '{1}'"
@@ -676,7 +681,7 @@ msgstr ""
 "imbrication de requirements mal formés detectée pour l'option : '{0}' avec "
 "requirement sur : '{1}'"
 
-#: tiramisu/setting.py:607
+#: tiramisu/setting.py:610
 msgid "option '{0}' has requirement's property error: {1} {2}"
 msgstr "l'option '{0}' a une erreur de propriété pour le requirement : {1} {2}"
 
@@ -701,7 +706,7 @@ msgid "invalid default_multi value {0} for option {1}: {2}"
 msgstr "la valeur default_multi est invalide {0} pour l'option {1} : {2}"
 
 #: tiramisu/storage/dictionary/option.py:138
-#: tiramisu/storage/sqlalchemy/option.py:431 tiramisu/value.py:501
+#: tiramisu/storage/sqlalchemy/option.py:431 tiramisu/value.py:506
 msgid "information's item not found: {0}"
 msgstr "aucune config spécifiée alors que c'est nécessaire"
 
@@ -751,52 +756,52 @@ msgstr "un espace de stockage dictionary ne peut être persistant"
 msgid "optiondescription has no value"
 msgstr "une optiondescription n'a pas de valeur"
 
-#: tiramisu/value.py:329
+#: tiramisu/value.py:334
 msgid "you should only set value with config"
 msgstr "vous devez seul affecter une valeur avec un config"
 
-#: tiramisu/value.py:406
+#: tiramisu/value.py:411
 msgid "owner only avalaible for an option"
 msgstr "owner seulement possible pour une option"
 
-#: tiramisu/value.py:444
+#: tiramisu/value.py:449
 msgid "no value for {0} cannot change owner to {1}"
 msgstr "pas de valeur pour {0} ne peut changer d'utilisateur pour {1}"
 
-#: tiramisu/value.py:542
+#: tiramisu/value.py:547
 msgid "can force cache only if cache is actived in config"
 msgstr ""
 "peut force la mise en cache seulement si le cache est activé dans la config"
 
-#: tiramisu/value.py:581
+#: tiramisu/value.py:586
 msgid "{0} is already a Multi "
 msgstr "{0} est déjà une Multi"
 
-#: tiramisu/value.py:651
+#: tiramisu/value.py:656
 msgid "cannot append a value on a multi option {0} which is a slave"
 msgstr "ne peut ajouter une valeur sur l'option multi {0} qui est une esclave"
 
-#: tiramisu/value.py:675
+#: tiramisu/value.py:680
 msgid "cannot sort multi option {0} if master or slave"
 msgstr "ne peut trier une option multi {0} pour une maître ou une esclave"
 
-#: tiramisu/value.py:679
+#: tiramisu/value.py:684
 msgid "cmp is not permitted in python v3 or greater"
 msgstr "cmp n'est pas permis en python v3 ou supérieure"
 
-#: tiramisu/value.py:688
+#: tiramisu/value.py:693
 msgid "cannot reverse multi option {0} if master or slave"
 msgstr "ne peut inverser une option multi {0} pour une maître ou une esclave"
 
-#: tiramisu/value.py:696
+#: tiramisu/value.py:701
 msgid "cannot insert multi option {0} if master or slave"
 msgstr "ne peut insérer une option multi {0} pour une maître ou une esclave"
 
-#: tiramisu/value.py:709
+#: tiramisu/value.py:714
 msgid "cannot extend multi option {0} if master or slave"
 msgstr "ne peut étendre une option multi {0} pour une maître ou une esclave"
 
-#: tiramisu/value.py:741
+#: tiramisu/value.py:746
 msgid "cannot pop a value on a multi option {0} which is a slave"
 msgstr "ne peut supprimer une valeur dans l'option multi {0} qui est esclave"
 
index e124107..8ca877e 100644 (file)
@@ -5,7 +5,7 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2015-04-18 22:40+CEST\n"
+"POT-Creation-Date: 2015-04-18 23:52+CEST\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -27,8 +27,8 @@ msgstr ""
 msgid "unknown group_type: {0}"
 msgstr ""
 
-#: tiramisu/config.py:181 tiramisu/setting.py:320 tiramisu/value.py:54
-#: tiramisu/value.py:616
+#: tiramisu/config.py:181 tiramisu/setting.py:323 tiramisu/value.py:54
+#: tiramisu/value.py:621
 msgid "the context does not exist anymore"
 msgstr ""
 
@@ -172,127 +172,131 @@ msgstr ""
 msgid "'{0}' ({1}) object attribute '{2}' is read-only"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:545 tiramisu/option/baseoption.py:588
+#: tiramisu/option/baseoption.py:392
+msgid "invalid unicode or string"
+msgstr ""
+
+#: tiramisu/option/baseoption.py:549 tiramisu/option/baseoption.py:594
 msgid "invalid value for option {0}: {1}"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:558
+#: tiramisu/option/baseoption.py:562
 msgid "do_validation for {0}: error in value"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:564
+#: tiramisu/option/baseoption.py:568
 msgid "do_validation for {0}: warning in value"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:574
+#: tiramisu/option/baseoption.py:578
 msgid "do_validation for {0}: error in consistency"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:578
+#: tiramisu/option/baseoption.py:582
 msgid "do_validation for {0}: warning in consistency"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:582
+#: tiramisu/option/baseoption.py:586
 msgid "warning on the value of the option {0}: {1}"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:600 tiramisu/option/baseoption.py:609
+#: tiramisu/option/baseoption.py:606 tiramisu/option/baseoption.py:615
 msgid "invalid value {0} for option {1} which must be a list"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:615
+#: tiramisu/option/baseoption.py:621
 msgid "invalid value {0} for option {1} which must be a list of list"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:668
+#: tiramisu/option/baseoption.py:674
 msgid "'{0}' ({1}) cannot add consistency, option is read-only"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:680
+#: tiramisu/option/baseoption.py:686
 msgid "unknow parameter {0} in consistency"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:687
+#: tiramisu/option/baseoption.py:693
 msgid "consistency must be set with an option"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:690 tiramisu/option/baseoption.py:697
+#: tiramisu/option/baseoption.py:696 tiramisu/option/baseoption.py:703
 msgid "almost one option in consistency is in a dynoptiondescription but not all"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:693
+#: tiramisu/option/baseoption.py:699
 msgid "option in consistency must be in same dynoptiondescription"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:700
+#: tiramisu/option/baseoption.py:706
 msgid "cannot add consistency with itself"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:702
+#: tiramisu/option/baseoption.py:708
 msgid "every options in consistency must be multi or none"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:706
+#: tiramisu/option/baseoption.py:712
 msgid "consistency {0} not available for this option"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:735
+#: tiramisu/option/baseoption.py:741
 msgid "same value for {0} and {1}, should be different"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:737
+#: tiramisu/option/baseoption.py:743
 msgid "same value for {0} and {1}, must be different"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:794
+#: tiramisu/option/baseoption.py:800
 msgid "default value not allowed if option: {0} is calculated"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:816
+#: tiramisu/option/baseoption.py:822
 msgid "malformed requirements type for option: {0}, must be a dict"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:822
+#: tiramisu/option/baseoption.py:828
 msgid "malformed requirements for option: {0} unknown keys {1}, must only {2}"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:833
+#: tiramisu/option/baseoption.py:839
 msgid "malformed requirements for option: {0} require must have option, expected and action keys"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:837
+#: tiramisu/option/baseoption.py:843
 msgid "malformed requirements for option: {0} action cannot be force_store_value"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:842
+#: tiramisu/option/baseoption.py:848
 msgid "malformed requirements for option: {0} inverse must be boolean"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:846
+#: tiramisu/option/baseoption.py:852
 msgid "malformed requirements for option: {0} transitive must be boolean"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:850
+#: tiramisu/option/baseoption.py:856
 msgid "malformed requirements for option: {0} same_action must be boolean"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:854
+#: tiramisu/option/baseoption.py:860
 msgid "malformed requirements must be an option in option {0}"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:857
+#: tiramisu/option/baseoption.py:863
 msgid "malformed requirements option {0} must not be a multi for {1}"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:864
+#: tiramisu/option/baseoption.py:870
 msgid "malformed requirements second argument must be valid for option {0}: {1}"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:869
+#: tiramisu/option/baseoption.py:875
 msgid "inconsistency in action types for option: {0} action: {1}"
 msgstr ""
 
-#: tiramisu/option/baseoption.py:897
+#: tiramisu/option/baseoption.py:903
 msgid "malformed symlinkoption must be an option for symlink {0}"
 msgstr ""
 
@@ -356,168 +360,168 @@ msgstr ""
 msgid "invalid unicode"
 msgstr ""
 
-#: tiramisu/option/option.py:178 tiramisu/option/option.py:181
-#: tiramisu/option/option.py:186
+#: tiramisu/option/option.py:179 tiramisu/option/option.py:182
+#: tiramisu/option/option.py:187
 msgid "invalid IP"
 msgstr ""
 
-#: tiramisu/option/option.py:192
+#: tiramisu/option/option.py:193
 msgid "IP is in reserved class"
 msgstr ""
 
-#: tiramisu/option/option.py:194
+#: tiramisu/option/option.py:195
 msgid "invalid IP, mustn't be in reserved class"
 msgstr ""
 
-#: tiramisu/option/option.py:198
+#: tiramisu/option/option.py:199
 msgid "IP is not in private class"
 msgstr ""
 
-#: tiramisu/option/option.py:200
+#: tiramisu/option/option.py:201
 msgid "invalid IP, must be in private class"
 msgstr ""
 
-#: tiramisu/option/option.py:205 tiramisu/option/option.py:377
+#: tiramisu/option/option.py:206 tiramisu/option/option.py:384
 msgid "invalid len for vals"
 msgstr ""
 
-#: tiramisu/option/option.py:211
+#: tiramisu/option/option.py:212
 msgid "IP {0} ({1}) not in network {2} ({3}) with netmask {4} ({5})"
 msgstr ""
 
-#: tiramisu/option/option.py:214
+#: tiramisu/option/option.py:215
 msgid "invalid IP {0} ({1}) not in network {2} ({3}) with netmask {4} ({5})"
 msgstr ""
 
-#: tiramisu/option/option.py:256
+#: tiramisu/option/option.py:257
 msgid "inconsistency in allowed range"
 msgstr ""
 
-#: tiramisu/option/option.py:261
+#: tiramisu/option/option.py:262
 msgid "max value is empty"
 msgstr ""
 
-#: tiramisu/option/option.py:279
+#: tiramisu/option/option.py:283
 msgid "invalid port, range must have two values only"
 msgstr ""
 
-#: tiramisu/option/option.py:282
+#: tiramisu/option/option.py:286
 msgid "invalid port, first port in range must be smaller than the second one"
 msgstr ""
 
-#: tiramisu/option/option.py:291
+#: tiramisu/option/option.py:295
 msgid "invalid port"
 msgstr ""
 
-#: tiramisu/option/option.py:293
+#: tiramisu/option/option.py:297
 msgid "invalid port, must be an integer between {0} and {1}"
 msgstr ""
 
-#: tiramisu/option/option.py:306
+#: tiramisu/option/option.py:311
 msgid "invalid network address"
 msgstr ""
 
-#: tiramisu/option/option.py:312
+#: tiramisu/option/option.py:317
 msgid "network address is in reserved class"
 msgstr ""
 
-#: tiramisu/option/option.py:314
+#: tiramisu/option/option.py:319
 msgid "invalid network address, mustn't be in reserved class"
 msgstr ""
 
-#: tiramisu/option/option.py:326
+#: tiramisu/option/option.py:332
 msgid "invalid netmask address"
 msgstr ""
 
-#: tiramisu/option/option.py:343
+#: tiramisu/option/option.py:349
 msgid "invalid len for opts"
 msgstr ""
 
-#: tiramisu/option/option.py:352
+#: tiramisu/option/option.py:358
 msgid "invalid IP {0} ({1}) with netmask {2}, this IP is a network"
 msgstr ""
 
-#: tiramisu/option/option.py:355
+#: tiramisu/option/option.py:361
 msgid "invalid IP {0} ({1}) with netmask {2}, this IP is a broadcast"
 msgstr ""
 
-#: tiramisu/option/option.py:360
+#: tiramisu/option/option.py:366
 msgid "invalid network {0} ({1}) with netmask {2}"
 msgstr ""
 
-#: tiramisu/option/option.py:373
+#: tiramisu/option/option.py:380
 msgid "invalid broadcast address"
 msgstr ""
 
-#: tiramisu/option/option.py:382
+#: tiramisu/option/option.py:389
 msgid "invalid broadcast {0} ({1}) with network {2} ({3}) and netmask {4} ({5})"
 msgstr ""
 
-#: tiramisu/option/option.py:403
+#: tiramisu/option/option.py:410
 msgid "unknown type_ {0} for hostname"
 msgstr ""
 
-#: tiramisu/option/option.py:406
+#: tiramisu/option/option.py:413
 msgid "allow_ip must be a boolean"
 msgstr ""
 
-#: tiramisu/option/option.py:408
+#: tiramisu/option/option.py:415
 msgid "allow_without_dot must be a boolean"
 msgstr ""
 
-#: tiramisu/option/option.py:429
+#: tiramisu/option/option.py:437
 msgid "invalid domainname's length (min 2)"
 msgstr ""
 
-#: tiramisu/option/option.py:431
+#: tiramisu/option/option.py:439
 msgid "invalid domainname's length (max {0})"
 msgstr ""
 
-#: tiramisu/option/option.py:446
+#: tiramisu/option/option.py:454
 msgid "invalid domainname, must have dot"
 msgstr ""
 
-#: tiramisu/option/option.py:448
+#: tiramisu/option/option.py:456
 msgid "invalid domainname's length (max 255)"
 msgstr ""
 
-#: tiramisu/option/option.py:457
+#: tiramisu/option/option.py:465
 msgid "some characters are uppercase"
 msgstr ""
 
-#: tiramisu/option/option.py:460
+#: tiramisu/option/option.py:468
 msgid "some characters may cause problems"
 msgstr ""
 
-#: tiramisu/option/option.py:462
+#: tiramisu/option/option.py:470
 msgid "invalid domainname"
 msgstr ""
 
-#: tiramisu/option/option.py:486
+#: tiramisu/option/option.py:495
 msgid "invalid email address, must contains one @"
 msgstr ""
 
-#: tiramisu/option/option.py:489
+#: tiramisu/option/option.py:498
 msgid "invalid username in email address"
 msgstr ""
 
-#: tiramisu/option/option.py:505
+#: tiramisu/option/option.py:515
 msgid "invalid url, must start with http:// or https://"
 msgstr ""
 
-#: tiramisu/option/option.py:524
+#: tiramisu/option/option.py:534
 msgid "invalid url, port must be an between 0 and 65536"
 msgstr ""
 
-#: tiramisu/option/option.py:531
+#: tiramisu/option/option.py:541
 msgid "invalid url, must ends with filename"
 msgstr ""
 
-#: tiramisu/option/option.py:545
+#: tiramisu/option/option.py:556
 msgid "invalid username"
 msgstr ""
 
-#: tiramisu/option/option.py:555
+#: tiramisu/option/option.py:567
 msgid "invalid filename"
 msgstr ""
 
@@ -565,55 +569,55 @@ msgstr ""
 msgid "callback is mandatory for dynoptiondescription"
 msgstr ""
 
-#: tiramisu/setting.py:121
+#: tiramisu/setting.py:124
 msgid "can't rebind {0}"
 msgstr ""
 
-#: tiramisu/setting.py:126
+#: tiramisu/setting.py:129
 msgid "can't unbind {0}"
 msgstr ""
 
-#: tiramisu/setting.py:254
+#: tiramisu/setting.py:257
 msgid "cannot append {0} property for option {1}: this property is calculated"
 msgstr ""
 
-#: tiramisu/setting.py:343
+#: tiramisu/setting.py:346
 msgid "you should only append/remove properties"
 msgstr ""
 
-#: tiramisu/setting.py:347
+#: tiramisu/setting.py:350
 msgid "opt and all_properties must not be set together in reset"
 msgstr ""
 
-#: tiramisu/setting.py:368
+#: tiramisu/setting.py:371
 msgid "if opt is not None, path should not be None in _getproperties"
 msgstr ""
 
-#: tiramisu/setting.py:412
+#: tiramisu/setting.py:415
 msgid "cannot add those properties: {0}"
 msgstr ""
 
-#: tiramisu/setting.py:477
+#: tiramisu/setting.py:480
 msgid "cannot change the value for option {0} this option is frozen"
 msgstr ""
 
-#: tiramisu/setting.py:483
+#: tiramisu/setting.py:486
 msgid "trying to access to an option named: {0} with properties {1}"
 msgstr ""
 
-#: tiramisu/setting.py:501
+#: tiramisu/setting.py:504
 msgid "permissive must be a tuple"
 msgstr ""
 
-#: tiramisu/setting.py:508 tiramisu/value.py:437
+#: tiramisu/setting.py:511 tiramisu/value.py:442
 msgid "invalid generic owner {0}"
 msgstr ""
 
-#: tiramisu/setting.py:596
+#: tiramisu/setting.py:599
 msgid "malformed requirements imbrication detected for option: '{0}' with requirement on: '{1}'"
 msgstr ""
 
-#: tiramisu/setting.py:607
+#: tiramisu/setting.py:610
 msgid "option '{0}' has requirement's property error: {1} {2}"
 msgstr ""
 
@@ -638,7 +642,7 @@ msgid "invalid default_multi value {0} for option {1}: {2}"
 msgstr ""
 
 #: tiramisu/storage/dictionary/option.py:138
-#: tiramisu/storage/sqlalchemy/option.py:431 tiramisu/value.py:501
+#: tiramisu/storage/sqlalchemy/option.py:431 tiramisu/value.py:506
 msgid "information's item not found: {0}"
 msgstr ""
 
@@ -687,51 +691,51 @@ msgstr ""
 msgid "optiondescription has no value"
 msgstr ""
 
-#: tiramisu/value.py:329
+#: tiramisu/value.py:334
 msgid "you should only set value with config"
 msgstr ""
 
-#: tiramisu/value.py:406
+#: tiramisu/value.py:411
 msgid "owner only avalaible for an option"
 msgstr ""
 
-#: tiramisu/value.py:444
+#: tiramisu/value.py:449
 msgid "no value for {0} cannot change owner to {1}"
 msgstr ""
 
-#: tiramisu/value.py:542
+#: tiramisu/value.py:547
 msgid "can force cache only if cache is actived in config"
 msgstr ""
 
-#: tiramisu/value.py:581
+#: tiramisu/value.py:586
 msgid "{0} is already a Multi "
 msgstr ""
 
-#: tiramisu/value.py:651
+#: tiramisu/value.py:656
 msgid "cannot append a value on a multi option {0} which is a slave"
 msgstr ""
 
-#: tiramisu/value.py:675
+#: tiramisu/value.py:680
 msgid "cannot sort multi option {0} if master or slave"
 msgstr ""
 
-#: tiramisu/value.py:679
+#: tiramisu/value.py:684
 msgid "cmp is not permitted in python v3 or greater"
 msgstr ""
 
-#: tiramisu/value.py:688
+#: tiramisu/value.py:693
 msgid "cannot reverse multi option {0} if master or slave"
 msgstr ""
 
-#: tiramisu/value.py:696
+#: tiramisu/value.py:701
 msgid "cannot insert multi option {0} if master or slave"
 msgstr ""
 
-#: tiramisu/value.py:709
+#: tiramisu/value.py:714
 msgid "cannot extend multi option {0} if master or slave"
 msgstr ""
 
-#: tiramisu/value.py:741
+#: tiramisu/value.py:746
 msgid "cannot pop a value on a multi option {0} which is a slave"
 msgstr ""