2 # Copyright (C) 2007-2013 EDF R&D
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License.
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # Lesser General Public License for more details.
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 Ce module contient toutes les classes necessaires pour
22 implanter le concept de validateur dans Accas
27 from N_ASSD import ASSD
28 from N_types import is_int, is_float_or_int, is_complex, is_number, is_str, is_sequence
29 from strfunc import convert, ufmt
32 class ValError(Exception):
37 if hasattr(cls, "__mro__"):
40 for base in cls.__bases__:
41 mro.extend(cls_mro(base))
47 def __init__(self, name):
52 def register(self, T, A):
56 # (a) verifier si l'objet peut s'adapter au protocole
57 adapt = getattr(obj, '__adapt__', None)
59 # on demande à l'objet obj de réaliser lui-meme l'adaptation
62 # (b) verifier si un adapteur est enregistré (si oui l'utiliser)
64 for T in cls_mro(obj.__class__):
65 if T in self.registry:
66 return self.registry[T](obj, self, **self.args)
68 # (c) utiliser l'adapteur par defaut
69 return self.default(obj, **self.args)
71 def default(self, obj, **args):
72 raise TypeError("Can't adapt %s to %s" %
73 (obj.__class__.__name__, self.name))
76 class PProtocol(Protocol):
78 """Verificateur de protocole paramétré (classe de base)"""
79 # Protocole paramétré. Le registre est unique pour toutes les instances.
80 # La methode register est une methode de classe
83 def __init__(self, name, **args):
87 def register(cls, T, A):
89 register = classmethod(register)
92 class ListProtocol(Protocol):
94 """Verificateur de protocole liste : convertit un objet quelconque en liste pour validation ultérieure"""
96 def default(self, obj):
97 if type(obj) is tuple:
98 if len(obj) > 0 and obj[0] in ('RI', 'MP'):
99 # il s'agit d'un complexe ancienne mode. La cardinalite vaut 1
103 elif type(obj) is list:
106 # pas de valeur affecte. La cardinalite vaut 0
109 # il s'agit d'une chaine. La cardinalite vaut 1
113 # si l'objet supporte len, on a la cardinalite
120 listProto = ListProtocol("list")
123 class TypeProtocol(PProtocol):
125 """Verificateur de type parmi une liste de types possibles"""
126 # pas de registre par instance. Registre unique pour toutes les instances
130 def __init__(self, name, typ=None):
131 PProtocol.__init__(self, name, typ=typ)
134 def default(self, obj, typ):
137 for type_permis in typ:
138 if type_permis == 'R':
139 if is_float_or_int(obj):
141 elif type_permis == 'I':
144 elif type_permis == 'C':
145 if self.is_complexe(obj):
147 elif type_permis == 'TXM':
150 elif type_permis == 'shell':
153 elif type_permis == 'Fichier':
155 if (len(typ) > 2 and typ[2] == "Sauvegarde") or os.path.isfile(obj):
159 ufmt(_(u"%s n'est pas un fichier valide"), repr(obj)))
160 elif type_permis == 'FichierNoAbs':
162 if (len(typ) > 2 and typ[2] == "Sauvegarde") or isinstance(obj, type("")):
166 ufmt(_(u"%s n'est pas un fichier valide"), repr(obj)))
167 elif type_permis == 'Repertoire':
169 if os.path.isdir(obj):
173 ufmt(_(u"%s n'est pas un répertoire valide"), repr(obj)))
174 elif type(type_permis) == types.ClassType or isinstance(type_permis, type):
176 if self.is_object_from(obj, type_permis):
178 except Exception, err:
180 elif type(type_permis) == types.InstanceType or isinstance(type_permis, object):
182 if type_permis.__convert__(obj):
184 except Exception, err:
187 print convert(ufmt(_(u"Type non encore géré %s"), `type_permis`))
189 ufmt(_(u"%s (de type %s) n'est pas d'un type autorisé: %s %s"),
190 repr(obj), type(obj), typ, unicode(err)))
192 def is_complexe(self, valeur):
193 """ Retourne 1 si valeur est un complexe, 0 sinon """
194 if is_number(valeur):
195 # Pour permettre l'utilisation de complexes Python (accepte les
198 elif type(valeur) != tuple:
199 # On n'autorise pas les listes pour les complexes
201 elif len(valeur) != 3:
204 # Un complexe doit etre un tuple de longueur 3 avec 'RI' ou 'MP' comme premiere
205 # valeur suivie de 2 reels.
206 if valeur[0].strip() in ('RI', 'MP'):
208 v1 = reelProto.adapt(valeur[1]), reelProto.adapt(valeur[2])
215 def is_object_from(self, objet, classe):
217 Retourne 1 si objet est une instance de la classe classe, 0 sinon
219 convert = getattr(classe, '__convert__', None)
220 if convert is not None:
221 # classe verifie les valeurs
225 except ValueError, err:
229 # On accepte les instances de la classe et des classes derivees
230 return isinstance(objet, classe)
232 reelProto = TypeProtocol("reel", typ=('R',))
235 class CardProtocol(PProtocol):
237 """Verificateur de cardinalité """
238 # pas de registre par instance. Registre unique pour toutes les instances
241 def __init__(self, name, min=1, max=1):
242 PProtocol.__init__(self, name, min=min, max=max)
244 def default(self, obj, min, max):
246 if length < min or length > max:
249 _(u"Nombre d'arguments de %s incorrect (min = %s, max = %s)"),
250 repr(obj), min, max))
254 class IntoProtocol(PProtocol):
256 """Verificateur de choix possibles : liste discrète ou intervalle"""
257 # pas de registre par instance. Registre unique pour toutes les instances
260 def __init__(self, name, into=None, val_min='**', val_max='**'):
262 self, name, into=into, val_min=val_min, val_max=val_max)
263 self.val_min = val_min
264 self.val_max = val_max
266 def default(self, obj, into, val_min, val_max):
271 _(u"La valeur : %s ne fait pas partie des choix possibles %s"),
274 # on est dans le cas d'un ensemble continu de valeurs possibles
276 if is_float_or_int(obj):
281 if obj < val_min or obj > val_max:
284 _(u"La valeur : %s est en dehors du domaine de validité [ %s , %s ]"),
285 repr(obj), self.val_min, self.val_max))
290 # exemple de classe pour verificateur de type
291 # on utilise des instances de classe comme type (typ=MinStr(3,6), par
294 def __init__(self, min, max):
298 def __convert__(self, valeur):
299 if is_str(valeur) and self.min <= len(valeur) <= self.max:
303 _(u"%s n'est pas une chaine de longueur comprise entre %s et %s"),
304 valeur, self.min, self.max))
307 return ufmt(_(u"TXM de longueur entre %s et %s"), self.min, self.max)
310 class Valid(PProtocol):
313 Cette classe est la classe mere des validateurs Accas
314 Elle doit etre derivee
315 Elle presente la signature des methodes indispensables pour son bon
316 fonctionnement et dans certains cas leur comportement par défaut.
318 @ivar cata_info: raison de la validite ou de l'invalidite du validateur meme
319 @type cata_info: C{string}
323 def __init__(self, **args):
324 PProtocol.__init__(self, "valid", **args)
328 Cette methode retourne une chaine de caractères informative sur
329 la validation demandée par le validateur. Elle est utilisée
330 pour produire le compte-rendu de validité du mot clé associé.
332 return _(u"valeur valide")
336 Cette methode retourne une chaine de caractère qui permet
337 de construire un message d'aide en ligne.
338 En général, le message retourné est le meme que celui retourné par la
343 def info_erreur_item(self):
345 Cette méthode permet d'avoir un message d'erreur pour un item
346 dans une liste dans le cas ou le validateur fait des vérifications
347 sur les items d'une liste. Si le validateur fait seulement des
348 vérifications sur la liste elle meme et non sur ses items, la méthode
349 doit retourner une chaine vide.
353 def info_erreur_liste(self):
355 Cette méthode a un comportement complémentaire de celui de
356 info_erreur_item. Elle retourne un message d'erreur lié uniquement
357 aux vérifications sur la liste elle meme et pas sur ses items.
358 Dans le cas où le validateur ne fait pas de vérification sur des
359 listes, elle retourne une chaine vide
363 def verif(self, valeur):
365 Cette methode sert a verifier si la valeur passee en argument est consideree
366 comme valide ou non par le validateur. Dans le premier cas le validateur retourne 1
367 (valide) sinon 0 (invalide).
369 @type valeur: tout type python
370 @param valeur: valeur du mot cle a valider
372 @return: indicateur de validite 1 (valide) ou 0 (invalide)
374 raise NotImplementedError("Must be implemented")
376 def verif_item(self, valeur):
378 La methode verif du validateur effectue une validation complete de
379 la valeur. valeur peut etre un scalaire ou une liste. Le validateur
380 doit traiter les 2 aspects s'il accepte des listes (dans ce cas la
381 methode is_list doit retourner 1).
382 La methode valid_item sert pour effectuer des validations partielles
383 de liste. Elle doit uniquement verifier la validite d'un item de
384 liste mais pas les caracteristiques de la liste.
388 def valide_liste_partielle(self, liste_courante):
390 Cette methode retourne un entier qui indique si liste_courante est partiellement valide (valeur 1)
391 ou invalide (valeur 0). La validation partielle concerne les listes en cours de construction : on
392 veut savoir si la liste en construction peut etre complétée ou si elle peut déjà etre considérée
394 En général un validateur effectue la meme validation pour les listes partielles et les
397 return self.verif(liste_courante)
399 def verif_cata(self):
401 Cette methode sert a realiser des verifications du validateur lui meme.
402 Elle est facultative et retourne 1 (valide) par defaut.
403 Elle retourne 0 si le validateur est lui meme invalide si par exemple ses
404 parametres de definition ne sont pas corrects.
405 La raison de l'invalidite est stockee dans l'attribut cata_info.
408 @return: indicateur de validite 1 (valide) ou 0 (invalide)
414 Cette méthode retourne un entier qui indique si le validateur
415 permet les listes (valeur 1) ou ne les permet pas (valeur 0).
416 Par défaut, un validateur n'autorise que des scalaires.
422 Cette méthode retourne un entier qui indique si le validateur
423 propose une liste de choix (valeur 1) ou n'en propose pas.
424 Par défaut, un validateur n'en propose pas.
428 def get_into(self, liste_courante=None, into_courant=None):
430 Cette méthode retourne la liste de choix proposée par le validateur.
431 Si le validateur ne propose pas de liste de choix, la méthode
433 L'argument d'entrée liste_courante, s'il est différent de None, donne
434 la liste des choix déjà effectués par l'utilisateur. Dans ce cas, la
435 méthode get_into doit calculer la liste des choix en en tenant
436 compte. Par exemple, si le validateur n'autorise pas les répétitions,
437 la liste des choix retournée ne doit pas contenir les choix déjà
438 contenus dans liste_courante.
439 L'argument d'entrée into_courant, s'il est différent de None, donne
440 la liste des choix proposés par d'autres validateurs. Dans ce cas,
441 la méthode get_into doit calculer la liste des choix à retourner
442 en se limitant à cette liste initiale. Par exemple, si into_courant
443 vaut (1,2,3) et que le validateur propose la liste de choix (3,4,5),
444 la méthode ne doit retourner que (3,).
446 La méthode get_into peut retourner une liste vide [], ce qui veut
447 dire qu'il n'y a pas (ou plus) de choix possible. Cette situation
448 peut etre normale : l''utilisateur a utilisé tous les choix, ou
449 résulter d'une incohérence des validateurs :
450 choix parmi (1,2,3) ET choix parmi (4,5,6). Il est impossible de
451 faire la différence entre ces deux situations.
456 class ListVal(Valid):
459 Cette classe sert de classe mère pour tous les validateurs qui acceptent
466 def get_into(self, liste_courante=None, into_courant=None):
468 Cette méthode get_into effectue un traitement général qui consiste
469 a filtrer la liste de choix into_courant, si elle existe, en ne
470 conservant que les valeurs valides (appel de la méthode valid).
472 if into_courant is None:
476 for e in into_courant:
478 liste_choix.append(e)
481 def convert(self, valeur):
483 Méthode convert pour les validateurs de listes. Cette méthode
484 fait appel à la méthode convert_item sur chaque élément de la
487 if is_sequence(valeur):
489 self.convert_item(val)
492 return self.convert_item(valeur)
494 def verif(self, valeur):
496 Méthode verif pour les validateurs de listes. Cette méthode
497 fait appel à la méthode verif_item sur chaque élément de la
498 liste. Si valeur est un paramètre, on utilise sa valeur effective
501 if is_sequence(valeur):
503 if not self.verif_item(val):
507 return self.verif_item(valeur)
510 class Compulsory(ListVal):
513 Validateur operationnel
514 Verification de la présence obligatoire d'un élément dans une liste
518 def __init__(self, elem=()):
519 if not is_sequence(elem):
521 Valid.__init__(self, elem=elem)
526 return ufmt(_(u"valeur %s obligatoire"), `self.elem`)
528 def default(self, valeur, elem):
531 def verif_item(self, valeur):
534 def convert(self, valeur):
535 elem = list(self.elem)
542 ufmt(_(u"%s ne contient pas les elements obligatoires : %s "),
549 def verif(self, valeur):
550 if not is_sequence(valeur):
554 for val in self.elem:
559 def info_erreur_item(self):
560 return _(u"La valeur n'est pas dans la liste des choix possibles")
563 class NoRepeat(ListVal):
566 Validateur operationnel
567 Verification d'absence de doublons dans la liste.
575 return _(u": pas de présence de doublon dans la liste")
577 def info_erreur_liste(self):
578 return _(u"Les doublons ne sont pas permis")
580 def default(self, valeur):
581 if valeur in self.liste:
582 raise ValError(ufmt(_(u"%s est un doublon"), valeur))
585 def convert(self, valeur):
592 def verif_item(self, valeur):
595 def verif(self, valeur):
596 if is_sequence(valeur):
599 if liste.count(val) != 1:
605 def get_into(self, liste_courante=None, into_courant=None):
607 Methode get_into spécifique pour validateur NoRepeat, on retourne
608 une liste de choix qui ne contient aucune valeur de into_courant
609 déjà contenue dans liste_courante
611 if into_courant is None:
615 for e in into_courant:
618 if liste_courante is not None and e in liste_courante:
620 liste_choix.append(e)
624 class LongStr(ListVal):
627 Validateur operationnel
628 Verification de la longueur d une chaine
631 def __init__(self, low, high):
632 ListVal.__init__(self, low=low, high=high)
638 return ufmt(_(u"longueur de la chaine entre %s et %s"), self.low, self.high)
640 def info_erreur_item(self):
641 return _(u"Longueur de la chaine incorrecte")
643 def convert(self, valeur):
648 def verif_item(self, valeur):
655 def default(self, valeur, low, high):
656 if not is_str(valeur):
657 raise ValError(ufmt(_(u"%s n'est pas une chaine"), repr(valeur)))
658 if valeur[0] == "'" and valeur[-1] == "'":
661 if len(valeur) < low or len(valeur) > high:
663 ufmt(_(u"%s n'est pas de la bonne longueur"), repr(valeur)))
667 class OnlyStr(ListVal):
670 Validateur operationnel
671 Valide que c'est une chaine
675 ListVal.__init__(self)
679 return _(u"regarde si c'est une chaine")
681 def info_erreur_item(self):
682 return _(u"Ce n'est pas une chaine")
684 def convert(self, valeur):
689 def verif_item(self, valeur):
696 def default(self, valeur):
697 if not is_str(valeur):
698 raise ValError(ufmt(_(u"%s n'est pas une chaine"), repr(valeur)))
702 class OrdList(ListVal):
705 Validateur operationnel
706 Verification qu'une liste est croissante ou decroissante
709 def __init__(self, ord):
710 ListVal.__init__(self, ord=ord)
715 return ufmt(_(u"liste %s"), self.ord)
717 def info_erreur_liste(self):
718 return ufmt(_(u"La liste doit etre en ordre %s"), self.ord)
720 def convert(self, valeur):
727 def default(self, valeur, ord):
728 if self.ord == 'croissant':
729 if self.val is not None and valeur < self.val:
731 ufmt(_(u"%s n'est pas par valeurs croissantes"), repr(self.liste)))
732 elif self.ord == 'decroissant':
733 if self.val is not None and valeur > self.val:
735 ufmt(_(u"%s n'est pas par valeurs decroissantes"), repr(self.liste)))
739 def verif_item(self, valeur):
742 def get_into(self, liste_courante=None, into_courant=None):
744 Methode get_into spécifique pour validateur OrdList, on retourne
745 une liste de choix qui ne contient aucune valeur de into_courant
746 dont la valeur est inférieure à la dernière valeur de
747 liste_courante, si elle est différente de None.
749 if into_courant is None:
751 elif not liste_courante:
755 last_val = liste_choix[-1]
756 for e in into_courant:
757 if self.ord == 'croissant' and e <= last_val:
759 if self.ord == 'decroissant' and e >= last_val:
761 liste_choix.append(e)
768 Validateur operationnel
769 Cette classe est un validateur qui controle une liste de validateurs
770 Elle verifie qu'au moins un des validateurs de la liste valide la valeur
773 def __init__(self, validators=()):
774 if not is_sequence(validators):
775 validators = (validators,)
777 for validator in validators:
778 if type(validator) == types.FunctionType:
779 self.validators.append(FunctionVal(validator))
781 self.validators.append(validator)
785 return "\n ou ".join([v.info() for v in self.validators])
787 def convert(self, valeur):
788 for validator in self.validators:
790 return validator.convert(valeur)
793 raise ValError(ufmt(_(u"%s n'est pas du bon type"), repr(valeur)))
795 def info_erreur_item(self):
797 for v in self.validators:
798 err = v.info_erreur_item()
801 chaine = " \n ou ".join(l)
804 def info_erreur_liste(self):
806 for v in self.validators:
807 err = v.info_erreur_liste()
810 chaine = " \n ou ".join(l)
815 Si plusieurs validateurs sont reliés par un OU
816 il suffit qu'un seul des validateurs attende une liste
817 pour qu'on considère que leur union attend une liste.
819 for validator in self.validators:
820 v = validator.is_list()
825 def verif(self, valeur):
826 for validator in self.validators:
827 v = validator.verif(valeur)
832 def verif_item(self, valeur):
833 for validator in self.validators:
834 v = validator.verif_item(valeur)
839 def verif_cata(self):
841 for validator in self.validators:
842 v = validator.verif_cata()
844 infos.append(validator.cata_info)
846 self.cata_info = "\n".join(infos)
853 Dans le cas ou plusieurs validateurs sont reliés par un OU
854 il faut que tous les validateurs proposent un choix pour
855 qu'on considère que leur union propose un choix.
856 Exemple : Enum(1,2,3) OU entier pair, ne propose pas de choix
857 En revanche, Enum(1,2,3) OU Enum(4,5,6) propose un choix (1,2,3,4,5,6)
859 for validator in self.validators:
860 v = validator.has_into()
865 def get_into(self, liste_courante=None, into_courant=None):
867 Dans le cas ou plusieurs validateurs sont reliés par un OU
868 tous les validateurs doivent proposer un choix pour
869 qu'on considère que leur union propose un choix. Tous les choix
870 proposés par les validateurs sont réunis (opérateur d'union).
871 Exemple : Enum(1,2,3) OU entier pair, ne propose pas de choix
872 En revanche, Enum(1,2,3) OU Enum(4,5,6) propose un
876 for validator in self.validators:
877 v_into = validator.get_into(liste_courante, into_courant)
880 validator_into.extend(v_into)
881 return validator_into
883 def valide_liste_partielle(self, liste_courante=None):
885 Méthode de validation de liste partielle pour le validateur Or.
886 Si un des validateurs gérés par le validateur Or considère la
887 liste comme valide, le validateur Or la considère comme valide.
889 for validator in self.validators:
890 v = validator.valide_liste_partielle(liste_courante)
899 Validateur operationnel
900 Cette classe est un validateur qui controle une liste de validateurs
901 Elle verifie que tous les validateurs de la liste valident la valeur
904 def __init__(self, validators=()):
905 if not is_sequence(validators):
906 validators = (validators,)
908 for validator in validators:
909 if type(validator) == types.FunctionType:
910 self.validators.append(FunctionVal(validator))
912 self.validators.append(validator)
913 if hasattr(validator, 'fonctions'):
914 for fonction in validator.fonctions:
915 f = getattr(validator, fonction)
916 setattr(self, fonction, f)
920 return "\n et ".join([v.info() for v in self.validators])
922 def convert(self, valeur):
923 for validator in self.validators:
924 valeur = validator.convert(valeur)
927 def info_erreur_item(self):
930 for v in self.validators:
931 if v.info_erreur_item() != " ":
933 chaine = v.info_erreur_item()
936 chaine = chaine + " \n et " + v.info_erreur_item()
939 def info_erreur_liste(self):
941 for v in self.validators:
942 if v.info_erreur_liste() != " ":
944 chaine = v.info_erreur_liste()
947 chaine = chaine + " \n et " + v.info_erreur_liste()
950 def verif(self, valeur):
951 for validator in self.validators:
952 v = validator.verif(valeur)
954 self.local_info = validator.info()
958 def verif_item(self, valeur):
959 for validator in self.validators:
960 v = validator.verif_item(valeur)
962 # L'info n'est probablement pas la meme que pour verif ???
963 self.local_info = validator.info()
967 def verif_cata(self):
969 for validator in self.validators:
970 v = validator.verif_cata()
972 infos.append(validator.cata_info)
974 self.cata_info = "\n".join(infos)
979 def valide_liste_partielle(self, liste_courante=None):
981 Méthode de validation de liste partielle pour le validateur And.
982 Tous les validateurs gérés par le validateur And doivent considérer
983 la liste comme valide, pour que le validateur And la considère
986 for validator in self.validators:
987 v = validator.valide_liste_partielle(liste_courante)
994 Si plusieurs validateurs sont reliés par un ET
995 il faut que tous les validateurs attendent une liste
996 pour qu'on considère que leur intersection attende une liste.
997 Exemple Range(2,5) ET Card(1) n'attend pas une liste
998 Range(2,5) ET Pair attend une liste
1000 for validator in self.validators:
1001 v = validator.is_list()
1008 Dans le cas ou plusieurs validateurs sont reliés par un ET
1009 il suffit qu'un seul validateur propose un choix pour
1010 qu'on considère que leur intersection propose un choix.
1011 Exemple : Enum(1,2,3) ET entier pair, propose un choix
1012 En revanche, entier pair ET superieur à 10 ne propose pas de choix
1014 for validator in self.validators:
1015 v = validator.has_into()
1020 def get_into(self, liste_courante=None, into_courant=None):
1022 Dans le cas ou plusieurs validateurs sont reliés par un ET
1023 il suffit qu'un seul validateur propose un choix pour
1024 qu'on considère que leur intersection propose un choix. Tous les
1025 choix proposés par les validateurs sont croisés (opérateur
1027 Exemple : Enum(1,2,3) ET entier pair, propose un choix (2,)
1028 En revanche, Enum(1,2,3) ET Enum(4,5,6) ne propose pas de choix.
1030 for validator in self.validators:
1031 into_courant = validator.get_into(liste_courante, into_courant)
1032 if into_courant in ([], None):
1037 def do_liste(validators):
1039 Convertit une arborescence de validateurs en OrVal ou AndVal
1040 validators est une liste de validateurs ou de listes ou de tuples
1043 for validator in validators:
1044 if type(validator) == types.FunctionType:
1045 valids.append(FunctionVal(validator))
1046 elif type(validator) is tuple:
1047 valids.append(OrVal(do_liste(validator)))
1048 elif type(validator) is list:
1049 valids.append(AndVal(do_liste(validator)))
1051 valids.append(validator)
1055 def validatorFactory(validator):
1056 if type(validator) == types.FunctionType:
1057 return FunctionVal(validator)
1058 elif type(validator) is tuple:
1059 return OrVal(do_liste(validator))
1060 elif type(validator) is list:
1061 return AndVal(do_liste(validator))
1065 # Ci-dessous : exemples de validateur (peu testés)
1068 class RangeVal(ListVal):
1071 Exemple de classe validateur : verification qu'une valeur
1072 est dans un intervalle.
1073 Pour une liste on verifie que tous les elements sont
1075 Susceptible de remplacer les attributs "vale_min" "vale_max"
1079 def __init__(self, low, high):
1082 self.cata_info = ufmt(_(u"%s doit être inférieur a %s"), low, high)
1085 return ufmt(_(u"valeur dans l'intervalle %s , %s"), self.low, self.high)
1087 def convert_item(self, valeur):
1088 if valeur > self.low and valeur < self.high:
1090 raise ValError(ufmt(_(u"%s devrait être comprise entre %s et %s"),
1091 valeur, self.low, self.high))
1093 def verif_item(self, valeur):
1094 return valeur > self.low and valeur < self.high
1096 def info_erreur_item(self):
1097 return ufmt(_(u"La valeur doit etre comprise entre %s et %s"), self.low, self.high)
1099 def verif_cata(self):
1100 if self.low > self.high:
1105 class CardVal(Valid):
1108 Exemple de classe validateur : verification qu'une liste est
1109 d'une longueur superieur a un minimum (min) et inferieure
1111 Susceptible de remplacer les attributs "min" "max" dans les
1115 def __init__(self, min='**', max='**'):
1118 self.cata_info = ufmt(_(u"%s doit etre inferieur a %s"), min, max)
1121 return ufmt(_(u"longueur de liste comprise entre %s et %s"), self.min, self.max)
1123 def info_erreur_liste(self):
1125 _(u"Le cardinal de la liste doit etre compris entre %s et %s"),
1129 return self.max == '**' or self.max > 1
1131 def get_into(self, liste_courante=None, into_courant=None):
1132 if into_courant is None:
1134 elif liste_courante is None:
1136 elif self.max == '**':
1138 elif len(liste_courante) < self.max:
1143 def convert(self, valeur):
1144 if is_sequence(valeur):
1146 elif valeur is None:
1150 if self.max != '**' and l > self.max:
1152 ufmt(_(u"%s devrait etre de longueur inferieure a %s"), valeur, self.max))
1153 if self.min != '**' and l < self.min:
1155 ufmt(_(u"%s devrait etre de longueur superieure a %s"), valeur, self.min))
1158 def verif_item(self, valeur):
1161 def verif(self, valeur):
1162 if is_sequence(valeur):
1163 if self.max != '**' and len(valeur) > self.max:
1165 if self.min != '**' and len(valeur) < self.min:
1169 if self.max != '**' and 1 > self.max:
1171 if self.min != '**' and 1 < self.min:
1175 def verif_cata(self):
1176 if self.min != '**' and self.max != '**' and self.min > self.max:
1180 def valide_liste_partielle(self, liste_courante=None):
1182 if liste_courante != None:
1183 if len(liste_courante) > self.max:
1188 class PairVal(ListVal):
1191 Exemple de classe validateur : verification qu'une valeur
1193 Pour une liste on verifie que tous les elements sont
1198 ListVal.__init__(self)
1202 return _(u"valeur paire")
1204 def info_erreur_item(self):
1205 return _(u"La valeur saisie doit etre paire")
1207 def convert(self, valeur):
1212 ufmt(_(u"%s contient des valeurs non paires"), repr(valeur)))
1215 def default(self, valeur):
1218 def verif_item(self, valeur):
1219 if type(valeur) not in (int, long):
1221 return valeur % 2 == 0
1223 def verif(self, valeur):
1224 if is_sequence(valeur):
1235 class EnumVal(ListVal):
1238 Exemple de classe validateur : verification qu'une valeur
1239 est prise dans une liste de valeurs.
1240 Susceptible de remplacer l attribut "into" dans les catalogues
1243 def __init__(self, into=()):
1244 if not is_sequence(into):
1250 return "valeur dans %s" % `self.into`
1252 def convert_item(self, valeur):
1253 if valeur in self.into:
1256 ufmt(_(u"%s contient des valeurs hors des choix possibles: %s "),
1259 def verif_item(self, valeur):
1260 if valeur not in self.into:
1267 def get_into(self, liste_courante=None, into_courant=None):
1268 if into_courant is None:
1269 liste_choix = list(self.into)
1272 for e in into_courant:
1274 liste_choix.append(e)
1277 def info_erreur_item(self):
1278 return _(u"La valeur n'est pas dans la liste des choix possibles")
1281 def ImpairVal(valeur):
1283 Exemple de validateur
1284 Cette fonction est un validateur. Elle verifie que la valeur passee
1285 est bien un nombre impair.
1287 if is_sequence(valeur):
1297 ImpairVal.info = "valeur impaire"
1303 Exemple de validateur
1304 Cette classe est un validateur de dictionnaire (mot cle facteur ?). Elle verifie
1305 que la somme des cles A et B vaut une valeur donnee
1306 en parametre du validateur
1309 def __init__(self, somme=10):
1314 return ufmt(_(u"valeur %s pour la somme des cles A et B "), self.somme)
1316 def verif(self, valeur):
1317 if is_sequence(valeur):
1319 if not val.has_key("A"):
1321 if not val.has_key("B"):
1323 if val["A"] + val["B"] != self.somme:
1327 if not valeur.has_key("A"):
1329 if not valeur.has_key("B"):
1331 if valeur["A"] + valeur["B"] != self.somme:
1336 class FunctionVal(Valid):
1339 Exemple de validateur
1340 Cette classe est un validateur qui est initialise avec une fonction
1343 def __init__(self, function):
1344 self.function = function
1347 return self.function.info
1349 def verif(self, valeur):
1350 return self.function(valeur)
1352 # MC ca ne devrait plus servir !
1353 CoercableFuncs = {types.IntType: int,
1354 types.LongType: long,
1355 types.FloatType: float,
1356 types.ComplexType: complex,
1357 types.UnicodeType: unicode}
1360 class TypeVal(ListVal):
1363 Exemple de validateur
1364 Cette classe est un validateur qui controle qu'une valeur
1365 est bien du type Python attendu.
1366 Pour une liste on verifie que tous les elements sont du bon type.
1367 Semblable a InstanceVal mais ici on fait le test par tentative de conversion
1368 alors qu'avec InstanceVal on ne teste que si isinstance est vrai.
1371 def __init__(self, aType):
1372 # Si aType n'est pas un type, on le retrouve a l'aide de la fonction type
1373 # type(1) == int;type(0.2)==float;etc.
1374 if type(aType) != types.TypeType:
1378 self.coerce = CoercableFuncs[aType]
1380 self.coerce = self.identity
1383 return ufmt(_(u"valeur de %s"), self.aType)
1385 def identity(self, value):
1386 if type(value) == self.aType:
1390 def convert_item(self, valeur):
1391 return self.coerce(valeur)
1393 def verif_item(self, valeur):
1401 class InstanceVal(ListVal):
1404 Exemple de validateur
1405 Cette classe est un validateur qui controle qu'une valeur est
1406 bien une instance (au sens Python) d'une classe
1407 Pour une liste on verifie chaque element de la liste
1410 def __init__(self, aClass):
1411 # Si aClass est une classe on la memorise dans self.aClass
1412 # sinon c'est une instance dont on memorise la classe
1413 if type(aClass) == types.InstanceType:
1414 # instance ancienne mode
1415 aClass = aClass.__class__
1416 elif type(aClass) == types.ClassType:
1417 # classe ancienne mode
1419 elif type(aClass) == type:
1420 # classe nouvelle mode
1422 elif isinstance(aClass, object):
1423 # instance nouvelle mode
1424 aClass = type(aClass)
1426 raise ValError(_(u"type non supporté"))
1428 self.aClass = aClass
1431 return ufmt(_(u"valeur d'instance de %s"), self.aClass.__name__)
1433 def verif_item(self, valeur):
1434 if not isinstance(valeur, self.aClass):
1439 class VerifTypeTuple(Valid, ListVal):
1441 def __init__(self, typeDesTuples):
1442 self.typeDesTuples = typeDesTuples
1443 Valid.__init__(self)
1447 return _(u": vérifie les types dans un tuple")
1449 def info_erreur_liste(self):
1450 return _(u"Les types entrés ne sont pas permis")
1452 def default(self, valeur):
1453 # if valeur in self.liste : raise ValError("%s est un doublon" %
1460 def convert_item(self, valeur):
1461 if len(valeur) != len(self.typeDesTuples):
1463 ufmt(_(u"%s devrait etre de type %s "), valeur, self.typeDesTuples))
1464 for i in range(len(valeur)):
1465 ok = self.verifType(valeur[i], self.typeDesTuples[i])
1468 ufmt(_(u"%s devrait etre de type %s "), valeur, self.typeDesTuples))
1471 def verif_item(self, valeur):
1473 if len(valeur) != len(self.typeDesTuples):
1475 for i in range(len(valeur)):
1476 ok = self.verifType(valeur[i], self.typeDesTuples[i])
1483 def verifType(self, valeur, type_permis):
1484 if type_permis == 'R':
1485 if type(valeur) in (types.IntType, types.FloatType, types.LongType):
1487 elif type_permis == 'I':
1488 if type(valeur) in (types.IntType, types.LongType):
1490 elif type_permis == 'C':
1491 if self.is_complexe(valeur):
1493 elif type_permis == 'TXM':
1494 if type(valeur) == types.StringType:
1498 def verif(self, valeur):
1499 if type(valeur) in (types.ListType, types.TupleType):
1500 liste = list(valeur)
1502 if self.verif_item(val) != 1:
1507 class VerifExiste(ListVal):
1510 fonctionne avec into
1511 Met une liste à jour selon les mot clefs existant
1512 exemple si into = ("A","B","C")
1513 si au niveau N du JDC les objets "A" et "C" existe
1514 alors la liste des into deviendra ( "A","C")
1516 niveauVerif est le niveau du JDC dans lequel va s effectuer la verification
1517 niveauVerif est defini par rapport au Noeud :
1518 exemple niveauVerif = 1 : on verifie les freres
1519 niveauVerif = 2 : on verifie les oncles..
1522 def __init__(self, niveauVerif):
1523 ListVal.__init__(self)
1524 self.niveauVerif = niveauVerif
1526 self.listeDesFreres = ()
1527 self.fonctions = ('verifie_liste', 'set_MCSimp')
1532 def verifie_liste(self, liste):
1533 self.set_MCSimp(self.MCSimp)
1535 if not(item in self.listeDesFreres):
1539 def verif_item(self, valeur):
1540 self.set_MCSimp(self.MCSimp)
1541 if valeur in self.listeDesFreres:
1545 def set_MCSimp(self, MCSimp):
1546 self.MCSimp = MCSimp
1547 k = self.niveauVerif
1553 # on met la liste à jour
1554 parent.forceRecalcul = self.niveauVerif
1555 self.listeDesFreres = parent.liste_mc_presents()
1557 def convert_item(self, valeur):
1558 if valeur in self.listeDesFreres:
1561 ufmt(_(u"%s n'est pas dans %s"), valeur, self.listeDesFreres))
1564 class RegExpVal(ListVal):
1567 Vérifie qu'une chaîne de caractère corresponde à l'expression régulière 'pattern'
1570 errormsg = u'La chaîne "%(value)s" ne correspond pas au motif "%(pattern)s"'
1572 def __init__(self, pattern):
1573 self.pattern = pattern
1574 self.compiled_regexp = re.compile(pattern)
1577 return u'Une chaîne correspondant au motif "%s" est attendue.' % self.pattern
1579 def verif_item(self, valeur):
1580 if self.compiled_regexp.match(valeur):
1583 return (0, self.errormsg % {"value": valeur, "pattern": self.pattern})
1585 def convert_item(self, valeur):
1586 if self.compiled_regexp.match(valeur):
1589 raise ValError(self.errormsg %
1590 {"value": valeur, "pattern": self.pattern})
1593 class FileExtVal(RegExpVal):
1596 Vérifie qu'une chaîne de caractère soit un nom de fichier valide avec l'extension 'ext'
1599 def __init__(self, ext):
1601 self.errormsg = u'"%%(value)s" n\'est pas un nom de fichier %(ext)s valide' % {
1603 RegExpVal.__init__(self, "^[\w\-]+\.%s$" % self.ext)
1606 return u'Un nom de fichier se terminant par ".%s" est attendu.' % self.ext