1 #@ MODIF N_VALIDATOR Noyau DATE 16/05/2006 AUTEUR DURAND C.DURAND
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
29 class ValError(Exception):pass
32 if hasattr(cls,"__mro__"):return cls.__mro__
34 for base in cls.__bases__:
35 mro.extend(cls_mro(base))
39 def __init__(self,name):
44 def register(self, T, A):
48 # (a) verifier si l'objet peut s'adapter au protocole
49 adapt = getattr(obj, '__adapt__', None)
51 # on demande à l'objet obj de réaliser lui-meme l'adaptation
54 # (b) verifier si un adapteur est enregistré (si oui l'utiliser)
56 for T in cls_mro(obj.__class__):
57 if T in self.registry:
58 return self.registry[T](obj,self,**self.args)
60 # (c) utiliser l'adapteur par defaut
61 return self.default(obj,**self.args)
63 def default(self,obj,**args):
64 raise TypeError("Can't adapt %s to %s" %
65 (obj.__class__.__name__, self.name))
67 class PProtocol(Protocol):
68 """Verificateur de protocole paramétré (classe de base)"""
69 #Protocole paramétré. Le registre est unique pour toutes les instances. La methode register est une methode de classe
71 def __init__(self,name,**args):
74 def register(cls, T, A):
76 register=classmethod(register)
78 class ListProtocol(Protocol):
79 """Verificateur de protocole liste : convertit un objet quelconque en liste pour validation ultérieure"""
80 def default(self,obj):
81 if type(obj) == types.TupleType :
82 if obj[0] in ('RI','MP'):
83 #il s'agit d'un complexe ancienne mode. La cardinalite vaut 1
87 elif type(obj) == types.ListType :
90 # pas de valeur affecte. La cardinalite vaut 0
92 elif type(obj) == types.StringType :
93 #il s'agit d'une chaine. La cardinalite vaut 1
97 # si l'objet supporte len, on a la cardinalite
104 listProto=ListProtocol("list")
106 class TypeProtocol(PProtocol):
107 """Verificateur de type parmi une liste de types possibles"""
108 #pas de registre par instance. Registre unique pour toutes les instances de TypeProtocol
110 def __init__(self,name,typ=None):
111 PProtocol.__init__(self,name,typ=typ)
114 def default(self,obj,typ):
115 for type_permis in typ:
116 if type_permis == 'R':
117 if type(obj) in (types.IntType,types.FloatType,types.LongType):return obj
118 elif type_permis == 'I':
119 if type(obj) in (types.IntType,types.LongType):return obj
120 elif type_permis == 'C':
121 if self.is_complexe(obj):return obj
122 elif type_permis == 'TXM':
123 if type(obj)==types.StringType:return obj
124 elif type_permis == 'shell':
125 if type(obj)==types.StringType:return obj
126 elif type(type_permis) == types.ClassType:
127 if self.is_object_from(obj,type_permis):return obj
128 elif type(type_permis) == types.InstanceType:
130 if type_permis.__convert__(obj) : return obj
134 print "Type non encore géré %s" %`type_permis`
136 raise ValError("%s n'est pas d'un type autorisé: %s" % (repr(obj),typ))
138 def is_complexe(self,valeur):
139 """ Retourne 1 si valeur est un complexe, 0 sinon """
140 if type(valeur) in (types.ComplexType,types.IntType,types.FloatType,types.LongType):
141 # Pour permettre l'utilisation de complexes Python
143 elif type(valeur) != types.TupleType :
144 # On n'autorise pas les listes pour les complexes
146 elif len(valeur) != 3:
149 # Un complexe doit etre un tuple de longueur 3 avec 'RI' ou 'MP' comme premiere
150 # valeur suivie de 2 reels.
151 if string.strip(valeur[0]) in ('RI','MP'):
153 v1=reelProto.adapt(valeur[1]),reelProto.adapt(valeur[2])
160 def is_object_from(self,objet,classe):
162 Retourne 1 si objet est une instance de la classe classe, 0 sinon
164 convert = getattr(classe, '__convert__', None)
165 if convert is not None:
166 # classe verifie les valeurs
172 # On accepte les instances de la classe et des classes derivees
173 return type(objet) == types.InstanceType and isinstance(objet,classe)
175 reelProto=TypeProtocol("reel",typ=('R',))
177 class CardProtocol(PProtocol):
178 """Verificateur de cardinalité """
179 #pas de registre par instance. Registre unique pour toutes les instances
181 def __init__(self,name,min=1,max=1):
182 PProtocol.__init__(self,name,min=min,max=max)
184 def default(self,obj,min,max):
186 if length < min or length >max:
187 raise ValError("Nombre d'arguments de %s incorrect (min = %s, max = %s)" % (repr(obj),min,max) )
190 class IntoProtocol(PProtocol):
191 """Verificateur de choix possibles : liste discrète ou intervalle"""
192 #pas de registre par instance. Registre unique pour toutes les instances
194 def __init__(self,name,into=None,val_min='**',val_max='**'):
195 PProtocol.__init__(self,name,into=into,val_min=val_min,val_max=val_max)
199 def default(self,obj,into,val_min,val_max):
202 raise ValError("La valeur : %s ne fait pas partie des choix possibles %s" % (repr(obj),into) )
204 #on est dans le cas d'un ensemble continu de valeurs possibles (intervalle)
205 if type(obj) in (types.IntType,types.FloatType,types.LongType) :
206 if val_min == '**': val_min = obj -1
207 if val_max == '**': val_max = obj +1
208 if obj < val_min or obj > val_max :
209 raise ValError("La valeur : %s est en dehors du domaine de validité [ %s , %s ]" % (repr(obj),self.val_min,self.val_max) )
213 #exemple de classe pour verificateur de type
214 #on utilise des instances de classe comme type (typ=MinStr(3,6), par exemple)
215 def __init__(self,min,max):
219 def __convert__(self,valeur):
220 if type(valeur) == types.StringType and self.min <= len(valeur) <= self.max:return valeur
221 raise ValError("%s n'est pas une chaine de longueur comprise entre %s et %s" % (valeur,self.min,self.max))
224 return "TXM de longueur entre %s et %s" %(self.min,self.max)
226 class Valid(PProtocol):
228 Cette classe est la classe mere des validateurs Accas
229 Elle doit etre derivee
230 Elle presente la signature des methodes indispensables pour son bon
231 fonctionnement et dans certains cas leur comportement par défaut.
233 @ivar cata_info: raison de la validite ou de l'invalidite du validateur meme
234 @type cata_info: C{string}
237 def __init__(self,**args):
238 PProtocol.__init__(self,"valid",**args)
242 Cette methode retourne une chaine de caractères informative sur
243 la validation demandée par le validateur. Elle est utilisée
244 pour produire le compte-rendu de validité du mot clé associé.
246 return "valeur valide"
250 Cette methode retourne une chaine de caractère qui permet
251 de construire un message d'aide en ligne.
252 En général, le message retourné est le meme que celui retourné par la
257 def info_erreur_item(self):
259 Cette méthode permet d'avoir un message d'erreur pour un item
260 dans une liste dans le cas ou le validateur fait des vérifications
261 sur les items d'une liste. Si le validateur fait seulement des
262 vérifications sur la liste elle meme et non sur ses items, la méthode
263 doit retourner une chaine vide.
267 def info_erreur_liste(self):
269 Cette méthode a un comportement complémentaire de celui de
270 info_erreur_item. Elle retourne un message d'erreur lié uniquement
271 aux vérifications sur la liste elle meme et pas sur ses items.
272 Dans le cas où le validateur ne fait pas de vérification sur des
273 listes, elle retourne une chaine vide
277 def verif(self,valeur):
279 Cette methode sert a verifier si la valeur passee en argument est consideree
280 comme valide ou non par le validateur. Dans le premier cas le validateur retourne 1
281 (valide) sinon 0 (invalide).
283 @type valeur: tout type python
284 @param valeur: valeur du mot cle a valider
286 @return: indicateur de validite 1 (valide) ou 0 (invalide)
288 raise "Must be implemented"
290 def verif_item(self,valeur):
292 La methode verif du validateur effectue une validation complete de
293 la valeur. valeur peut etre un scalaire ou une liste. Le validateur
294 doit traiter les 2 aspects s'il accepte des listes (dans ce cas la
295 methode is_list doit retourner 1).
296 La methode valid_item sert pour effectuer des validations partielles
297 de liste. Elle doit uniquement verifier la validite d'un item de
298 liste mais pas les caracteristiques de la liste.
302 def valide_liste_partielle(self,liste_courante):
304 Cette methode retourne un entier qui indique si liste_courante est partiellement valide (valeur 1)
305 ou invalide (valeur 0). La validation partielle concerne les listes en cours de construction : on
306 veut savoir si la liste en construction peut etre complétée ou si elle peut déjà etre considérée
308 En général un validateur effectue la meme validation pour les listes partielles et les
311 return self.verif(liste_courante)
313 def verif_cata(self):
315 Cette methode sert a realiser des verifications du validateur lui meme.
316 Elle est facultative et retourne 1 (valide) par defaut.
317 Elle retourne 0 si le validateur est lui meme invalide si par exemple ses
318 parametres de definition ne sont pas corrects.
319 La raison de l'invalidite est stockee dans l'attribut cata_info.
322 @return: indicateur de validite 1 (valide) ou 0 (invalide)
328 Cette méthode retourne un entier qui indique si le validateur
329 permet les listes (valeur 1) ou ne les permet pas (valeur 0).
330 Par défaut, un validateur n'autorise que des scalaires.
336 Cette méthode retourne un entier qui indique si le validateur
337 propose une liste de choix (valeur 1) ou n'en propose pas.
338 Par défaut, un validateur n'en propose pas.
342 def get_into(self,liste_courante=None,into_courant=None):
344 Cette méthode retourne la liste de choix proposée par le validateur.
345 Si le validateur ne propose pas de liste de choix, la méthode
347 L'argument d'entrée liste_courante, s'il est différent de None, donne
348 la liste des choix déjà effectués par l'utilisateur. Dans ce cas, la
349 méthode get_into doit calculer la liste des choix en en tenant
350 compte. Par exemple, si le validateur n'autorise pas les répétitions,
351 la liste des choix retournée ne doit pas contenir les choix déjà
352 contenus dans liste_courante.
353 L'argument d'entrée into_courant, s'il est différent de None, donne
354 la liste des choix proposés par d'autres validateurs. Dans ce cas,
355 la méthode get_into doit calculer la liste des choix à retourner
356 en se limitant à cette liste initiale. Par exemple, si into_courant
357 vaut (1,2,3) et que le validateur propose la liste de choix (3,4,5),
358 la méthode ne doit retourner que (3,).
360 La méthode get_into peut retourner une liste vide [], ce qui veut
361 dire qu'il n'y a pas (ou plus) de choix possible. Cette situation
362 peut etre normale : l''utilisateur a utilisé tous les choix, ou
363 résulter d'une incohérence des validateurs :
364 choix parmi (1,2,3) ET choix parmi (4,5,6). Il est impossible de
365 faire la différence entre ces deux situations.
369 class ListVal(Valid):
371 Cette classe sert de classe mère pour tous les validateurs qui acceptent
377 def get_into(self,liste_courante=None,into_courant=None):
379 Cette méthode get_into effectue un traitement général qui consiste
380 a filtrer la liste de choix into_courant, si elle existe, en ne
381 conservant que les valeurs valides (appel de la méthode valid).
383 if into_courant is None:
387 for e in into_courant:
389 liste_choix.append(e)
392 def convert(self,valeur):
394 Méthode convert pour les validateurs de listes. Cette méthode
395 fait appel à la méthode convert_item sur chaque élément de la
398 if type(valeur) in (types.ListType,types.TupleType):
400 self.convert_item(val)
403 return self.convert_item(valeur)
405 def verif(self,valeur):
407 Méthode verif pour les validateurs de listes. Cette méthode
408 fait appel à la méthode verif_item sur chaque élément de la
409 liste. Si valeur est un paramètre, on utilise sa valeur effective
412 if type(valeur) in (types.ListType,types.TupleType):
414 if not self.verif_item(val):
418 return self.verif_item(valeur)
420 class Compulsory(ListVal):
422 Validateur operationnel
423 Verification de la présence obligatoire d'un élément dans une liste
426 def __init__(self,elem=()):
427 if type(elem) not in (types.ListType,types.TupleType): elem=(elem,)
428 Valid.__init__(self,elem=elem)
433 return "valeur %s obligatoire" % `self.elem`
435 def default(self,valeur,elem):
438 def verif_item(self,valeur):
441 def convert(self,valeur):
445 if v in elem:elem.remove(v)
447 raise ValError("%s ne contient pas les elements obligatoires : %s " %(valeur,elem))
453 def verif(self,valeur):
454 if type(valeur) not in (types.ListType,types.TupleType):
458 for val in self.elem :
459 if val not in liste : return 0
462 def info_erreur_item(self):
463 return "La valeur n'est pas dans la liste des choix possibles"
465 class NoRepeat(ListVal):
467 Validateur operationnel
468 Verification d'absence de doublons dans la liste.
475 return ": pas de présence de doublon dans la liste"
477 def info_erreur_liste(self):
478 return "Les doublons ne sont pas permis"
480 def default(self,valeur):
481 if valeur in self.liste : raise ValError("%s est un doublon" % valeur)
484 def convert(self,valeur):
491 def verif_item(self,valeur):
494 def verif(self,valeur):
495 if type(valeur) in (types.ListType,types.TupleType):
498 if liste.count(val)!=1 : return 0
503 def get_into(self,liste_courante=None,into_courant=None):
505 Methode get_into spécifique pour validateur NoRepeat, on retourne
506 une liste de choix qui ne contient aucune valeur de into_courant
507 déjà contenue dans liste_courante
509 if into_courant is None:
513 for e in into_courant:
514 if e in liste_choix: continue
515 if liste_courante is not None and e in liste_courante: continue
516 liste_choix.append(e)
519 class LongStr(ListVal):
521 Validateur operationnel
522 Verification de la longueur d une chaine
524 def __init__(self,low,high):
525 ListVal.__init__(self,low=low,high=high)
531 return "longueur de la chaine entre %s et %s" %(self.low,self.high)
533 def info_erreur_item(self):
534 return "Longueur de la chaine incorrecte"
536 def convert(self,valeur):
541 def verif_item(self,valeur):
548 def default(self,valeur,low,high):
549 if type(valeur) != types.StringType :
550 raise ValError("%s n'est pas une string" % repr(valeur))
551 if valeur[0]=="'" and valeur[-1]=="'" :
554 if len(valeur) < low or len(valeur) > high :
555 raise ValError("%s n'est pas de la bonne longueur" % repr(valeur))
558 class OrdList(ListVal):
560 Validateur operationnel
561 Verification qu'une liste est croissante ou decroissante
563 def __init__(self,ord):
564 ListVal.__init__(self,ord=ord)
569 return "liste %s" % self.ord
571 def info_erreur_liste(self) :
572 return "La liste doit etre en ordre "+self.ord
574 def convert(self,valeur):
581 def default(self,valeur,ord):
582 if self.ord=='croissant':
583 if self.val is not None and valeur<self.val:
584 raise ValError("%s n'est pas par valeurs croissantes" % repr(self.liste))
585 elif self.ord=='decroissant':
586 if self.val is not None and valeur > self.val:
587 raise ValError("%s n'est pas par valeurs decroissantes" % repr(self.liste))
591 def verif_item(self,valeur):
594 def get_into(self,liste_courante=None,into_courant=None):
596 Methode get_into spécifique pour validateur OrdList, on retourne
597 une liste de choix qui ne contient aucune valeur de into_courant
598 dont la valeur est inférieure à la dernière valeur de
599 liste_courante, si elle est différente de None.
601 if into_courant is None:
603 elif not liste_courante :
607 last_val=liste_choix[-1]
608 for e in into_courant:
609 if self.ord=='croissant' and e <= last_val:continue
610 if self.ord=='decroissant' and e >= last_val:continue
611 liste_choix.append(e)
616 Validateur operationnel
617 Cette classe est un validateur qui controle une liste de validateurs
618 Elle verifie qu'au moins un des validateurs de la liste valide la valeur
620 def __init__(self,validators=()):
621 if type(validators) not in (types.ListType,types.TupleType):
622 validators=(validators,)
624 for validator in validators:
625 if type(validator) == types.FunctionType:
626 self.validators.append(FunctionVal(validator))
628 self.validators.append(validator)
632 return "\n ou ".join([v.info() for v in self.validators])
634 def convert(self,valeur):
635 for validator in self.validators:
637 return validator.convert(valeur)
640 raise ValError("%s n'est pas du bon type" % repr(valeur))
642 def info_erreur_item(self):
644 for v in self.validators:
645 err=v.info_erreur_item()
646 if err != " " : l.append(err)
647 chaine=" \n ou ".join(l)
650 def info_erreur_liste(self):
652 for v in self.validators:
653 err=v.info_erreur_liste()
654 if err != " " : l.append(err)
655 chaine=" \n ou ".join(l)
660 Si plusieurs validateurs sont reliés par un OU
661 il suffit qu'un seul des validateurs attende une liste
662 pour qu'on considère que leur union attend une liste.
664 for validator in self.validators:
665 v=validator.is_list()
670 def verif(self,valeur):
671 for validator in self.validators:
672 v=validator.verif(valeur)
677 def verif_item(self,valeur):
678 for validator in self.validators:
679 v=validator.verif_item(valeur)
684 def verif_cata(self):
686 for validator in self.validators:
687 v=validator.verif_cata()
688 if not v :infos.append(validator.cata_info)
690 self.cata_info="\n".join(infos)
697 Dans le cas ou plusieurs validateurs sont reliés par un OU
698 il faut que tous les validateurs proposent un choix pour
699 qu'on considère que leur union propose un choix.
700 Exemple : Enum(1,2,3) OU entier pair, ne propose pas de choix
701 En revanche, Enum(1,2,3) OU Enum(4,5,6) propose un choix (1,2,3,4,5,6)
703 for validator in self.validators:
704 v=validator.has_into()
709 def get_into(self,liste_courante=None,into_courant=None):
711 Dans le cas ou plusieurs validateurs sont reliés par un OU
712 tous les validateurs doivent proposer un choix pour
713 qu'on considère que leur union propose un choix. Tous les choix
714 proposés par les validateurs sont réunis (opérateur d'union).
715 Exemple : Enum(1,2,3) OU entier pair, ne propose pas de choix
716 En revanche, Enum(1,2,3) OU Enum(4,5,6) propose un
720 for validator in self.validators:
721 v_into=validator.get_into(liste_courante,into_courant)
724 validator_into.extend(v_into)
725 return validator_into
727 def valide_liste_partielle(self,liste_courante=None):
729 Méthode de validation de liste partielle pour le validateur Or.
730 Si un des validateurs gérés par le validateur Or considère la
731 liste comme valide, le validateur Or la considère comme valide.
733 for validator in self.validators:
734 v=validator.valide_liste_partielle(liste_courante)
741 Validateur operationnel
742 Cette classe est un validateur qui controle une liste de validateurs
743 Elle verifie que tous les validateurs de la liste valident la valeur
745 def __init__(self,validators=()):
746 if type(validators) not in (types.ListType,types.TupleType):
747 validators=(validators,)
749 for validator in validators:
750 if type(validator) == types.FunctionType:
751 self.validators.append(FunctionVal(validator))
753 self.validators.append(validator)
757 return "\n et ".join([v.info() for v in self.validators])
759 def convert(self,valeur):
760 for validator in self.validators:
761 valeur=validator.convert(valeur)
764 def info_erreur_item(self):
767 for v in self.validators:
768 if v.info_erreur_item() != " " :
770 chaine=v.info_erreur_item()
773 chaine=chaine+" \n et "+v.info_erreur_item()
776 def info_erreur_liste(self):
778 for v in self.validators:
779 if v.info_erreur_liste() != " " :
781 chaine=v.info_erreur_liste()
784 chaine=chaine+" \n et "+v.info_erreur_liste()
787 def verif(self,valeur):
788 for validator in self.validators:
789 v=validator.verif(valeur)
791 self.local_info=validator.info()
795 def verif_item(self,valeur):
796 for validator in self.validators:
797 v=validator.verif_item(valeur)
799 # L'info n'est probablement pas la meme que pour verif ???
800 self.local_info=validator.info()
804 def verif_cata(self):
806 for validator in self.validators:
807 v=validator.verif_cata()
808 if not v :infos.append(validator.cata_info)
810 self.cata_info="\n".join(infos)
815 def valide_liste_partielle(self,liste_courante=None):
817 Méthode de validation de liste partielle pour le validateur And.
818 Tous les validateurs gérés par le validateur And doivent considérer
819 la liste comme valide, pour que le validateur And la considère
822 for validator in self.validators:
823 v=validator.valide_liste_partielle(liste_courante)
830 Si plusieurs validateurs sont reliés par un ET
831 il faut que tous les validateurs attendent une liste
832 pour qu'on considère que leur intersection attende une liste.
833 Exemple Range(2,5) ET Card(1) n'attend pas une liste
834 Range(2,5) ET Pair attend une liste
836 for validator in self.validators:
837 v=validator.is_list()
844 Dans le cas ou plusieurs validateurs sont reliés par un ET
845 il suffit qu'un seul validateur propose un choix pour
846 qu'on considère que leur intersection propose un choix.
847 Exemple : Enum(1,2,3) ET entier pair, propose un choix
848 En revanche, entier pair ET superieur à 10 ne propose pas de choix
850 for validator in self.validators:
851 v=validator.has_into()
856 def get_into(self,liste_courante=None,into_courant=None):
858 Dans le cas ou plusieurs validateurs sont reliés par un ET
859 il suffit qu'un seul validateur propose un choix pour
860 qu'on considère que leur intersection propose un choix. Tous les
861 choix proposés par les validateurs sont croisés (opérateur
863 Exemple : Enum(1,2,3) ET entier pair, propose un choix (2,)
864 En revanche, Enum(1,2,3) ET Enum(4,5,6) ne propose pas de choix.
866 for validator in self.validators:
867 into_courant=validator.get_into(liste_courante,into_courant)
868 if into_courant in ([],None):break
871 def do_liste(validators):
873 Convertit une arborescence de validateurs en OrVal ou AndVal
874 validators est une liste de validateurs ou de listes ou de tuples
877 for validator in validators:
878 if type(validator) == types.FunctionType:
879 valids.append(FunctionVal(validator))
880 elif type(validator) == types.TupleType:
881 valids.append(OrVal(do_liste(validator)))
882 elif type(validator) == types.ListType:
883 valids.append(AndVal(do_liste(validator)))
885 valids.append(validator)
888 def validatorFactory(validator):
889 if type(validator) == types.FunctionType:
890 return FunctionVal(validator)
891 elif type(validator) == types.TupleType:
892 return OrVal(do_liste(validator))
893 elif type(validator) == types.ListType:
894 return AndVal(do_liste(validator))
898 # Ci-dessous : exemples de validateur (peu testés)
900 class RangeVal(ListVal):
902 Exemple de classe validateur : verification qu'une valeur
903 est dans un intervalle.
904 Pour une liste on verifie que tous les elements sont
906 Susceptible de remplacer les attributs "vale_min" "vale_max"
909 def __init__(self,low,high):
912 self.cata_info="%s doit etre inferieur a %s" %(low,high)
915 return "valeur dans l'intervalle %s , %s" %(self.low,self.high)
917 def convert_item(self,valeur):
918 if valeur > self.low and valeur < self.high:return valeur
919 raise ValError("%s devrait etre comprise entre %s et %s" %(valeur,self.low,self.high))
921 def verif_item(self,valeur):
922 return valeur > self.low and valeur < self.high
924 def info_erreur_item(self) :
925 return "La valeur doit etre comprise entre %s et %s" % (self.low,
928 def verif_cata(self):
929 if self.low > self.high : return 0
932 class CardVal(Valid):
934 Exemple de classe validateur : verification qu'une liste est
935 d'une longueur superieur a un minimum (min) et inferieure
937 Susceptible de remplacer les attributs "min" "max" dans les
940 def __init__(self,min='**',max='**'):
943 self.cata_info="%s doit etre inferieur a %s" % (min,max)
946 return "longueur de liste comprise entre %s et %s" % (self.min,self.max)
948 def info_erreur_liste(self):
949 return "Le cardinal de la liste doit etre compris entre %s et %s" % (self.min,self.max)
952 return self.max == '**' or self.max > 1
954 def get_into(self,liste_courante=None,into_courant=None):
955 if into_courant is None:
957 elif liste_courante is None:
959 elif self.max == '**':
961 elif len(liste_courante) < self.max:
966 def convert(self,valeur):
967 if type(valeur) in (types.ListType,types.TupleType):
973 if self.max != '**' and l > self.max:raise ValError("%s devrait etre de longueur inferieure a %s" %(valeur,self.max))
974 if self.min != '**' and l < self.min:raise ValError("%s devrait etre de longueur superieure a %s" %(valeur,self.min))
977 def verif_item(self,valeur):
980 def verif(self,valeur):
981 if type(valeur) in (types.ListType,types.TupleType):
982 if self.max != '**' and len(valeur) > self.max:return 0
983 if self.min != '**' and len(valeur) < self.min:return 0
986 if self.max != '**' and 1 > self.max:return 0
987 if self.min != '**' and 1 < self.min:return 0
990 def verif_cata(self):
991 if self.min != '**' and self.max != '**' and self.min > self.max : return 0
994 def valide_liste_partielle(self,liste_courante=None):
996 if liste_courante != None :
997 if len(liste_courante) > self.max :
1001 class PairVal(ListVal):
1003 Exemple de classe validateur : verification qu'une valeur
1005 Pour une liste on verifie que tous les elements sont
1009 ListVal.__init__(self)
1013 return "valeur paire"
1015 def info_erreur_item(self):
1016 return "La valeur saisie doit etre paire"
1018 def convert(self,valeur):
1021 if v % 2 != 0:raise ValError("%s contient des valeurs non paires" % repr(valeur))
1024 def default(self,valeur):
1027 def verif_item(self,valeur):
1028 if type(valeur) == types.InstanceType:
1030 return valeur % 2 == 0
1032 def verif(self,valeur):
1033 if type(valeur) in (types.ListType,types.TupleType):
1035 if val % 2 != 0:return 0
1038 if valeur % 2 != 0:return 0
1041 class EnumVal(ListVal):
1043 Exemple de classe validateur : verification qu'une valeur
1044 est prise dans une liste de valeurs.
1045 Susceptible de remplacer l attribut "into" dans les catalogues
1047 def __init__(self,into=()):
1048 if type(into) not in (types.ListType,types.TupleType): into=(into,)
1053 return "valeur dans %s" % `self.into`
1055 def convert_item(self,valeur):
1056 if valeur in self.into:return valeur
1057 raise ValError("%s contient des valeurs hors des choix possibles: %s " %(valeur,self.into))
1059 def verif_item(self,valeur):
1060 if valeur not in self.into:return 0
1066 def get_into(self,liste_courante=None,into_courant=None):
1067 if into_courant is None:
1068 liste_choix= list(self.into)
1071 for e in into_courant:
1073 liste_choix.append(e)
1076 def info_erreur_item(self):
1077 return "La valeur n'est pas dans la liste des choix possibles"
1079 def ImpairVal(valeur):
1081 Exemple de validateur
1082 Cette fonction est un validateur. Elle verifie que la valeur passee
1083 est bien un nombre impair.
1085 if type(valeur) in (types.ListType,types.TupleType):
1087 if val % 2 != 1:return 0
1090 if valeur % 2 != 1:return 0
1093 ImpairVal.info="valeur impaire"
1097 Exemple de validateur
1098 Cette classe est un validateur de dictionnaire (mot cle facteur ?). Elle verifie
1099 que la somme des cles A et B vaut une valeur donnee
1100 en parametre du validateur
1102 def __init__(self,somme=10):
1107 return "valeur %s pour la somme des cles A et B " % self.somme
1109 def verif(self,valeur):
1110 if type(valeur) in (types.ListType,types.TupleType):
1112 if not val.has_key("A"):return 0
1113 if not val.has_key("B"):return 0
1114 if val["A"]+val["B"] != self.somme:return 0
1117 if not valeur.has_key("A"):return 0
1118 if not valeur.has_key("B"):return 0
1119 if valeur["A"]+valeur["B"] != self.somme:return 0
1122 class FunctionVal(Valid):
1124 Exemple de validateur
1125 Cette classe est un validateur qui est initialise avec une fonction
1127 def __init__(self,function):
1128 self.function=function
1131 return self.function.info
1133 def verif(self,valeur):
1134 return self.function(valeur)
1136 CoercableFuncs = { types.IntType: int,
1137 types.LongType: long,
1138 types.FloatType: float,
1139 types.ComplexType: complex,
1140 types.UnicodeType: unicode }
1142 class TypeVal(ListVal):
1144 Exemple de validateur
1145 Cette classe est un validateur qui controle qu'une valeur
1146 est bien du type Python attendu.
1147 Pour une liste on verifie que tous les elements sont du bon type.
1149 def __init__(self, aType):
1150 if type(aType) != types.TypeType:
1154 self.coerce=CoercableFuncs[ aType ]
1156 self.coerce = self.identity
1159 return "valeur de %s" % self.aType
1161 def identity ( self, value ):
1162 if type( value ) == self.aType:
1166 def convert_item(self,valeur):
1167 return self.coerce(valeur)
1169 def verif_item(self,valeur):
1176 class InstanceVal(ListVal):
1178 Exemple de validateur
1179 Cette classe est un validateur qui controle qu'une valeur est
1180 bien une instance (au sens Python) d'une classe
1181 Pour une liste on verifie chaque element de la liste
1183 def __init__(self,aClass):
1184 if type(aClass) == types.InstanceType:
1185 aClass=aClass.__class__
1189 return "valeur d'instance de %s" % self.aClass.__name__
1191 def verif_item(self,valeur):
1192 if not isinstance(valeur,self.aClass): return 0