1 #@ MODIF N_VALIDATOR Noyau DATE 16/05/2007 AUTEUR COURTOIS M.COURTOIS
2 # -*- coding: iso-8859-1 -*-
3 # CONFIGURATION MANAGEMENT OF EDF VERSION
4 # ======================================================================
5 # COPYRIGHT (C) 1991 - 2003 EDF R&D WWW.CODE-ASTER.ORG
6 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
7 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
8 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
9 # (AT YOUR OPTION) ANY LATER VERSION.
11 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
12 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
13 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
14 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
16 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
17 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
18 # 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
19 # ======================================================================
22 Ce module contient toutes les classes necessaires pour
23 implanter le concept de validateur dans Accas
28 from N_ASSD import ASSD
30 class ValError(Exception):pass
33 if hasattr(cls,"__mro__"):return cls.__mro__
35 for base in cls.__bases__:
36 mro.extend(cls_mro(base))
40 def __init__(self,name):
45 def register(self, T, A):
49 # (a) verifier si l'objet peut s'adapter au protocole
50 adapt = getattr(obj, '__adapt__', None)
52 # on demande à l'objet obj de réaliser lui-meme l'adaptation
55 # (b) verifier si un adapteur est enregistré (si oui l'utiliser)
57 for T in cls_mro(obj.__class__):
58 if T in self.registry:
59 return self.registry[T](obj,self,**self.args)
61 # (c) utiliser l'adapteur par defaut
62 return self.default(obj,**self.args)
64 def default(self,obj,**args):
65 raise TypeError("Can't adapt %s to %s" %
66 (obj.__class__.__name__, self.name))
68 class PProtocol(Protocol):
69 """Verificateur de protocole paramétré (classe de base)"""
70 #Protocole paramétré. Le registre est unique pour toutes les instances. La methode register est une methode de classe
72 def __init__(self,name,**args):
75 def register(cls, T, A):
77 register=classmethod(register)
79 class ListProtocol(Protocol):
80 """Verificateur de protocole liste : convertit un objet quelconque en liste pour validation ultérieure"""
81 def default(self,obj):
82 if type(obj) == types.TupleType :
83 if obj[0] in ('RI','MP'):
84 #il s'agit d'un complexe ancienne mode. La cardinalite vaut 1
88 elif type(obj) == types.ListType :
91 # pas de valeur affecte. La cardinalite vaut 0
93 elif type(obj) == types.StringType :
94 #il s'agit d'une chaine. La cardinalite vaut 1
98 # si l'objet supporte len, on a la cardinalite
105 listProto=ListProtocol("list")
107 class TypeProtocol(PProtocol):
108 """Verificateur de type parmi une liste de types possibles"""
109 #pas de registre par instance. Registre unique pour toutes les instances de TypeProtocol
111 def __init__(self,name,typ=None):
112 PProtocol.__init__(self,name,typ=typ)
115 def default(self,obj,typ):
116 for type_permis in typ:
117 if type_permis == 'R':
118 if type(obj) in (types.IntType,types.FloatType,types.LongType):return obj
119 elif type_permis == 'I':
120 if type(obj) in (types.IntType,types.LongType):return obj
121 elif type_permis == 'C':
122 if self.is_complexe(obj):return obj
123 elif type_permis == 'TXM':
124 if type(obj)==types.StringType:return obj
125 elif type_permis == 'shell':
126 if type(obj)==types.StringType:return obj
127 elif type(type_permis) == types.ClassType or isinstance(type_permis,type):
128 if self.is_object_from(obj,type_permis):return obj
129 elif type(type_permis) == types.InstanceType or isinstance(type_permis,object):
131 if type_permis.__convert__(obj) : return obj
135 print "Type non encore géré %s" %`type_permis`
137 raise ValError("%s n'est pas d'un type autorisé: %s" % (repr(obj),typ))
139 def is_complexe(self,valeur):
140 """ Retourne 1 si valeur est un complexe, 0 sinon """
141 if type(valeur) in (types.ComplexType,types.IntType,types.FloatType,types.LongType):
142 # Pour permettre l'utilisation de complexes Python
144 elif type(valeur) != types.TupleType :
145 # On n'autorise pas les listes pour les complexes
147 elif len(valeur) != 3:
150 # Un complexe doit etre un tuple de longueur 3 avec 'RI' ou 'MP' comme premiere
151 # valeur suivie de 2 reels.
152 if string.strip(valeur[0]) in ('RI','MP'):
154 v1=reelProto.adapt(valeur[1]),reelProto.adapt(valeur[2])
161 def is_object_from(self,objet,classe):
163 Retourne 1 si objet est une instance de la classe classe, 0 sinon
165 convert = getattr(classe, '__convert__', None)
166 if convert is not None:
167 # classe verifie les valeurs
173 # On accepte les instances de la classe et des classes derivees
174 return isinstance(objet,classe)
176 reelProto=TypeProtocol("reel",typ=('R',))
178 class CardProtocol(PProtocol):
179 """Verificateur de cardinalité """
180 #pas de registre par instance. Registre unique pour toutes les instances
182 def __init__(self,name,min=1,max=1):
183 PProtocol.__init__(self,name,min=min,max=max)
185 def default(self,obj,min,max):
187 if length < min or length >max:
188 raise ValError("Nombre d'arguments de %s incorrect (min = %s, max = %s)" % (repr(obj),min,max) )
191 class IntoProtocol(PProtocol):
192 """Verificateur de choix possibles : liste discrète ou intervalle"""
193 #pas de registre par instance. Registre unique pour toutes les instances
195 def __init__(self,name,into=None,val_min='**',val_max='**'):
196 PProtocol.__init__(self,name,into=into,val_min=val_min,val_max=val_max)
200 def default(self,obj,into,val_min,val_max):
203 raise ValError("La valeur : %s ne fait pas partie des choix possibles %s" % (repr(obj),into) )
205 #on est dans le cas d'un ensemble continu de valeurs possibles (intervalle)
206 if type(obj) in (types.IntType,types.FloatType,types.LongType) :
207 if val_min == '**': val_min = obj -1
208 if val_max == '**': val_max = obj +1
209 if obj < val_min or obj > val_max :
210 raise ValError("La valeur : %s est en dehors du domaine de validité [ %s , %s ]" % (repr(obj),self.val_min,self.val_max) )
214 #exemple de classe pour verificateur de type
215 #on utilise des instances de classe comme type (typ=MinStr(3,6), par exemple)
216 def __init__(self,min,max):
220 def __convert__(self,valeur):
221 if type(valeur) == types.StringType and self.min <= len(valeur) <= self.max:return valeur
222 raise ValError("%s n'est pas une chaine de longueur comprise entre %s et %s" % (valeur,self.min,self.max))
225 return "TXM de longueur entre %s et %s" %(self.min,self.max)
227 class Valid(PProtocol):
229 Cette classe est la classe mere des validateurs Accas
230 Elle doit etre derivee
231 Elle presente la signature des methodes indispensables pour son bon
232 fonctionnement et dans certains cas leur comportement par défaut.
234 @ivar cata_info: raison de la validite ou de l'invalidite du validateur meme
235 @type cata_info: C{string}
238 def __init__(self,**args):
239 PProtocol.__init__(self,"valid",**args)
243 Cette methode retourne une chaine de caractères informative sur
244 la validation demandée par le validateur. Elle est utilisée
245 pour produire le compte-rendu de validité du mot clé associé.
247 return "valeur valide"
251 Cette methode retourne une chaine de caractère qui permet
252 de construire un message d'aide en ligne.
253 En général, le message retourné est le meme que celui retourné par la
258 def info_erreur_item(self):
260 Cette méthode permet d'avoir un message d'erreur pour un item
261 dans une liste dans le cas ou le validateur fait des vérifications
262 sur les items d'une liste. Si le validateur fait seulement des
263 vérifications sur la liste elle meme et non sur ses items, la méthode
264 doit retourner une chaine vide.
268 def info_erreur_liste(self):
270 Cette méthode a un comportement complémentaire de celui de
271 info_erreur_item. Elle retourne un message d'erreur lié uniquement
272 aux vérifications sur la liste elle meme et pas sur ses items.
273 Dans le cas où le validateur ne fait pas de vérification sur des
274 listes, elle retourne une chaine vide
278 def verif(self,valeur):
280 Cette methode sert a verifier si la valeur passee en argument est consideree
281 comme valide ou non par le validateur. Dans le premier cas le validateur retourne 1
282 (valide) sinon 0 (invalide).
284 @type valeur: tout type python
285 @param valeur: valeur du mot cle a valider
287 @return: indicateur de validite 1 (valide) ou 0 (invalide)
289 raise "Must be implemented"
291 def verif_item(self,valeur):
293 La methode verif du validateur effectue une validation complete de
294 la valeur. valeur peut etre un scalaire ou une liste. Le validateur
295 doit traiter les 2 aspects s'il accepte des listes (dans ce cas la
296 methode is_list doit retourner 1).
297 La methode valid_item sert pour effectuer des validations partielles
298 de liste. Elle doit uniquement verifier la validite d'un item de
299 liste mais pas les caracteristiques de la liste.
303 def valide_liste_partielle(self,liste_courante):
305 Cette methode retourne un entier qui indique si liste_courante est partiellement valide (valeur 1)
306 ou invalide (valeur 0). La validation partielle concerne les listes en cours de construction : on
307 veut savoir si la liste en construction peut etre complétée ou si elle peut déjà etre considérée
309 En général un validateur effectue la meme validation pour les listes partielles et les
312 return self.verif(liste_courante)
314 def verif_cata(self):
316 Cette methode sert a realiser des verifications du validateur lui meme.
317 Elle est facultative et retourne 1 (valide) par defaut.
318 Elle retourne 0 si le validateur est lui meme invalide si par exemple ses
319 parametres de definition ne sont pas corrects.
320 La raison de l'invalidite est stockee dans l'attribut cata_info.
323 @return: indicateur de validite 1 (valide) ou 0 (invalide)
329 Cette méthode retourne un entier qui indique si le validateur
330 permet les listes (valeur 1) ou ne les permet pas (valeur 0).
331 Par défaut, un validateur n'autorise que des scalaires.
337 Cette méthode retourne un entier qui indique si le validateur
338 propose une liste de choix (valeur 1) ou n'en propose pas.
339 Par défaut, un validateur n'en propose pas.
343 def get_into(self,liste_courante=None,into_courant=None):
345 Cette méthode retourne la liste de choix proposée par le validateur.
346 Si le validateur ne propose pas de liste de choix, la méthode
348 L'argument d'entrée liste_courante, s'il est différent de None, donne
349 la liste des choix déjà effectués par l'utilisateur. Dans ce cas, la
350 méthode get_into doit calculer la liste des choix en en tenant
351 compte. Par exemple, si le validateur n'autorise pas les répétitions,
352 la liste des choix retournée ne doit pas contenir les choix déjà
353 contenus dans liste_courante.
354 L'argument d'entrée into_courant, s'il est différent de None, donne
355 la liste des choix proposés par d'autres validateurs. Dans ce cas,
356 la méthode get_into doit calculer la liste des choix à retourner
357 en se limitant à cette liste initiale. Par exemple, si into_courant
358 vaut (1,2,3) et que le validateur propose la liste de choix (3,4,5),
359 la méthode ne doit retourner que (3,).
361 La méthode get_into peut retourner une liste vide [], ce qui veut
362 dire qu'il n'y a pas (ou plus) de choix possible. Cette situation
363 peut etre normale : l''utilisateur a utilisé tous les choix, ou
364 résulter d'une incohérence des validateurs :
365 choix parmi (1,2,3) ET choix parmi (4,5,6). Il est impossible de
366 faire la différence entre ces deux situations.
370 class ListVal(Valid):
372 Cette classe sert de classe mère pour tous les validateurs qui acceptent
378 def get_into(self,liste_courante=None,into_courant=None):
380 Cette méthode get_into effectue un traitement général qui consiste
381 a filtrer la liste de choix into_courant, si elle existe, en ne
382 conservant que les valeurs valides (appel de la méthode valid).
384 if into_courant is None:
388 for e in into_courant:
390 liste_choix.append(e)
393 def convert(self,valeur):
395 Méthode convert pour les validateurs de listes. Cette méthode
396 fait appel à la méthode convert_item sur chaque élément de la
399 if type(valeur) in (types.ListType,types.TupleType):
401 self.convert_item(val)
404 return self.convert_item(valeur)
406 def verif(self,valeur):
408 Méthode verif pour les validateurs de listes. Cette méthode
409 fait appel à la méthode verif_item sur chaque élément de la
410 liste. Si valeur est un paramètre, on utilise sa valeur effective
413 if type(valeur) in (types.ListType,types.TupleType):
415 if not self.verif_item(val):
419 return self.verif_item(valeur)
421 class Compulsory(ListVal):
423 Validateur operationnel
424 Verification de la présence obligatoire d'un élément dans une liste
427 def __init__(self,elem=()):
428 if type(elem) not in (types.ListType,types.TupleType): elem=(elem,)
429 Valid.__init__(self,elem=elem)
434 return "valeur %s obligatoire" % `self.elem`
436 def default(self,valeur,elem):
439 def verif_item(self,valeur):
442 def convert(self,valeur):
446 if v in elem:elem.remove(v)
448 raise ValError("%s ne contient pas les elements obligatoires : %s " %(valeur,elem))
454 def verif(self,valeur):
455 if type(valeur) not in (types.ListType,types.TupleType):
459 for val in self.elem :
460 if val not in liste : return 0
463 def info_erreur_item(self):
464 return "La valeur n'est pas dans la liste des choix possibles"
466 class NoRepeat(ListVal):
468 Validateur operationnel
469 Verification d'absence de doublons dans la liste.
476 return ": pas de présence de doublon dans la liste"
478 def info_erreur_liste(self):
479 return "Les doublons ne sont pas permis"
481 def default(self,valeur):
482 if valeur in self.liste : raise ValError("%s est un doublon" % valeur)
485 def convert(self,valeur):
492 def verif_item(self,valeur):
495 def verif(self,valeur):
496 if type(valeur) in (types.ListType,types.TupleType):
499 if liste.count(val)!=1 : return 0
504 def get_into(self,liste_courante=None,into_courant=None):
506 Methode get_into spécifique pour validateur NoRepeat, on retourne
507 une liste de choix qui ne contient aucune valeur de into_courant
508 déjà contenue dans liste_courante
510 if into_courant is None:
514 for e in into_courant:
515 if e in liste_choix: continue
516 if liste_courante is not None and e in liste_courante: continue
517 liste_choix.append(e)
520 class LongStr(ListVal):
522 Validateur operationnel
523 Verification de la longueur d une chaine
525 def __init__(self,low,high):
526 ListVal.__init__(self,low=low,high=high)
532 return "longueur de la chaine entre %s et %s" %(self.low,self.high)
534 def info_erreur_item(self):
535 return "Longueur de la chaine incorrecte"
537 def convert(self,valeur):
542 def verif_item(self,valeur):
549 def default(self,valeur,low,high):
550 if type(valeur) != types.StringType :
551 raise ValError("%s n'est pas une string" % repr(valeur))
552 if valeur[0]=="'" and valeur[-1]=="'" :
555 if len(valeur) < low or len(valeur) > high :
556 raise ValError("%s n'est pas de la bonne longueur" % repr(valeur))
559 class OrdList(ListVal):
561 Validateur operationnel
562 Verification qu'une liste est croissante ou decroissante
564 def __init__(self,ord):
565 ListVal.__init__(self,ord=ord)
570 return "liste %s" % self.ord
572 def info_erreur_liste(self) :
573 return "La liste doit etre en ordre "+self.ord
575 def convert(self,valeur):
582 def default(self,valeur,ord):
583 if self.ord=='croissant':
584 if self.val is not None and valeur<self.val:
585 raise ValError("%s n'est pas par valeurs croissantes" % repr(self.liste))
586 elif self.ord=='decroissant':
587 if self.val is not None and valeur > self.val:
588 raise ValError("%s n'est pas par valeurs decroissantes" % repr(self.liste))
592 def verif_item(self,valeur):
595 def get_into(self,liste_courante=None,into_courant=None):
597 Methode get_into spécifique pour validateur OrdList, on retourne
598 une liste de choix qui ne contient aucune valeur de into_courant
599 dont la valeur est inférieure à la dernière valeur de
600 liste_courante, si elle est différente de None.
602 if into_courant is None:
604 elif not liste_courante :
608 last_val=liste_choix[-1]
609 for e in into_courant:
610 if self.ord=='croissant' and e <= last_val:continue
611 if self.ord=='decroissant' and e >= last_val:continue
612 liste_choix.append(e)
617 Validateur operationnel
618 Cette classe est un validateur qui controle une liste de validateurs
619 Elle verifie qu'au moins un des validateurs de la liste valide la valeur
621 def __init__(self,validators=()):
622 if type(validators) not in (types.ListType,types.TupleType):
623 validators=(validators,)
625 for validator in validators:
626 if type(validator) == types.FunctionType:
627 self.validators.append(FunctionVal(validator))
629 self.validators.append(validator)
633 return "\n ou ".join([v.info() for v in self.validators])
635 def convert(self,valeur):
636 for validator in self.validators:
638 return validator.convert(valeur)
641 raise ValError("%s n'est pas du bon type" % repr(valeur))
643 def info_erreur_item(self):
645 for v in self.validators:
646 err=v.info_erreur_item()
647 if err != " " : l.append(err)
648 chaine=" \n ou ".join(l)
651 def info_erreur_liste(self):
653 for v in self.validators:
654 err=v.info_erreur_liste()
655 if err != " " : l.append(err)
656 chaine=" \n ou ".join(l)
661 Si plusieurs validateurs sont reliés par un OU
662 il suffit qu'un seul des validateurs attende une liste
663 pour qu'on considère que leur union attend une liste.
665 for validator in self.validators:
666 v=validator.is_list()
671 def verif(self,valeur):
672 for validator in self.validators:
673 v=validator.verif(valeur)
678 def verif_item(self,valeur):
679 for validator in self.validators:
680 v=validator.verif_item(valeur)
685 def verif_cata(self):
687 for validator in self.validators:
688 v=validator.verif_cata()
689 if not v :infos.append(validator.cata_info)
691 self.cata_info="\n".join(infos)
698 Dans le cas ou plusieurs validateurs sont reliés par un OU
699 il faut que tous les validateurs proposent un choix pour
700 qu'on considère que leur union propose un choix.
701 Exemple : Enum(1,2,3) OU entier pair, ne propose pas de choix
702 En revanche, Enum(1,2,3) OU Enum(4,5,6) propose un choix (1,2,3,4,5,6)
704 for validator in self.validators:
705 v=validator.has_into()
710 def get_into(self,liste_courante=None,into_courant=None):
712 Dans le cas ou plusieurs validateurs sont reliés par un OU
713 tous les validateurs doivent proposer un choix pour
714 qu'on considère que leur union propose un choix. Tous les choix
715 proposés par les validateurs sont réunis (opérateur d'union).
716 Exemple : Enum(1,2,3) OU entier pair, ne propose pas de choix
717 En revanche, Enum(1,2,3) OU Enum(4,5,6) propose un
721 for validator in self.validators:
722 v_into=validator.get_into(liste_courante,into_courant)
725 validator_into.extend(v_into)
726 return validator_into
728 def valide_liste_partielle(self,liste_courante=None):
730 Méthode de validation de liste partielle pour le validateur Or.
731 Si un des validateurs gérés par le validateur Or considère la
732 liste comme valide, le validateur Or la considère comme valide.
734 for validator in self.validators:
735 v=validator.valide_liste_partielle(liste_courante)
742 Validateur operationnel
743 Cette classe est un validateur qui controle une liste de validateurs
744 Elle verifie que tous les validateurs de la liste valident la valeur
746 def __init__(self,validators=()):
747 if type(validators) not in (types.ListType,types.TupleType):
748 validators=(validators,)
750 for validator in validators:
751 if type(validator) == types.FunctionType:
752 self.validators.append(FunctionVal(validator))
754 self.validators.append(validator)
758 return "\n et ".join([v.info() for v in self.validators])
760 def convert(self,valeur):
761 for validator in self.validators:
762 valeur=validator.convert(valeur)
765 def info_erreur_item(self):
768 for v in self.validators:
769 if v.info_erreur_item() != " " :
771 chaine=v.info_erreur_item()
774 chaine=chaine+" \n et "+v.info_erreur_item()
777 def info_erreur_liste(self):
779 for v in self.validators:
780 if v.info_erreur_liste() != " " :
782 chaine=v.info_erreur_liste()
785 chaine=chaine+" \n et "+v.info_erreur_liste()
788 def verif(self,valeur):
789 for validator in self.validators:
790 v=validator.verif(valeur)
792 self.local_info=validator.info()
796 def verif_item(self,valeur):
797 for validator in self.validators:
798 v=validator.verif_item(valeur)
800 # L'info n'est probablement pas la meme que pour verif ???
801 self.local_info=validator.info()
805 def verif_cata(self):
807 for validator in self.validators:
808 v=validator.verif_cata()
809 if not v :infos.append(validator.cata_info)
811 self.cata_info="\n".join(infos)
816 def valide_liste_partielle(self,liste_courante=None):
818 Méthode de validation de liste partielle pour le validateur And.
819 Tous les validateurs gérés par le validateur And doivent considérer
820 la liste comme valide, pour que le validateur And la considère
823 for validator in self.validators:
824 v=validator.valide_liste_partielle(liste_courante)
831 Si plusieurs validateurs sont reliés par un ET
832 il faut que tous les validateurs attendent une liste
833 pour qu'on considère que leur intersection attende une liste.
834 Exemple Range(2,5) ET Card(1) n'attend pas une liste
835 Range(2,5) ET Pair attend une liste
837 for validator in self.validators:
838 v=validator.is_list()
845 Dans le cas ou plusieurs validateurs sont reliés par un ET
846 il suffit qu'un seul validateur propose un choix pour
847 qu'on considère que leur intersection propose un choix.
848 Exemple : Enum(1,2,3) ET entier pair, propose un choix
849 En revanche, entier pair ET superieur à 10 ne propose pas de choix
851 for validator in self.validators:
852 v=validator.has_into()
857 def get_into(self,liste_courante=None,into_courant=None):
859 Dans le cas ou plusieurs validateurs sont reliés par un ET
860 il suffit qu'un seul validateur propose un choix pour
861 qu'on considère que leur intersection propose un choix. Tous les
862 choix proposés par les validateurs sont croisés (opérateur
864 Exemple : Enum(1,2,3) ET entier pair, propose un choix (2,)
865 En revanche, Enum(1,2,3) ET Enum(4,5,6) ne propose pas de choix.
867 for validator in self.validators:
868 into_courant=validator.get_into(liste_courante,into_courant)
869 if into_courant in ([],None):break
872 def do_liste(validators):
874 Convertit une arborescence de validateurs en OrVal ou AndVal
875 validators est une liste de validateurs ou de listes ou de tuples
878 for validator in validators:
879 if type(validator) == types.FunctionType:
880 valids.append(FunctionVal(validator))
881 elif type(validator) == types.TupleType:
882 valids.append(OrVal(do_liste(validator)))
883 elif type(validator) == types.ListType:
884 valids.append(AndVal(do_liste(validator)))
886 valids.append(validator)
889 def validatorFactory(validator):
890 if type(validator) == types.FunctionType:
891 return FunctionVal(validator)
892 elif type(validator) == types.TupleType:
893 return OrVal(do_liste(validator))
894 elif type(validator) == types.ListType:
895 return AndVal(do_liste(validator))
899 # Ci-dessous : exemples de validateur (peu testés)
901 class RangeVal(ListVal):
903 Exemple de classe validateur : verification qu'une valeur
904 est dans un intervalle.
905 Pour une liste on verifie que tous les elements sont
907 Susceptible de remplacer les attributs "vale_min" "vale_max"
910 def __init__(self,low,high):
913 self.cata_info="%s doit etre inferieur a %s" %(low,high)
916 return "valeur dans l'intervalle %s , %s" %(self.low,self.high)
918 def convert_item(self,valeur):
919 if valeur > self.low and valeur < self.high:return valeur
920 raise ValError("%s devrait etre comprise entre %s et %s" %(valeur,self.low,self.high))
922 def verif_item(self,valeur):
923 return valeur > self.low and valeur < self.high
925 def info_erreur_item(self) :
926 return "La valeur doit etre comprise entre %s et %s" % (self.low,
929 def verif_cata(self):
930 if self.low > self.high : return 0
933 class CardVal(Valid):
935 Exemple de classe validateur : verification qu'une liste est
936 d'une longueur superieur a un minimum (min) et inferieure
938 Susceptible de remplacer les attributs "min" "max" dans les
941 def __init__(self,min='**',max='**'):
944 self.cata_info="%s doit etre inferieur a %s" % (min,max)
947 return "longueur de liste comprise entre %s et %s" % (self.min,self.max)
949 def info_erreur_liste(self):
950 return "Le cardinal de la liste doit etre compris entre %s et %s" % (self.min,self.max)
953 return self.max == '**' or self.max > 1
955 def get_into(self,liste_courante=None,into_courant=None):
956 if into_courant is None:
958 elif liste_courante is None:
960 elif self.max == '**':
962 elif len(liste_courante) < self.max:
967 def convert(self,valeur):
968 if type(valeur) in (types.ListType,types.TupleType):
974 if self.max != '**' and l > self.max:raise ValError("%s devrait etre de longueur inferieure a %s" %(valeur,self.max))
975 if self.min != '**' and l < self.min:raise ValError("%s devrait etre de longueur superieure a %s" %(valeur,self.min))
978 def verif_item(self,valeur):
981 def verif(self,valeur):
982 if type(valeur) in (types.ListType,types.TupleType):
983 if self.max != '**' and len(valeur) > self.max:return 0
984 if self.min != '**' and len(valeur) < self.min:return 0
987 if self.max != '**' and 1 > self.max:return 0
988 if self.min != '**' and 1 < self.min:return 0
991 def verif_cata(self):
992 if self.min != '**' and self.max != '**' and self.min > self.max : return 0
995 def valide_liste_partielle(self,liste_courante=None):
997 if liste_courante != None :
998 if len(liste_courante) > self.max :
1002 class PairVal(ListVal):
1004 Exemple de classe validateur : verification qu'une valeur
1006 Pour une liste on verifie que tous les elements sont
1010 ListVal.__init__(self)
1014 return "valeur paire"
1016 def info_erreur_item(self):
1017 return "La valeur saisie doit etre paire"
1019 def convert(self,valeur):
1022 if v % 2 != 0:raise ValError("%s contient des valeurs non paires" % repr(valeur))
1025 def default(self,valeur):
1028 def verif_item(self,valeur):
1029 if type(valeur) not in (int,long):
1031 return valeur % 2 == 0
1033 def verif(self,valeur):
1034 if type(valeur) in (types.ListType,types.TupleType):
1036 if val % 2 != 0:return 0
1039 if valeur % 2 != 0:return 0
1042 class EnumVal(ListVal):
1044 Exemple de classe validateur : verification qu'une valeur
1045 est prise dans une liste de valeurs.
1046 Susceptible de remplacer l attribut "into" dans les catalogues
1048 def __init__(self,into=()):
1049 if type(into) not in (types.ListType,types.TupleType): into=(into,)
1054 return "valeur dans %s" % `self.into`
1056 def convert_item(self,valeur):
1057 if valeur in self.into:return valeur
1058 raise ValError("%s contient des valeurs hors des choix possibles: %s " %(valeur,self.into))
1060 def verif_item(self,valeur):
1061 if valeur not in self.into:return 0
1067 def get_into(self,liste_courante=None,into_courant=None):
1068 if into_courant is None:
1069 liste_choix= list(self.into)
1072 for e in into_courant:
1074 liste_choix.append(e)
1077 def info_erreur_item(self):
1078 return "La valeur n'est pas dans la liste des choix possibles"
1080 def ImpairVal(valeur):
1082 Exemple de validateur
1083 Cette fonction est un validateur. Elle verifie que la valeur passee
1084 est bien un nombre impair.
1086 if type(valeur) in (types.ListType,types.TupleType):
1088 if val % 2 != 1:return 0
1091 if valeur % 2 != 1:return 0
1094 ImpairVal.info="valeur impaire"
1098 Exemple de validateur
1099 Cette classe est un validateur de dictionnaire (mot cle facteur ?). Elle verifie
1100 que la somme des cles A et B vaut une valeur donnee
1101 en parametre du validateur
1103 def __init__(self,somme=10):
1108 return "valeur %s pour la somme des cles A et B " % self.somme
1110 def verif(self,valeur):
1111 if type(valeur) in (types.ListType,types.TupleType):
1113 if not val.has_key("A"):return 0
1114 if not val.has_key("B"):return 0
1115 if val["A"]+val["B"] != self.somme:return 0
1118 if not valeur.has_key("A"):return 0
1119 if not valeur.has_key("B"):return 0
1120 if valeur["A"]+valeur["B"] != self.somme:return 0
1123 class FunctionVal(Valid):
1125 Exemple de validateur
1126 Cette classe est un validateur qui est initialise avec une fonction
1128 def __init__(self,function):
1129 self.function=function
1132 return self.function.info
1134 def verif(self,valeur):
1135 return self.function(valeur)
1137 #MC ca ne devrait plus servir !
1138 CoercableFuncs = { types.IntType: int,
1139 types.LongType: long,
1140 types.FloatType: float,
1141 types.ComplexType: complex,
1142 types.UnicodeType: unicode }
1144 class TypeVal(ListVal):
1146 Exemple de validateur
1147 Cette classe est un validateur qui controle qu'une valeur
1148 est bien du type Python attendu.
1149 Pour une liste on verifie que tous les elements sont du bon type.
1150 Semblable a InstanceVal mais ici on fait le test par tentative de conversion
1151 alors qu'avec InstanceVal on ne teste que si isinstance est vrai.
1153 def __init__(self, aType):
1154 #Si aType n'est pas un type, on le retrouve a l'aide de la fonction type
1155 #type(1) == int;type(0.2)==float;etc.
1156 if type(aType) != types.TypeType:
1160 self.coerce=CoercableFuncs[ aType ]
1162 self.coerce = self.identity
1165 return "valeur de %s" % self.aType
1167 def identity ( self, value ):
1168 if type( value ) == self.aType:
1172 def convert_item(self,valeur):
1173 return self.coerce(valeur)
1175 def verif_item(self,valeur):
1182 class InstanceVal(ListVal):
1184 Exemple de validateur
1185 Cette classe est un validateur qui controle qu'une valeur est
1186 bien une instance (au sens Python) d'une classe
1187 Pour une liste on verifie chaque element de la liste
1189 def __init__(self,aClass):
1190 #Si aClass est une classe on la memorise dans self.aClass
1191 #sinon c'est une instance dont on memorise la classe
1192 if type(aClass) == types.InstanceType:
1193 #instance ancienne mode
1194 aClass=aClass.__class__
1195 elif type(aClass) == types.ClassType:
1196 #classe ancienne mode
1198 elif type(aClass) == type:
1199 #classe nouvelle mode
1201 elif isinstance(aClass,object):
1202 #instance nouvelle mode
1205 raise ValError("type non supporte")
1210 return "valeur d'instance de %s" % self.aClass.__name__
1212 def verif_item(self,valeur):
1213 if not isinstance(valeur,self.aClass): return 0