1 #@ MODIF N_VALIDATOR Noyau DATE 11/05/2010 AUTEUR COURTOIS M.COURTOIS
2 # -*- coding: iso-8859-1 -*-
3 # RESPONSABLE COURTOIS M.COURTOIS
4 # CONFIGURATION MANAGEMENT OF EDF VERSION
5 # ======================================================================
6 # COPYRIGHT (C) 1991 - 2003 EDF R&D WWW.CODE-ASTER.ORG
7 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
8 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
9 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
10 # (AT YOUR OPTION) ANY LATER VERSION.
12 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
13 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
14 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
15 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
17 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
18 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
19 # 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
20 # ======================================================================
23 Ce module contient toutes les classes necessaires pour
24 implanter le concept de validateur dans Accas
28 from N_ASSD import ASSD
29 from N_types import is_int, is_float_or_int, is_complex, is_number, is_str, is_enum
32 class ValError(Exception):pass
35 if hasattr(cls,"__mro__"):return cls.__mro__
37 for base in cls.__bases__:
38 mro.extend(cls_mro(base))
42 def __init__(self,name):
47 def register(self, T, A):
51 # (a) verifier si l'objet peut s'adapter au protocole
52 adapt = getattr(obj, '__adapt__', None)
54 # on demande à l'objet obj de réaliser lui-meme l'adaptation
57 # (b) verifier si un adapteur est enregistré (si oui l'utiliser)
59 for T in cls_mro(obj.__class__):
60 if T in self.registry:
61 return self.registry[T](obj,self,**self.args)
63 # (c) utiliser l'adapteur par defaut
64 return self.default(obj,**self.args)
66 def default(self,obj,**args):
67 raise TypeError("Can't adapt %s to %s" %
68 (obj.__class__.__name__, self.name))
70 class PProtocol(Protocol):
71 """Verificateur de protocole paramétré (classe de base)"""
72 #Protocole paramétré. Le registre est unique pour toutes les instances. La methode register est une methode de classe
74 def __init__(self,name,**args):
77 def register(cls, T, A):
79 register=classmethod(register)
81 class ListProtocol(Protocol):
82 """Verificateur de protocole liste : convertit un objet quelconque en liste pour validation ultérieure"""
83 def default(self,obj):
84 if type(obj) is tuple:
85 if len(obj) > 0 and obj[0] in ('RI','MP'):
86 #il s'agit d'un complexe ancienne mode. La cardinalite vaut 1
90 elif type(obj) is list:
93 # pas de valeur affecte. La cardinalite vaut 0
96 #il s'agit d'une chaine. La cardinalite vaut 1
100 # si l'objet supporte len, on a la cardinalite
107 listProto=ListProtocol("list")
110 class TypeProtocol(PProtocol):
111 """Verificateur de type parmi une liste de types possibles"""
112 #pas de registre par instance. Registre unique pour toutes les instances de TypeProtocol
114 def __init__(self,name,typ=None):
115 PProtocol.__init__(self,name,typ=typ)
118 def default(self,obj,typ):
120 for type_permis in typ:
121 if type_permis == 'R':
122 if is_float_or_int(obj): return obj
123 elif type_permis == 'I':
124 if is_int(obj): return obj
125 elif type_permis == 'C':
126 if self.is_complexe(obj): return obj
127 elif type_permis == 'TXM':
128 if is_str(obj): return obj
129 elif type_permis == 'shell':
130 if is_str(obj): return obj
131 elif type_permis == 'Fichier' :
133 if (len(typ) > 2 and typ[2] == "Sauvegarde") or os.path.isfile(obj):
135 else : raise ValError("%s n'est pas un fichier valide" % repr(obj))
136 elif type(type_permis) == types.ClassType or isinstance(type_permis,type):
138 if self.is_object_from(obj,type_permis): return obj
139 except Exception, err:
141 elif type(type_permis) == types.InstanceType or isinstance(type_permis,object):
143 if type_permis.__convert__(obj): return obj
144 except Exception, err:
147 print "Type non encore géré %s" %`type_permis`
148 raise ValError("%s (de type %s) n'est pas d'un type autorisé: %s %s" % (repr(obj),type(obj),typ, help))
150 def is_complexe(self,valeur):
151 """ Retourne 1 si valeur est un complexe, 0 sinon """
152 if is_number(valeur):
153 # Pour permettre l'utilisation de complexes Python (accepte les entiers et réels)
155 elif type(valeur) != tuple :
156 # On n'autorise pas les listes pour les complexes
158 elif len(valeur) != 3:
161 # Un complexe doit etre un tuple de longueur 3 avec 'RI' ou 'MP' comme premiere
162 # valeur suivie de 2 reels.
163 if valeur[0].strip() in ('RI','MP'):
165 v1=reelProto.adapt(valeur[1]),reelProto.adapt(valeur[2])
172 def is_object_from(self,objet,classe):
174 Retourne 1 si objet est une instance de la classe classe, 0 sinon
176 convert = getattr(classe, '__convert__', None)
177 if convert is not None:
178 # classe verifie les valeurs
182 except ValueError, err:
186 # On accepte les instances de la classe et des classes derivees
187 return isinstance(objet,classe)
189 reelProto=TypeProtocol("reel",typ=('R',))
191 class CardProtocol(PProtocol):
192 """Verificateur de cardinalité """
193 #pas de registre par instance. Registre unique pour toutes les instances
195 def __init__(self,name,min=1,max=1):
196 PProtocol.__init__(self,name,min=min,max=max)
198 def default(self,obj,min,max):
200 if length < min or length >max:
201 raise ValError("Nombre d'arguments de %s incorrect (min = %s, max = %s)" % (repr(obj),min,max) )
204 class IntoProtocol(PProtocol):
205 """Verificateur de choix possibles : liste discrète ou intervalle"""
206 #pas de registre par instance. Registre unique pour toutes les instances
208 def __init__(self,name,into=None,val_min='**',val_max='**'):
209 PProtocol.__init__(self,name,into=into,val_min=val_min,val_max=val_max)
213 def default(self,obj,into,val_min,val_max):
216 raise ValError("La valeur : %s ne fait pas partie des choix possibles %s" % (repr(obj),into) )
218 #on est dans le cas d'un ensemble continu de valeurs possibles (intervalle)
219 if is_float_or_int(obj):
220 if val_min == '**': val_min = obj -1
221 if val_max == '**': val_max = obj +1
222 if obj < val_min or obj > val_max :
223 raise ValError("La valeur : %s est en dehors du domaine de validité [ %s , %s ]" % (repr(obj),self.val_min,self.val_max) )
227 #exemple de classe pour verificateur de type
228 #on utilise des instances de classe comme type (typ=MinStr(3,6), par exemple)
229 def __init__(self,min,max):
233 def __convert__(self,valeur):
234 if is_str(valeur) and self.min <= len(valeur) <= self.max:return valeur
235 raise ValError("%s n'est pas une chaine de longueur comprise entre %s et %s" % (valeur,self.min,self.max))
238 return "TXM de longueur entre %s et %s" %(self.min,self.max)
240 class Valid(PProtocol):
242 Cette classe est la classe mere des validateurs Accas
243 Elle doit etre derivee
244 Elle presente la signature des methodes indispensables pour son bon
245 fonctionnement et dans certains cas leur comportement par défaut.
247 @ivar cata_info: raison de la validite ou de l'invalidite du validateur meme
248 @type cata_info: C{string}
251 def __init__(self,**args):
252 PProtocol.__init__(self,"valid",**args)
256 Cette methode retourne une chaine de caractères informative sur
257 la validation demandée par le validateur. Elle est utilisée
258 pour produire le compte-rendu de validité du mot clé associé.
260 return "valeur valide"
264 Cette methode retourne une chaine de caractère qui permet
265 de construire un message d'aide en ligne.
266 En général, le message retourné est le meme que celui retourné par la
271 def info_erreur_item(self):
273 Cette méthode permet d'avoir un message d'erreur pour un item
274 dans une liste dans le cas ou le validateur fait des vérifications
275 sur les items d'une liste. Si le validateur fait seulement des
276 vérifications sur la liste elle meme et non sur ses items, la méthode
277 doit retourner une chaine vide.
281 def info_erreur_liste(self):
283 Cette méthode a un comportement complémentaire de celui de
284 info_erreur_item. Elle retourne un message d'erreur lié uniquement
285 aux vérifications sur la liste elle meme et pas sur ses items.
286 Dans le cas où le validateur ne fait pas de vérification sur des
287 listes, elle retourne une chaine vide
291 def verif(self,valeur):
293 Cette methode sert a verifier si la valeur passee en argument est consideree
294 comme valide ou non par le validateur. Dans le premier cas le validateur retourne 1
295 (valide) sinon 0 (invalide).
297 @type valeur: tout type python
298 @param valeur: valeur du mot cle a valider
300 @return: indicateur de validite 1 (valide) ou 0 (invalide)
302 raise "Must be implemented"
304 def verif_item(self,valeur):
306 La methode verif du validateur effectue une validation complete de
307 la valeur. valeur peut etre un scalaire ou une liste. Le validateur
308 doit traiter les 2 aspects s'il accepte des listes (dans ce cas la
309 methode is_list doit retourner 1).
310 La methode valid_item sert pour effectuer des validations partielles
311 de liste. Elle doit uniquement verifier la validite d'un item de
312 liste mais pas les caracteristiques de la liste.
316 def valide_liste_partielle(self,liste_courante):
318 Cette methode retourne un entier qui indique si liste_courante est partiellement valide (valeur 1)
319 ou invalide (valeur 0). La validation partielle concerne les listes en cours de construction : on
320 veut savoir si la liste en construction peut etre complétée ou si elle peut déjà etre considérée
322 En général un validateur effectue la meme validation pour les listes partielles et les
325 return self.verif(liste_courante)
327 def verif_cata(self):
329 Cette methode sert a realiser des verifications du validateur lui meme.
330 Elle est facultative et retourne 1 (valide) par defaut.
331 Elle retourne 0 si le validateur est lui meme invalide si par exemple ses
332 parametres de definition ne sont pas corrects.
333 La raison de l'invalidite est stockee dans l'attribut cata_info.
336 @return: indicateur de validite 1 (valide) ou 0 (invalide)
342 Cette méthode retourne un entier qui indique si le validateur
343 permet les listes (valeur 1) ou ne les permet pas (valeur 0).
344 Par défaut, un validateur n'autorise que des scalaires.
350 Cette méthode retourne un entier qui indique si le validateur
351 propose une liste de choix (valeur 1) ou n'en propose pas.
352 Par défaut, un validateur n'en propose pas.
356 def get_into(self,liste_courante=None,into_courant=None):
358 Cette méthode retourne la liste de choix proposée par le validateur.
359 Si le validateur ne propose pas de liste de choix, la méthode
361 L'argument d'entrée liste_courante, s'il est différent de None, donne
362 la liste des choix déjà effectués par l'utilisateur. Dans ce cas, la
363 méthode get_into doit calculer la liste des choix en en tenant
364 compte. Par exemple, si le validateur n'autorise pas les répétitions,
365 la liste des choix retournée ne doit pas contenir les choix déjà
366 contenus dans liste_courante.
367 L'argument d'entrée into_courant, s'il est différent de None, donne
368 la liste des choix proposés par d'autres validateurs. Dans ce cas,
369 la méthode get_into doit calculer la liste des choix à retourner
370 en se limitant à cette liste initiale. Par exemple, si into_courant
371 vaut (1,2,3) et que le validateur propose la liste de choix (3,4,5),
372 la méthode ne doit retourner que (3,).
374 La méthode get_into peut retourner une liste vide [], ce qui veut
375 dire qu'il n'y a pas (ou plus) de choix possible. Cette situation
376 peut etre normale : l''utilisateur a utilisé tous les choix, ou
377 résulter d'une incohérence des validateurs :
378 choix parmi (1,2,3) ET choix parmi (4,5,6). Il est impossible de
379 faire la différence entre ces deux situations.
383 class ListVal(Valid):
385 Cette classe sert de classe mère pour tous les validateurs qui acceptent
391 def get_into(self,liste_courante=None,into_courant=None):
393 Cette méthode get_into effectue un traitement général qui consiste
394 a filtrer la liste de choix into_courant, si elle existe, en ne
395 conservant que les valeurs valides (appel de la méthode valid).
397 if into_courant is None:
401 for e in into_courant:
403 liste_choix.append(e)
406 def convert(self,valeur):
408 Méthode convert pour les validateurs de listes. Cette méthode
409 fait appel à la méthode convert_item sur chaque élément de la
414 self.convert_item(val)
417 return self.convert_item(valeur)
419 def verif(self,valeur):
421 Méthode verif pour les validateurs de listes. Cette méthode
422 fait appel à la méthode verif_item sur chaque élément de la
423 liste. Si valeur est un paramètre, on utilise sa valeur effective
428 if not self.verif_item(val):
432 return self.verif_item(valeur)
434 class Compulsory(ListVal):
436 Validateur operationnel
437 Verification de la présence obligatoire d'un élément dans une liste
440 def __init__(self,elem=()):
441 if not is_enum(elem): elem=(elem,)
442 Valid.__init__(self,elem=elem)
447 return "valeur %s obligatoire" % `self.elem`
449 def default(self,valeur,elem):
452 def verif_item(self,valeur):
455 def convert(self,valeur):
459 if v in elem:elem.remove(v)
461 raise ValError("%s ne contient pas les elements obligatoires : %s " %(valeur,elem))
467 def verif(self,valeur):
468 if not is_enum(valeur):
472 for val in self.elem :
473 if val not in liste : return 0
476 def info_erreur_item(self):
477 return "La valeur n'est pas dans la liste des choix possibles"
479 class NoRepeat(ListVal):
481 Validateur operationnel
482 Verification d'absence de doublons dans la liste.
489 return ": pas de présence de doublon dans la liste"
491 def info_erreur_liste(self):
492 return "Les doublons ne sont pas permis"
494 def default(self,valeur):
495 if valeur in self.liste : raise ValError("%s est un doublon" % valeur)
498 def convert(self,valeur):
505 def verif_item(self,valeur):
508 def verif(self,valeur):
512 if liste.count(val)!=1 : return 0
517 def get_into(self,liste_courante=None,into_courant=None):
519 Methode get_into spécifique pour validateur NoRepeat, on retourne
520 une liste de choix qui ne contient aucune valeur de into_courant
521 déjà contenue dans liste_courante
523 if into_courant is None:
527 for e in into_courant:
528 if e in liste_choix: continue
529 if liste_courante is not None and e in liste_courante: continue
530 liste_choix.append(e)
533 class LongStr(ListVal):
535 Validateur operationnel
536 Verification de la longueur d une chaine
538 def __init__(self,low,high):
539 ListVal.__init__(self,low=low,high=high)
545 return "longueur de la chaine entre %s et %s" %(self.low,self.high)
547 def info_erreur_item(self):
548 return "Longueur de la chaine incorrecte"
550 def convert(self,valeur):
555 def verif_item(self,valeur):
562 def default(self,valeur,low,high):
563 if not is_str(valeur):
564 raise ValError("%s n'est pas une string" % repr(valeur))
565 if valeur[0]=="'" and valeur[-1]=="'" :
568 if len(valeur) < low or len(valeur) > high :
569 raise ValError("%s n'est pas de la bonne longueur" % repr(valeur))
572 class OrdList(ListVal):
574 Validateur operationnel
575 Verification qu'une liste est croissante ou decroissante
577 def __init__(self,ord):
578 ListVal.__init__(self,ord=ord)
583 return "liste %s" % self.ord
585 def info_erreur_liste(self) :
586 return "La liste doit etre en ordre "+self.ord
588 def convert(self,valeur):
595 def default(self,valeur,ord):
596 if self.ord=='croissant':
597 if self.val is not None and valeur<self.val:
598 raise ValError("%s n'est pas par valeurs croissantes" % repr(self.liste))
599 elif self.ord=='decroissant':
600 if self.val is not None and valeur > self.val:
601 raise ValError("%s n'est pas par valeurs decroissantes" % repr(self.liste))
605 def verif_item(self,valeur):
608 def get_into(self,liste_courante=None,into_courant=None):
610 Methode get_into spécifique pour validateur OrdList, on retourne
611 une liste de choix qui ne contient aucune valeur de into_courant
612 dont la valeur est inférieure à la dernière valeur de
613 liste_courante, si elle est différente de None.
615 if into_courant is None:
617 elif not liste_courante :
621 last_val=liste_choix[-1]
622 for e in into_courant:
623 if self.ord=='croissant' and e <= last_val:continue
624 if self.ord=='decroissant' and e >= last_val:continue
625 liste_choix.append(e)
630 Validateur operationnel
631 Cette classe est un validateur qui controle une liste de validateurs
632 Elle verifie qu'au moins un des validateurs de la liste valide la valeur
634 def __init__(self,validators=()):
635 if not is_enum(validators):
636 validators=(validators,)
638 for validator in validators:
639 if type(validator) == types.FunctionType:
640 self.validators.append(FunctionVal(validator))
642 self.validators.append(validator)
646 return "\n ou ".join([v.info() for v in self.validators])
648 def convert(self,valeur):
649 for validator in self.validators:
651 return validator.convert(valeur)
654 raise ValError("%s n'est pas du bon type" % repr(valeur))
656 def info_erreur_item(self):
658 for v in self.validators:
659 err=v.info_erreur_item()
660 if err != " " : l.append(err)
661 chaine=" \n ou ".join(l)
664 def info_erreur_liste(self):
666 for v in self.validators:
667 err=v.info_erreur_liste()
668 if err != " " : l.append(err)
669 chaine=" \n ou ".join(l)
674 Si plusieurs validateurs sont reliés par un OU
675 il suffit qu'un seul des validateurs attende une liste
676 pour qu'on considère que leur union attend une liste.
678 for validator in self.validators:
679 v=validator.is_list()
684 def verif(self,valeur):
685 for validator in self.validators:
686 v=validator.verif(valeur)
691 def verif_item(self,valeur):
692 for validator in self.validators:
693 v=validator.verif_item(valeur)
698 def verif_cata(self):
700 for validator in self.validators:
701 v=validator.verif_cata()
702 if not v :infos.append(validator.cata_info)
704 self.cata_info="\n".join(infos)
711 Dans le cas ou plusieurs validateurs sont reliés par un OU
712 il faut que tous les validateurs proposent un choix pour
713 qu'on considère que leur union propose un choix.
714 Exemple : Enum(1,2,3) OU entier pair, ne propose pas de choix
715 En revanche, Enum(1,2,3) OU Enum(4,5,6) propose un choix (1,2,3,4,5,6)
717 for validator in self.validators:
718 v=validator.has_into()
723 def get_into(self,liste_courante=None,into_courant=None):
725 Dans le cas ou plusieurs validateurs sont reliés par un OU
726 tous les validateurs doivent proposer un choix pour
727 qu'on considère que leur union propose un choix. Tous les choix
728 proposés par les validateurs sont réunis (opérateur d'union).
729 Exemple : Enum(1,2,3) OU entier pair, ne propose pas de choix
730 En revanche, Enum(1,2,3) OU Enum(4,5,6) propose un
734 for validator in self.validators:
735 v_into=validator.get_into(liste_courante,into_courant)
738 validator_into.extend(v_into)
739 return validator_into
741 def valide_liste_partielle(self,liste_courante=None):
743 Méthode de validation de liste partielle pour le validateur Or.
744 Si un des validateurs gérés par le validateur Or considère la
745 liste comme valide, le validateur Or la considère comme valide.
747 for validator in self.validators:
748 v=validator.valide_liste_partielle(liste_courante)
755 Validateur operationnel
756 Cette classe est un validateur qui controle une liste de validateurs
757 Elle verifie que tous les validateurs de la liste valident la valeur
759 def __init__(self,validators=()):
760 if not is_enum(validators):
761 validators=(validators,)
763 for validator in validators:
764 if type(validator) == types.FunctionType:
765 self.validators.append(FunctionVal(validator))
767 self.validators.append(validator)
768 if hasattr(validator,'fonctions'):
769 for fonction in validator.fonctions :
770 f=getattr(validator,fonction)
771 setattr(self,fonction,f)
775 return "\n et ".join([v.info() for v in self.validators])
777 def convert(self,valeur):
778 for validator in self.validators:
779 valeur=validator.convert(valeur)
782 def info_erreur_item(self):
785 for v in self.validators:
786 if v.info_erreur_item() != " " :
788 chaine=v.info_erreur_item()
791 chaine=chaine+" \n et "+v.info_erreur_item()
794 def info_erreur_liste(self):
796 for v in self.validators:
797 if v.info_erreur_liste() != " " :
799 chaine=v.info_erreur_liste()
802 chaine=chaine+" \n et "+v.info_erreur_liste()
805 def verif(self,valeur):
806 print "je suis dans le verif du AndVal"
807 for validator in self.validators:
808 v=validator.verif(valeur)
810 self.local_info=validator.info()
814 def verif_item(self,valeur):
815 for validator in self.validators:
816 v=validator.verif_item(valeur)
818 # L'info n'est probablement pas la meme que pour verif ???
819 self.local_info=validator.info()
823 def verif_cata(self):
825 for validator in self.validators:
826 v=validator.verif_cata()
827 if not v :infos.append(validator.cata_info)
829 self.cata_info="\n".join(infos)
834 def valide_liste_partielle(self,liste_courante=None):
836 Méthode de validation de liste partielle pour le validateur And.
837 Tous les validateurs gérés par le validateur And doivent considérer
838 la liste comme valide, pour que le validateur And la considère
841 for validator in self.validators:
842 v=validator.valide_liste_partielle(liste_courante)
849 Si plusieurs validateurs sont reliés par un ET
850 il faut que tous les validateurs attendent une liste
851 pour qu'on considère que leur intersection attende une liste.
852 Exemple Range(2,5) ET Card(1) n'attend pas une liste
853 Range(2,5) ET Pair attend une liste
855 for validator in self.validators:
856 v=validator.is_list()
863 Dans le cas ou plusieurs validateurs sont reliés par un ET
864 il suffit qu'un seul validateur propose un choix pour
865 qu'on considère que leur intersection propose un choix.
866 Exemple : Enum(1,2,3) ET entier pair, propose un choix
867 En revanche, entier pair ET superieur à 10 ne propose pas de choix
869 for validator in self.validators:
870 v=validator.has_into()
875 def get_into(self,liste_courante=None,into_courant=None):
877 Dans le cas ou plusieurs validateurs sont reliés par un ET
878 il suffit qu'un seul validateur propose un choix pour
879 qu'on considère que leur intersection propose un choix. Tous les
880 choix proposés par les validateurs sont croisés (opérateur
882 Exemple : Enum(1,2,3) ET entier pair, propose un choix (2,)
883 En revanche, Enum(1,2,3) ET Enum(4,5,6) ne propose pas de choix.
885 for validator in self.validators:
886 into_courant=validator.get_into(liste_courante,into_courant)
887 if into_courant in ([],None):break
890 def do_liste(validators):
892 Convertit une arborescence de validateurs en OrVal ou AndVal
893 validators est une liste de validateurs ou de listes ou de tuples
896 for validator in validators:
897 if type(validator) == types.FunctionType:
898 valids.append(FunctionVal(validator))
899 elif type(validator) is tuple:
900 valids.append(OrVal(do_liste(validator)))
901 elif type(validator) is list:
902 valids.append(AndVal(do_liste(validator)))
904 valids.append(validator)
907 def validatorFactory(validator):
908 if type(validator) == types.FunctionType:
909 return FunctionVal(validator)
910 elif type(validator) is tuple:
911 return OrVal(do_liste(validator))
912 elif type(validator) is list:
913 return AndVal(do_liste(validator))
917 # Ci-dessous : exemples de validateur (peu testés)
919 class RangeVal(ListVal):
921 Exemple de classe validateur : verification qu'une valeur
922 est dans un intervalle.
923 Pour une liste on verifie que tous les elements sont
925 Susceptible de remplacer les attributs "vale_min" "vale_max"
928 def __init__(self,low,high):
931 self.cata_info="%s doit etre inferieur a %s" %(low,high)
934 return "valeur dans l'intervalle %s , %s" %(self.low,self.high)
936 def convert_item(self,valeur):
937 if valeur > self.low and valeur < self.high:return valeur
938 raise ValError("%s devrait etre comprise entre %s et %s" %(valeur,self.low,self.high))
940 def verif_item(self,valeur):
941 return valeur > self.low and valeur < self.high
943 def info_erreur_item(self) :
944 return "La valeur doit etre comprise entre %s et %s" % (self.low,
947 def verif_cata(self):
948 if self.low > self.high : return 0
951 class CardVal(Valid):
953 Exemple de classe validateur : verification qu'une liste est
954 d'une longueur superieur a un minimum (min) et inferieure
956 Susceptible de remplacer les attributs "min" "max" dans les
959 def __init__(self,min='**',max='**'):
962 self.cata_info="%s doit etre inferieur a %s" % (min,max)
965 return "longueur de liste comprise entre %s et %s" % (self.min,self.max)
967 def info_erreur_liste(self):
968 return "Le cardinal de la liste doit etre compris entre %s et %s" % (self.min,self.max)
971 return self.max == '**' or self.max > 1
973 def get_into(self,liste_courante=None,into_courant=None):
974 if into_courant is None:
976 elif liste_courante is None:
978 elif self.max == '**':
980 elif len(liste_courante) < self.max:
985 def convert(self,valeur):
992 if self.max != '**' and l > self.max:raise ValError("%s devrait etre de longueur inferieure a %s" %(valeur,self.max))
993 if self.min != '**' and l < self.min:raise ValError("%s devrait etre de longueur superieure a %s" %(valeur,self.min))
996 def verif_item(self,valeur):
999 def verif(self,valeur):
1001 if self.max != '**' and len(valeur) > self.max:return 0
1002 if self.min != '**' and len(valeur) < self.min:return 0
1005 if self.max != '**' and 1 > self.max:return 0
1006 if self.min != '**' and 1 < self.min:return 0
1009 def verif_cata(self):
1010 if self.min != '**' and self.max != '**' and self.min > self.max : return 0
1013 def valide_liste_partielle(self,liste_courante=None):
1015 if liste_courante != None :
1016 if len(liste_courante) > self.max :
1020 class PairVal(ListVal):
1022 Exemple de classe validateur : verification qu'une valeur
1024 Pour une liste on verifie que tous les elements sont
1028 ListVal.__init__(self)
1032 return "valeur paire"
1034 def info_erreur_item(self):
1035 return "La valeur saisie doit etre paire"
1037 def convert(self,valeur):
1040 if v % 2 != 0:raise ValError("%s contient des valeurs non paires" % repr(valeur))
1043 def default(self,valeur):
1046 def verif_item(self,valeur):
1047 if type(valeur) not in (int,long):
1049 return valeur % 2 == 0
1051 def verif(self,valeur):
1054 if val % 2 != 0:return 0
1057 if valeur % 2 != 0:return 0
1060 class EnumVal(ListVal):
1062 Exemple de classe validateur : verification qu'une valeur
1063 est prise dans une liste de valeurs.
1064 Susceptible de remplacer l attribut "into" dans les catalogues
1066 def __init__(self,into=()):
1067 if not is_enum(into):
1073 return "valeur dans %s" % `self.into`
1075 def convert_item(self,valeur):
1076 if valeur in self.into:return valeur
1077 raise ValError("%s contient des valeurs hors des choix possibles: %s " %(valeur,self.into))
1079 def verif_item(self,valeur):
1080 if valeur not in self.into:return 0
1086 def get_into(self,liste_courante=None,into_courant=None):
1087 if into_courant is None:
1088 liste_choix= list(self.into)
1091 for e in into_courant:
1093 liste_choix.append(e)
1096 def info_erreur_item(self):
1097 return "La valeur n'est pas dans la liste des choix possibles"
1099 def ImpairVal(valeur):
1101 Exemple de validateur
1102 Cette fonction est un validateur. Elle verifie que la valeur passee
1103 est bien un nombre impair.
1107 if val % 2 != 1:return 0
1110 if valeur % 2 != 1:return 0
1113 ImpairVal.info="valeur impaire"
1117 Exemple de validateur
1118 Cette classe est un validateur de dictionnaire (mot cle facteur ?). Elle verifie
1119 que la somme des cles A et B vaut une valeur donnee
1120 en parametre du validateur
1122 def __init__(self,somme=10):
1127 return "valeur %s pour la somme des cles A et B " % self.somme
1129 def verif(self,valeur):
1132 if not val.has_key("A"):return 0
1133 if not val.has_key("B"):return 0
1134 if val["A"]+val["B"] != self.somme:return 0
1137 if not valeur.has_key("A"):return 0
1138 if not valeur.has_key("B"):return 0
1139 if valeur["A"]+valeur["B"] != self.somme:return 0
1142 class FunctionVal(Valid):
1144 Exemple de validateur
1145 Cette classe est un validateur qui est initialise avec une fonction
1147 def __init__(self,function):
1148 self.function=function
1151 return self.function.info
1153 def verif(self,valeur):
1154 return self.function(valeur)
1156 #MC ca ne devrait plus servir !
1157 CoercableFuncs = { types.IntType: int,
1158 types.LongType: long,
1159 types.FloatType: float,
1160 types.ComplexType: complex,
1161 types.UnicodeType: unicode }
1163 class TypeVal(ListVal):
1165 Exemple de validateur
1166 Cette classe est un validateur qui controle qu'une valeur
1167 est bien du type Python attendu.
1168 Pour une liste on verifie que tous les elements sont du bon type.
1169 Semblable a InstanceVal mais ici on fait le test par tentative de conversion
1170 alors qu'avec InstanceVal on ne teste que si isinstance est vrai.
1172 def __init__(self, aType):
1173 #Si aType n'est pas un type, on le retrouve a l'aide de la fonction type
1174 #type(1) == int;type(0.2)==float;etc.
1175 if type(aType) != types.TypeType:
1179 self.coerce=CoercableFuncs[ aType ]
1181 self.coerce = self.identity
1184 return "valeur de %s" % self.aType
1186 def identity ( self, value ):
1187 if type( value ) == self.aType:
1191 def convert_item(self,valeur):
1192 return self.coerce(valeur)
1194 def verif_item(self,valeur):
1201 class InstanceVal(ListVal):
1203 Exemple de validateur
1204 Cette classe est un validateur qui controle qu'une valeur est
1205 bien une instance (au sens Python) d'une classe
1206 Pour une liste on verifie chaque element de la liste
1208 def __init__(self,aClass):
1209 #Si aClass est une classe on la memorise dans self.aClass
1210 #sinon c'est une instance dont on memorise la classe
1211 if type(aClass) == types.InstanceType:
1212 #instance ancienne mode
1213 aClass=aClass.__class__
1214 elif type(aClass) == types.ClassType:
1215 #classe ancienne mode
1217 elif type(aClass) == type:
1218 #classe nouvelle mode
1220 elif isinstance(aClass,object):
1221 #instance nouvelle mode
1224 raise ValError("type non supporte")
1229 return "valeur d'instance de %s" % self.aClass.__name__
1231 def verif_item(self,valeur):
1232 if not isinstance(valeur,self.aClass): return 0
1235 class VerifTypeTuple(Valid,ListVal) :
1236 def __init__(self,typeDesTuples):
1237 self.typeDesTuples=typeDesTuples
1238 Valid.__init__(self)
1242 return ": verifie les types dans un tuple"
1244 def info_erreur_liste(self):
1245 return "Les types entres ne sont pas permis"
1247 def default(self,valeur):
1248 #if valeur in self.liste : raise ValError("%s est un doublon" % valeur)
1254 def convert_item(self,valeur):
1255 if len(valeur) != len(self.typeDesTuples):
1256 raise ValError("%s devrait etre de type %s " %(valeur,self.typeDesTuples))
1257 for i in range(len(valeur)) :
1258 ok=self.verifType(valeur[i],self.typeDesTuples[i])
1260 raise ValError("%s devrait etre de type %s " %(valeur,self.typeDesTuples))
1263 def verif_item(self,valeur):
1265 if len(valeur) != len(self.typeDesTuples): return 0
1266 for i in range(len(valeur)) :
1267 ok=self.verifType(valeur[i],self.typeDesTuples[i])
1273 def verifType(self,valeur,type_permis):
1274 if type_permis == 'R':
1275 if type(valeur) in (types.IntType,types.FloatType,types.LongType):return 1
1276 elif type_permis == 'I':
1277 if type(valeur) in (types.IntType,types.LongType):return 1
1278 elif type_permis == 'C':
1279 if self.is_complexe(valeur):return 1
1280 elif type_permis == 'TXM':
1281 if type(valeur)==types.StringType:return 1
1284 def verif(self,valeur):
1285 if type(valeur) in (types.ListType,types.TupleType):
1288 if self.verif_item(val)!=1 : return 0
1291 class VerifExiste(ListVal) :
1293 fonctionne avec into
1294 Met une liste à jour selon les mot clefs existant
1295 exemple si into = ("A","B","C")
1296 si au niveau N du JDC les objets "A" et "C" existe
1297 alors la liste des into deviendra ( "A","C")
1299 niveauVerif est le niveau du JDC dans lequel va s effectuer la verification
1300 niveauVerif est defini par rapport au Noeud :
1301 exemple niveauVerif = 1 : on verifie les freres
1302 niveauVerif = 2 : on verifie les oncles..
1304 def __init__(self,niveauVerif):
1305 ListVal.__init__(self)
1306 self.niveauVerif=niveauVerif
1308 self.listeDesFreres=()
1309 self.fonctions=('verifie_liste','set_MCSimp')
1314 def verifie_liste(self,liste):
1315 self.set_MCSimp(self.MCSimp)
1317 if not( item in self.listeDesFreres) : return 0
1320 def verif_item(self,valeur):
1321 self.set_MCSimp(self.MCSimp)
1322 if valeur in self.listeDesFreres : return 1
1325 def set_MCSimp(self, MCSimp) :
1333 #on met la liste à jour
1334 parent.forceRecalcul=self.niveauVerif
1335 self.listeDesFreres=parent.liste_mc_presents()
1337 def convert_item(self,valeur):
1338 if valeur in self.listeDesFreres : return valeur
1339 raise ValError(str(valeur)+" n est pas dans " + str(self.listeDesFreres))