]> SALOME platform Git repositories - modules/eficas.git/commitdiff
Salome HOME
CCAR: adaptation pour validation parametres
authoreficas <>
Mon, 23 Jan 2006 09:41:11 +0000 (09:41 +0000)
committereficas <>
Mon, 23 Jan 2006 09:41:11 +0000 (09:41 +0000)
17 files changed:
Accas/A_ASSD.py
Accas/A_VALIDATOR.py
Accas/__init__.py
Editeur/appli.py
Editeur/composimp.py
Editeur/uniqueassdpanel.py
Extensions/commande_comm.py
Extensions/jdc_include.py
Extensions/param2.py
Extensions/parametre.py
Ihm/I_ASSD.py
Ihm/I_ETAPE.py
Ihm/I_FONCTION.py
Ihm/I_JDC.py
Ihm/I_MACRO_ETAPE.py
Ihm/I_MCSIMP.py
Ihm/I_VALIDATOR.py

index e8669988ae12df79e1832f709f00d9278338afc7..2968709f2a2310a1edd705efa725c3d764ea6e24 100644 (file)
@@ -37,7 +37,7 @@ class ASSD(N_ASSD.ASSD,I_ASSD.ASSD):pass
 #class LASSD(I_LASSD.LASSD,N_LASSD.LASSD):pass
 class LASSD(I_LASSD.LASSD):pass
 
-class assd(N_ASSD.assd,I_ASSD.ASSD,ASSD):pass
+class assd(N_ASSD.assd,I_ASSD.assd,ASSD):pass
 
 class FONCTION(N_FONCTION.FONCTION,I_FONCTION.FONCTION,ASSD):
    def __init__(self,etape=None,sd=None,reg='oui'):
@@ -56,6 +56,6 @@ class fonction(N_FONCTION.formule,I_FONCTION.fonction,ASSD):
       N_FONCTION.formule.__init__(self,etape=etape,sd=sd,reg=reg)
       I_FONCTION.fonction.__init__(self,etape=etape,sd=sd,reg=reg)
 
-class GEOM(N_GEOM.GEOM,I_ASSD.ASSD,ASSD):pass
-class geom(N_GEOM.geom,I_ASSD.ASSD,ASSD):pass
-class CO(N_CO.CO,I_ASSD.ASSD,ASSD):pass
+class GEOM(N_GEOM.GEOM,I_ASSD.GEOM,ASSD):pass
+class geom(N_GEOM.geom,I_ASSD.geom,ASSD):pass
+class CO(N_CO.CO,I_ASSD.CO,ASSD):pass
index c127c965c8b4fee62c6a1413af6ecc94fc0670f9..2f0d29787596e8ead479558a17531b0b9ddbe35d 100644 (file)
@@ -2,6 +2,7 @@
 import types
 from Noyau import N_VALIDATOR
 from Ihm import I_VALIDATOR
+from Ihm.I_VALIDATOR import ValidException
 
 class FunctionVal(I_VALIDATOR.FunctionVal,N_VALIDATOR.FunctionVal):pass
 class OrVal(I_VALIDATOR.OrVal,N_VALIDATOR.OrVal):pass
index 28d0e17905d17ea0bfc5196ac78ced2770d32c0c..1eb50497f05a8ba86f2ba3d84a5f757c17e3e418 100644 (file)
@@ -77,6 +77,7 @@ from Noyau.N_utils import AsType
 from A_VALIDATOR import OrdList,NoRepeat,LongStr,OrVal,AndVal
 from A_VALIDATOR import RangeVal, EnumVal, TypeVal, PairVal
 from A_VALIDATOR import CardVal, InstanceVal
+from A_VALIDATOR import ValidException
 
 # On remplace la factory des validateurs initialement dans Noyau par celle
 # de A_VALIDATOR
index 0df698555645f405b4394eefb6ed5bc7082e5b81..97fdba1a55861ca6e74e75686ede06ef0e914479 100644 (file)
@@ -379,6 +379,23 @@ class STANDALONE(APPLI):
                                     rep_mat=self.CONFIGURATION.rep_mat,
                                    )
       J.analyse()
+      txt= J.cr.get_mess_exception()
+      if txt:raise ValueError(txt)
+      return J
+
+   def openTXT(self,text):
+      self.JDCName="TEXT"
+      CONTEXT.unset_current_step()
+      J=self.readercata.cata[0].JdC(procedure=text,
+                                    appli=self,
+                                    cata=self.readercata.cata,
+                                    cata_ord_dico=self.readercata.cata_ordonne_dico,
+                                    nom=self.JDCName,
+                                    rep_mat=self.CONFIGURATION.rep_mat,
+                                   )
+      J.analyse()
+      txt= J.cr.get_mess_exception()
+      if txt:raise ValueError(txt)
       return J
 
    def create_item(self,obj):
index cf8eae081d760410ac5d51fd05ccdefae0a27003..101239dc93f99a07072d5bd6ea068d74653fae44 100644 (file)
@@ -524,6 +524,14 @@ class SIMPTreeItem(Objecttreeitem.AtomicObjectTreeItem):
   # traite_reel
 
   def eval_valeur(self,valeur):
+      """ Lance l'interprétation de 'valeur' (chaîne de caractères) comme valeur de self :
+             - retourne l'objet associé si on a pu interpréter (entier, réel, ASSD,...)
+             - retourne 'valeur' (chaîne de caractères) sinon
+      """
+      newvaleur=self.eval_val(valeur)
+      return newvaleur,1
+
+  def eval_valeur_BAK(self,valeur):
       """ Lance l'interprétation de 'valeur' (chaîne de caractères) comme valeur
       de l'objet pointé par self :
         - retourne l'objet associé si on a pu interpréter (entier, réel, ASSD,...)
index 6bff4bdf12dbcb76c8b4a0c208a049cbfd82f9f0..b90b532aed91e7c5f7692f9315790584dd5df2b9 100644 (file)
@@ -188,7 +188,7 @@ class UNIQUE_ASSD_Panel(UNIQUE_Panel):
       """
       valeur = self.node.item.get_valeur()
       if valeur == None or valeur == '' : return # pas de valeur à afficher ...
-      self.valeur_choisie.set(valeur.nom)
+      self.valeur_choisie.set(getattr(valeur,"nom","unknown"))
 
   def erase_valeur(self):
       pass
index 2d7950c20a9cb98939d29fae6c86e68b6949fcec..d54060a40dd5dae92ede09304c6b55aa08f99dc7 100644 (file)
@@ -207,6 +207,7 @@ class COMMANDE_COMM(N_OBJECT.OBJECT,I_OBJECT.OBJECT) :
         #print "uncomment",new_etape.sd
 
         pos=self.parent.etapes.index(self)
+        # L'ordre d'appel est important : suppentite fait le menage des concepts dans les etapes suivantes
         self.parent.addentite(new_etape,pos)
         self.parent.suppentite(self)
         return new_etape,nom_sd
index e02f1dccea0f292448f3f86c3959cd73bf1c20b8..8a74ee420e15527518299a11873666a1ce63b1ad 100644 (file)
@@ -303,6 +303,7 @@ class JDC_POURSUITE(JDC):
       #Regularise les etapes du jdc apres l'etape etape
       self.control_jdc_context_apres(etape)
       if self.etape_include:
+         #print "CONTROL_INCLUDE:",self.etape_include,self.etape_include.nom
          # il existe un jdc pere. On propage la regularisation
          self.etape_include.parent.control_context_apres(self.etape_include)
 
index 61c6e3ae6c0145ec923d97459a5922e4230de30d..2ccdac4b524ecdb570a5ace2ae57a6c083acf5a5 100644 (file)
@@ -3,15 +3,19 @@ import math
 import Numeric
 
 def mkf(value):
-    if type(value) in (type(1), type(1L), type(1.5), type(1j),type("hh")):
+    if type(value) in (type(1), type(1L), type(1.5), type(1j),type("hh")) :
         return Constant(value)
     elif isinstance(value, Formula):
         return value
+    elif type(value) == type([]):
+        return Constant(value)
     else:
+#        return Constant(value)
         raise TypeError, ("Can't make formula from", value)
 
 #class Formula(object):
 class Formula:
+    def __len__(self): return len(self.eval())
     def __complex__(self): return complex(self.eval())
     def __int__(self): return int(self.eval())
     def __long__(self): return long(self.eval())
@@ -58,6 +62,8 @@ class Binop(Formula):
         while isinstance(result,Formula):
               result=result.eval()
         return result
+    def __adapt__(self,validator):
+        return validator(self.eval())
 
 original_cos=math.cos
 original_sin=math.sin
@@ -66,7 +72,7 @@ original_nsin=Numeric.sin
 
 class Unop(Formula):
     opmap = { '-': lambda x: -x,
-              'sin': lambda x: math.sin(x),
+              'sin': lambda x: original_sin(x),
               'cos': lambda x: original_cos(x) ,
               'ncos': lambda x: original_ncos(x),
               'nsin': lambda x: original_nsin(x),
@@ -80,6 +86,8 @@ class Unop(Formula):
         return "%s(%s)" % (self._op, self._arg)
     def eval(self):
         return self.opmap[self._op](self._arg.eval())
+    def __adapt__(self,validator):
+        return validator(self.eval())
 
 class Unop2(Unop):
     def __init__(self, nom, op, arg):
@@ -110,6 +118,8 @@ class Constant(Formula):
     def __init__(self, value): self._value = value
     def eval(self): return self._value
     def __str__(self): return str(self._value)
+    def __adapt__(self,validator):
+        return validator(self._value)
 
 class Variable(Formula):
     def __init__(self,name,value):
@@ -118,6 +128,8 @@ class Variable(Formula):
     def eval(self): return self._value
     def __repr__(self): return "Variable('%s',%s)" % (self._name, self._value)
     def __str__(self): return self._name
+    def __adapt__(self,validator):
+        return validator(self._value)
 
 def cos(f): return Unop('ncos', f)
 def sin(f): return Unop('nsin', f)
index bb525091d8673603bf402b0d3b9ebccfb268cee3..7ca8ca641bf2eda8746ad5a5f4aa251281568de9 100644 (file)
@@ -60,171 +60,11 @@ class PARAMETRE(N_OBJECT.OBJECT,I_OBJECT.OBJECT,Formula) :
     self.state='undetermined'
     self.register()
     self.dict_valeur=[]
-    self.valeur = self.interprete_valeur(valeur)
-    self.val=valeur
-
-#  def __getitem__(self,key):
-#    param_item=ITEM_PARAMETRE(self,key)
-#    return param_item
-
-#  def __neg__(self):
-#    try:
-#      return -1*self.valeur
-#    except:
-#      print "******* Probleme : pas de valeur négative"
-#      return None
-    
-#  def __add__(self,a):
-#    try :
-#      return self.valeur+a.valeur
-#    except :
-#      print "******* Probleme : a l addition"
-#      return None
-
-#  def __radd__(self,a):
-#    try :
-#      return self.valeur+a.valeur
-#    except :
-#      print "******* Probleme : a l addition"
-#      return None
-
-#  def __sub__(self,a):
-#    try :
-#      return self.valeur  - a.valeur
-#    except :
-#      print "******* Probleme : a la soustraction"
-#      return None
-
-#  def __rsub__(self,a):
-#    try :
-#      return a.valeur - self.valeur
-#    except :
-#      print "******* Probleme : a la soustraction"
-#      return None
-
-
-#  def __mul__(self,a):
-#    try :
-#      return self.valeur*a.valeur
-#    except :
-#      print "******* Probleme : a la multiplication"
-#      return None
-
-#  def __rmul__(self,a):
-#    try :
-#      return self.valeur*a.valeur
-#    except :
-#      print "******* Probleme : a la multiplication"
-#      return None
-
-#  def __add__(self,other):
-#    try :
-#      return self.valeur+other
-#    except :
-#      print "******* Probleme : a l addition"
-#      return None
-
-#  def __radd__(self,other):
-#    try :
-#      return self.valeur+other
-#    except :
-#      print "******* Probleme : a l addition"
-#      return None
-
-#  def __sub__(self,other):
-#    try :
-#      return self.valeur  - other
-#    except :
-#      print "******* Probleme : a la soustraction"
-#      return None
-
-#  def __rsub__(self,other):
-#    try :
-#      return other - self.valeur
-#    except :
-#      print "******* Probleme : a la soustraction"
-#      return None
-
-#  def  __mul__ (self,other):
-#    retour=None
-#    try :
-#      retour = eval(self.valeur) * other
-#    except :
-#      try :
-#         retour = self.valeur * other
-#      except :
-#         try :
-#         retour = eval(self.valeur) * eval(other)
-#       except :
-#         try :
-#           retour = self.valeur * eval(other)
-#         except :
-#           print other
-#             print "******* Probleme : a la multiplication _mul__"
-#    return retour
-#
-#  def __rmul__ (self,other):
-#    retour=None
-#    try :
-#      retour = eval(self.valeur) * other
-#    except :
-#      try :
-#         retour = self.valeur * other
-#      except :
-#         try :
-#          retour = eval(self.valeur) * eval(other)
-#       except :
-#            print "******* Probleme : a la multiplication __rmul__"
-#    return retour
-#
-#
-#  def __div__(self,other):
-#    retour=None
-#    try:
-#      retour = eval(self.valeur) / other
-#    except :
-#      try :
-#      retour = self.valeur / other
-#      except :
-#      print "******* Probleme : a la division"
-#    return retour
-#
-#
-#  def cos(self):
-#      try :
-#              retour=cos(self.valeur)
-#        return retour
-#      except:
-#        print "pb pour cosinus"
-#
-#  def sin(self):
-#      try :
-#              retour=sin(self.valeur)
-#        return retour
-#      except:
-#        print "pb pour sinus"
-#
-#  def tan(self):
-#      try :
-#              retour=tan(self.valeur)
-#        return retour
-#      except:
-#        print "pb pour tangente"
-#
-#  def log(self):
-#      try :
-#              retour=log(self.valeur)
-#        return retour
-#      except:
-#        print "pb pour log"
-#
-#  def sqrt(self):
-#      try :
-#              retour=sqrt(self.valeur)
-#        return retour
-#      except:
-#        print "pb pour sqrt"
-#
+    #self.valeur = self.interprete_valeur(valeur)
+    #self.val=valeur
+    self.valeur = valeur
+    self.val=repr(valeur)
+
   def interprete_valeur(self,val):
     """
     Essaie d'interpréter val (chaîne de caractères)comme :
@@ -236,36 +76,19 @@ class PARAMETRE(N_OBJECT.OBJECT,I_OBJECT.OBJECT,Formula) :
     """
     #if not val : return None
     valeur = None
-    #  on vérifie si val est un entier
-    #try :
-    #    valeur = string.atoi(val)       # on a un entier
-    #    print "int",valeur
-    #    return valeur
-    #except :
-    #    traceback.print_exc()
-    #    pass
-    #print val,valeur
-    #  on vérifie si val est un réel
-    #try:
-    #    valeur = string.atof(val)   # on a un réel
-    #    print "float",valeur
-    #    return valeur
-    #except :
-    #    traceback.print_exc()
-    #    pass
-    #print val,valeur
 
     if type(val) == types.StringType:
-       # on tente l'evaluation (dans quel contexte ?)
+       # on tente l'evaluation dans un contexte fourni par le parent s'il existe
        if self.parent:
           valeur=self.parent.eval_in_context(val,self)
        else:
           try :
               valeur = eval(val)
           except:
-              traceback.print_exc()
+              #traceback.print_exc()
               pass
     #PN je n ose pas modifier je rajoute
+    # refus des listes heterogenes : ne dvrait pas etre la
     if valeur != None :
         if type(valeur) == types.TupleType:
             l_new_val = []
@@ -282,11 +105,7 @@ class PARAMETRE(N_OBJECT.OBJECT,I_OBJECT.OBJECT,Formula) :
                         return val
                 l_new_val.append(v)
             return tuple(l_new_val)
-       # PN : commente le print
-        #else:
-            # on a réussi à évaluer val en autre chose qu'un tuple ...
-            #print "on a réussi à évaluer %s en autre chose qu'un tuple ..." %val
-            #print 'on trouve : ',str(valeur),' de type : ',type(valeur)
+
     if valeur != None :
        if type(valeur).__name__ == 'list':
           self.dict_valeur=[]
@@ -437,7 +256,14 @@ class PARAMETRE(N_OBJECT.OBJECT,I_OBJECT.OBJECT,Formula) :
         Donne un echo de self sous la forme nom = valeur
     """
     if type(self.valeur) == types.StringType:
-       return self.nom+' = '+ repr(self.valeur)
+         if self.valeur.find('\n') == -1:
+            # pas de retour chariot, on utilise repr
+            return self.nom+' = '+ repr(self.valeur)
+         elif self.valeur.find('"""') == -1:
+            # retour chariot mais pas de triple ", on formatte
+            return self.nom+' = """'+self.valeur+'"""'
+         else:
+            return self.nom+' = '+ repr(self.valeur)
     else:
        return self.nom+' = '+ str(self.valeur)
 
@@ -508,6 +334,9 @@ class PARAMETRE(N_OBJECT.OBJECT,I_OBJECT.OBJECT,Formula) :
       else:
          return self.valeur
 
+  def __adapt__(self,validator):
+      return validator(self.eval())
+
 class COMBI_PARAMETRE :
   def __init__(self,chainevaleur,valeur):
       self.chainevaleur=chainevaleur
index f7bd493ea6f213c4e28215ec13e4dcabcf5a769c..15b7e162ae69abb44db521f30e535db43c69d6a8 100644 (file)
 #
 # ======================================================================
 
+from I_VALIDATOR import ValidException
+
 class ASSD:
    def __repr__(self):
       return "concept %s de type %s" % (self.get_name(),self.__class__.__name__)
    #def __del__(self):
    #   print "__del__",self
+
+class assd(ASSD):
+   def __convert__(cls,valeur):
+      return valeur
+   __convert__=classmethod(__convert__)
+
+class GEOM(ASSD):
+   def __convert__(cls,valeur):
+      return valeur
+   __convert__=classmethod(__convert__)
+
+class geom(GEOM):pass
+
+class CO(ASSD):
+   def __convert__(cls,valeur):
+      if hasattr(valeur,'_etape') :
+         # valeur est un concept CO qui a ete transforme par type_sdprod
+         if valeur.etape == valeur._etape:
+             # le concept est bien produit par l'etape
+             return valeur
+      raise ValidException("Pas un concept CO")
+   __convert__=classmethod(__convert__)
+
index eb3d20bfc36b8638ca4d7aca4a5da7ad1973bebe..167524971d72e2fe371b828804bf13fe07e37268 100644 (file)
@@ -85,12 +85,14 @@ class ETAPE(I_MCCOMPO.MCCOMPO):
       """
       #print "fin_modif",self,self.parent
       if self.nom == "DETRUIRE":
+         traceback.print_stack(limit=8)
          #Il n'est pas conseillé de mettre des traitements dans fin_modif. Ceci est une
          # exception qu'il faut supprimer à terme.
          #une commande DETRUIRE a été modifiée. Il faut verifier les commandes
          #suivantes
          #ATTENTION: aux eventuelles recursions
          self.parent.control_context_apres(self)
+         pass
 
       CONNECTOR.Emit(self,"valid")
       if self.parent:
index 04879d4f04ada91ce2f0be3d0e7ab1f9dfd490e9..18f66362a0addc4871886b5d36b1f3187f88b962 100644 (file)
@@ -46,6 +46,8 @@ class fonction(FONCTION) : pass
 from Extensions import param2
 class formule(FONCTION) : 
    def __call__(self,*val):
+      if len(val) != len(self.nompar):
+         raise TypeError(" %s() takes exactly %d argument (%d given)" % (self.nom,len(self.nompar),len(val)))
       return param2.Unop2(self.nom,self.real_call,val)
 
    def real_call(self,*val):
index 17de72e29d26d2978cb8c2459e87553c4eee0737..26e13e44fe157a6255a8820b49869c9b34664e8f 100644 (file)
@@ -702,17 +702,13 @@ class JDC(I_OBJECT.OBJECT):
       """
       #contexte initial du jdc
       context=self.condition_context.copy()
-      #contexte courant des concepts
+      #contexte courant des concepts. Il contient les parametres
       context.update(self.get_contexte_avant(etape))
-      #contexte des parametres 
-      for e in self.etapes:
-         if e is etape:break
-         if not e.isactif():continue
-         e.update_context(context)
       try :
          objet = eval(valeur,context)
          return objet
       except:
+         #traceback.print_exc()
          pass
       return valeur
 
index e351b006dd45e153ea04c7afca82e185afb3d867..6be22b1242a3b063aedc8d6177f5f126af64a371 100644 (file)
@@ -28,6 +28,7 @@ import traceback,types,string
 import I_ETAPE
 import Noyau
 from Noyau.N_ASSD import ASSD
+import convert
 
 # import rajoutés suite à l'ajout de Build_sd --> à résorber
 import Noyau, Validation.V_MACRO_ETAPE
@@ -95,6 +96,15 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
           self.jdc_aux.supprime_aux()
 
        if fichier is None:fichier="SansNom"
+
+       # Il faut convertir le texte inclus en fonction du format
+       format=self.jdc.appli.format_fichier.get()
+       if convert.plugins.has_key(format):
+          # Le convertisseur existe on l'utilise
+          p=convert.plugins[format]()
+          p.text=text
+          text=p.convert('exec',self)
+
        j=self.JdC_aux( procedure=text, nom=fichier,
                                 appli=self.jdc.appli,
                                 cata=self.jdc.cata,
@@ -110,6 +120,7 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
        self.etapes=j.etapes
        self.jdc_aux=j
     except:
+       traceback.print_exc()
        # On retablit l'etape courante step
        CONTEXT.unset_current_step()
        CONTEXT.set_current_step(step)
@@ -676,6 +687,14 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
       #print "update_context.fin",d.keys()
 
 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
+  def copy(self):
+      etape=Noyau.N_MACRO_ETAPE.MACRO_ETAPE.copy(self)
+      if hasattr(etape,"etapes") :etape.etapes=[]
+      if hasattr(etape,"jdc_aux") : 
+         etape.jdc_aux=None
+         del etape.fichier_ini
+      return etape
+
   def supprime(self):
       #print "supprime",self
       if hasattr(self,"jdc_aux") and self.jdc_aux:
@@ -774,30 +793,35 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
     # On supprime l'attribut mat qui bloque l'evaluation du source de l'INCLUDE_MATERIAU
     # car on ne s'appuie pas sur lui dans EFICAS mais sur l'attribut fichier_ini
     if hasattr(self,'mat'):del self.mat
-    self.fichier_ini =fichier
-    self.fichier_unite =fichier
-    self.fichier_text=text
-    self.fichier_err=None 
-    self.contexte_fichier_init={}
-    # On specifie la classe a utiliser pour le JDC auxiliaire
-    try:
-      import Extensions.jdc_include
-    except:
-      traceback.print_exc()
-      raise
-    self.JdC_aux=Extensions.jdc_include.JdC_include
-    try:
-       self.make_contexte_include(self.fichier_ini ,self.fichier_text)
-       #self.parent.record_unit(self.fichier_unite,self)
-    except:
-       l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
-       self.fichier_err = string.join(l)
-       #self.parent.record_unit(self.fichier_unite,self)
-       self.g_context={}
-       self.etapes=[]
-       self.jdc_aux=None
+    if not hasattr(self,'fichier_ini') or self.fichier_ini != fichier or self.fichier_mater != self.nom_mater: 
+       # le fichier est nouveau ou change
+       self.fichier_ini =fichier
+       self.fichier_unite =fichier
+       self.fichier_mater=self.nom_mater
+       self.fichier_text=text
+       self.fichier_err=None 
        self.contexte_fichier_init={}
-       raise
+       # On specifie la classe a utiliser pour le JDC auxiliaire
+       try:
+         import Extensions.jdc_include
+         self.JdC_aux=Extensions.jdc_include.JdC_include
+       except:
+         traceback.print_exc()
+         raise
+       try:
+          self.make_contexte_include(self.fichier_ini ,self.fichier_text)
+       except:
+          l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
+          self.fichier_err = string.join(l)
+          self.g_context={}
+          self.etapes=[]
+          self.jdc_aux=None
+          self.contexte_fichier_init={}
+          raise
+    else:
+       # le fichier est le meme on ne le reevalue pas
+       # et on leve une exception si une erreur a été enregistrée
+       if self.fichier_err is not None: raise Exception(self.fichier_err)
 
 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
   def update_sdprod(self,cr='non'):
index 6dedfca25ec3abe21945d20f2a067849a811f836..3e549ce7ac49819ccfe1f92424149b5ceeab9db0 100644 (file)
@@ -48,6 +48,8 @@ from Extensions import param2
 import I_OBJECT
 import CONNECTOR
 
+from I_VALIDATOR import ValidException
+
 class MCSIMP(I_OBJECT.OBJECT):
 
   def GetNomConcept(self):
@@ -290,7 +292,7 @@ class MCSIMP(I_OBJECT.OBJECT):
     sd = self.jdc.get_sd_avant_etape(new_valeur,self.etape)
     #sd = self.jdc.get_contexte_avant(self.etape).get(new_valeur,None)
     #print sd
-    if sd :
+    if sd is not None:
       return sd,1
     lsd = self.jdc.cherche_list_avant(self.etape,new_valeur) 
     if lsd :
@@ -327,11 +329,6 @@ class MCSIMP(I_OBJECT.OBJECT):
        return valeurretour
     else:
        valeur=self.eval_val_item(new_valeur)
-       if valeur == new_valeur and new_valeur.find(',') > 0:
-          valeurretour=[]
-          for item in new_valeur.split(',') :
-             valeurretour.append(self.eval_val_item(item))
-          return valeurretour
        return valeur
 
   def eval_val_item(self,new_valeur):
@@ -340,22 +337,17 @@ class MCSIMP(I_OBJECT.OBJECT):
        Si c'est impossible retourne new_valeur inchange
        argument new_valeur : string (nom de concept, de parametre, expression ou simple chaine)
     """
-    # concept ?
-    sd = self.jdc.get_sd_avant_etape(new_valeur,self.etape)
-    if sd :
-      return sd
-    # expression ou item parametre ?
-    d={}
-    # On veut EVAL avec tous ses comportements. On utilise Accas. Perfs ??
-    d['EVAL']=Accas.EVAL
-    for p in self.jdc.params:
-       d[p.nom]=p
-    try :
-      objet = eval(new_valeur,d)
-      return objet
-    except:
-      pass
-    return new_valeur
+    if self.etape and self.etape.parent:
+       valeur=self.etape.parent.eval_in_context(new_valeur,self.etape)
+       return valeur
+    else:
+       try :
+           valeur = eval(val)
+           return valeur
+       except:
+           #traceback.print_exc()
+           return new_valeur
+           pass
 
   def cherche_item_parametre (self,new_valeur):
         try:
@@ -464,11 +456,11 @@ class MCSIMP(I_OBJECT.OBJECT):
       self.init_modif()
       self.valeur = new_objet
       self.val = new_objet
-      self.fin_modif()
-      step.reset_context()
       # On force l'enregistrement de new_objet en tant que concept produit 
       # de la macro en appelant get_type_produit avec force=1
       self.etape.get_type_produit(force=1)
+      self.fin_modif()
+      step.reset_context()
       #print "set_valeur_co",new_objet
       return 1,"Concept créé"
        
@@ -479,21 +471,24 @@ class MCSIMP(I_OBJECT.OBJECT):
      """
      #print "verif_existence_sd"
      # Attention : possible probleme avec include
+     # A priori il n'y a pas de raison de retirer les concepts non existants
+     # avant etape. En fait il s'agit uniquement eventuellement de ceux crees par une macro
      l_sd_avant_etape = self.jdc.get_contexte_avant(self.etape).values()  
      if type(self.valeur) in (types.TupleType,types.ListType) :
        l=[]
-       self.init_modif()
        for sd in self.valeur:
          if isinstance(sd,ASSD) :
-           if sd in l_sd_avant_etape :
+           if sd in l_sd_avant_etape or self.etape.get_sdprods(sd.nom) is sd:
               l.append(sd)
         else:
            l.append(sd)
-       self.valeur=tuple(l)
-       self.fin_modif()
+       if len(l) < len(self.valeur):
+          self.init_modif()
+          self.valeur=tuple(l)
+          self.fin_modif()
      else:
        if isinstance(self.valeur,ASSD) :
-         if self.valeur not in l_sd_avant_etape :
+         if self.valeur not in l_sd_avant_etape and self.etape.get_sdprods(self.valeur.nom) is None:
              self.init_modif()
             self.valeur = None
              self.fin_modif()
@@ -547,6 +542,262 @@ class MCSIMP(I_OBJECT.OBJECT):
 # Elles doivent etre reintegrees des que possible
 
 
+  def convert_card(self,valeur):
+      """
+          Cette methode verifie que la cardinalite de valeur est correcte (comprise entre min et max)
+          Si c'est le cas elle retourne valeur eventuellement convertie
+          Si ce n'est pas le cas, elle leve une exception
+      """
+
+      adapt = getattr(valeur, '__adapt__', None)
+      if adapt is not None:
+         # l'objet valeur peut se verifier lui meme
+         return adapt(self.convert_card)
+
+      min=self.definition.min
+      max=self.definition.max
+
+      if type(valeur) == types.TupleType and valeur[0] in ('RI','MP'):
+         #il s'agit d'un complexe ancienne mode. La cardinalite vaut 1
+         length=1
+      elif valeur == None :
+         # pas de valeur affecte. La cardinalite vaut 0
+         length=0
+      elif type(valeur) == types.StringType :
+         #il s'agit d'une chaine. La cardinalite vaut 1
+         length=1
+      else:
+         try:
+            # si l'objet supporte len, on a la cardinalite
+            length=len(valeur)
+         except:
+            # sinon elle vaut 1
+            length=1
+         
+      if length < min or length >max:
+         raise ValidException("Nombre d'arguments de %s incorrect pour %s (min = %s, max = %s)" % (repr(valeur),self.nom,min,max) )
+
+      return valeur
+      
+  def verif_card(self,cr='non'):
+      """
+         un mot-clé simple ne peut etre répété :
+           la cardinalité ici s'entend par la vérification que le nombre d'arguments de self.valeur
+           est bien compris entre self.min et self.max dans le cas où il s'agit d'une liste
+      """
+      card = 1
+      try:
+         self.convert_card(self.valeur)
+      except ValidException,e:
+         if cr == 'oui': self.cr.fatal(str(e))
+         card = 0
+      return card
+
+  def convert_into(self,valeur):
+      """
+          Cette methode verifie que valeur est dans la liste des valeurs possibles donnée
+          dans la definition (attribut into) ou dans un intervalle donné dans la definition (attributs
+          val_min, val_max)
+          Si c'est le cas elle retourne valeur eventuellement convertie
+          Si ce n'est pas le cas, elle leve une exception
+      """
+      adapt = getattr(valeur, '__adapt__', None)
+      if adapt is not None:
+         # l'objet valeur peut se verifier lui meme
+         return adapt(self.convert_into)
+
+      if type(valeur) == types.TupleType and not valeur[0] in ('RI','MP') or type(valeur) == types.ListType:
+        # Cas d'une liste de valeurs
+        # on s'arrete a la premiere erreur
+        for val in valeur:
+           self.convert_into(val)
+        return valeur
+
+      # Cas d'un scalaire
+      if self.definition.into == None :
+        #on est dans le cas d'un ensemble continu de valeurs possibles (intervalle)
+        if type(valeur) in (types.IntType,types.FloatType,types.LongType) :
+           min = self.definition.val_min
+           max = self.definition.val_max
+           if min == '**': min = valeur -1
+           if max == '**': max = valeur +1
+           if valeur < min or valeur > max :
+              raise ValidException("La valeur : %s  du mot-clé  %s  est en dehors du domaine de validité [ %s , %s ]" % (repr(valeur),self.nom,min,max) )
+        return valeur
+      else :
+        # on est dans le cas d'un ensemble discret de valeurs possibles (into)
+        if valeur not in self.definition.into:
+           raise ValidException("La valeur : %s  n'est pas permise pour le mot-clé : %s" % (repr(valeur),self.nom) )
+        return valeur
+
+  def verif_into(self,cr='non'):
+      """
+      Vérifie si la valeur de self est bien dans l'ensemble discret de valeurs
+      donné dans le catalogue derrière l'attribut into ou vérifie que valeur est bien compris
+      entre val_min et val_max
+      """
+      into = 1
+      try:
+         self.convert_into(self.valeur)
+      except ValidException,e:
+         if cr == 'oui': self.cr.fatal(str(e))
+         into = 0
+      return into
+
+  def convert_type(self,valeur):
+      """
+          Cette methode verifie que valeur est du bon type
+          Si c'est le cas elle retourne valeur eventuellement convertie
+          Si ce n'est pas le cas, elle leve une exception
+      """
+      if self.definition.type is None: return valeur
+
+      if valeur == None :
+         raise ValidException("None n'est pas une valeur autorisée")
+
+      adapt = getattr(valeur, '__adapt__', None)
+      if adapt is not None:
+         # l'objet valeur peut se verifier lui meme
+         return adapt(self.convert_type)
+
+      if type(valeur) == types.TupleType and not valeur[0] in ('RI','MP') or type(valeur) == types.ListType:
+        # Cas d'une liste de valeurs
+        # on s'arrete a la premiere erreur
+        for val in valeur:
+           self.convert_type(val)
+        return valeur
+
+      # Ici, valeur est un scalaire ...il faut tester sur tous les types ou les valeurs possibles
+      for type_permis in self.definition.type:
+          if self.check_type(valeur,type_permis) : return valeur
+      # si on sort de la boucle précédente par ici c'est que l'on n'a trouvé aucun type valable --> valeur refusée
+      raise ValidException("%s n'est pas d'un type autorisé" % repr(valeur))
+
+  def check_type(self,valeur,type_permis):
+      """
+          Fonction booléenne qui retourne 1 si valeur est du type type_permis, 0 sinon
+      """
+      if type_permis == 'R':
+        return self.is_reel(valeur)
+      elif type_permis == 'I':
+        return self.is_entier(valeur)
+      elif type_permis == 'C':
+        return self.is_complexe(valeur)
+      elif type_permis == 'TXM':
+        return type(valeur)==types.StringType
+      elif type(type_permis) == types.ClassType:
+        return self.is_object_from(valeur,type_permis)
+      elif type(type_permis) == types.InstanceType:
+        try:
+           return type_permis.__convert__(valeur) is not None
+        except:
+           return 0
+      elif type_permis == 'shell':
+        return self.is_shell(valeur)
+      else:
+        print "Type non encore géré %s" %`type_permis`
+        print self.nom,self.parent.nom,self.jdc.fichier
+        return 0
+
+  def is_complexe(self,valeur):
+      """ Retourne 1 si valeur est un complexe, 0 sinon """
+      if type(valeur) in (types.ComplexType,types.IntType,types.FloatType,types.LongType):
+      # Pour permettre l'utilisation de complexes Python
+        return 1
+      elif type(valeur) != types.TupleType :
+        # On n'autorise pas les listes pour les complexes
+        return 0
+      elif len(valeur) != 3:return 0
+      else:
+          # Un complexe doit etre un tuple de longueur 3 avec 'RI' ou 'MP' comme premiere
+          # valeur suivie de 2 reels.
+          if string.strip(valeur[0]) in ('RI','MP'):
+             try:
+                v1=self.convert_reel(valeur[1]),self.convert_reel(valeur[2])
+                return 1
+             except:
+                return 0
+          else:
+             return 0
+
+  def convert_reel(self,valeur):
+      try:
+         return float(valeur)
+      except:
+         adapt = getattr(valeur, '__adapt__', None)
+         if adapt is not None:
+            # l'objet valeur peut se verifier lui meme
+            return adapt(self.convert_reel)
+      raise ValidException("%s n'est pas un reel" % repr(valeur))
+         
+  def is_reel(self,valeur):
+      """
+      Retourne 1 si valeur est un reel, 0 sinon
+      """
+      if type(valeur) not in (types.IntType,types.FloatType,types.LongType):
+        # ce n'est pas un réel
+        return 0
+      else:
+        return 1
+
+  def is_entier(self,valeur):
+      """ Retourne 1 si valeur est un entier, 0 sinon """
+      if type(valeur) not in (types.IntType,types.LongType):
+        # ce n'est pas un entier
+        return 0
+      else:
+        return 1
+
+  def is_shell(self,valeur):
+      """
+          Retourne 1 si valeur est un shell, 0 sinon
+          Pour l'instant aucune vérification n'est faite
+          On impose juste que valeur soit une string
+      """
+      if type(valeur) != types.StringType:
+        return 0
+      else:
+        return 1
+
+  def is_object_from(self,objet,classe):
+      """
+           Retourne 1 si objet est une instance de la classe classe, 0 sinon
+      """
+      convert = getattr(classe, '__convert__', None)
+      if convert is not None:
+         # classe verifie les valeurs
+         try:
+            v=  convert(objet)
+            if v is None:return 0
+            else:return 1
+         except:
+            return 0
+      if type(objet) != types.InstanceType :
+        return 0
+      if isinstance(objet,classe) :
+        # On accepte les instances de la classe et des classes derivees
+        return 1
+
+      return 0
+
+  def verif_type(self,val=None,cr='non'):
+      """
+        FONCTION :
+         Cette methode verifie que le type de l'argument val est en conformite avec celui
+         qui est declare dans la definition du mot cle simple.
+         Elle a plusieurs modes de fonctionnement liés à la valeur de cr.
+         Si cr vaut 'oui' : elle remplit le compte-rendu self.cr sinon elle ne le remplit pas.
+        PARAMETRE DE RETOUR :
+         Cette méthode retourne une valeur booléenne qui vaut 1 si le type de val est correct ou 0 sinon
+
+      """
+      try:
+         self.convert_type(val)
+         return 1
+      except ValidException,e:
+         if cr == 'oui': self.cr.fatal(str(e))
+         return 0
+
   def isvalid(self,cr='non'):
       """
          Cette méthode retourne un indicateur de validité de l'objet de type MCSIMP
@@ -575,49 +826,19 @@ class MCSIMP(I_OBJECT.OBJECT):
               self.cr.fatal("None n'est pas une valeur autorisée")
         else:
            # type,into ...
-          #PN ??? je n ose pas y toucher ???
-          #if v.__class__.__name__ in ('PARAMETRE','EVAL', 'ITEM_PARAMETRE','PARAMETRE_EVAL'):
-          if ((issubclass(v.__class__,param2.Formula)) or
-               (v.__class__.__name__  in ('EVAL', 'ITEM_PARAMETRE','PARAMETRE_EVAL'))): 
-             verif_type=self.verif_typeihm(v)
-          else:
-             verif_type=self.verif_type(val=v,cr=None)
-             # cas des tuples avec un ITEM_PARAMETRE
-              if verif_type == 0:
-                 if type(v) in ( types.TupleType ,types.ListType):
-                  new_val=[]
-                  for i in v:
-                    if ((issubclass(i.__class__,param2.Formula)) or
-                        (i.__class__.__name__  in ('EVAL', 'ITEM_PARAMETRE','PARAMETRE_EVAL'))): 
-                         if self.verif_typeihm(val=i,cr=cr) == 0:
-                            verif_type = 0
-                            break
-                    else:
-                         new_val.append(i)
-                  if new_val != [] :
-                    verif_type=self.verif_type(val=new_val,cr=cr)
-                  else :
-                    # Cas d une liste de paramétre
-                    verif_type=self.verif_typeliste(val=v,cr=cr)
-                else:
-                    verif_type=self.verif_type(val=v,cr=cr)
-           valid = verif_type*self.verif_into(cr=cr)*self.verif_card(cr=cr)
+           valid = self.verif_type(val=v,cr=cr)*self.verif_into(cr=cr)*self.verif_card(cr=cr)
            #
            # On verifie les validateurs s'il y en a et si necessaire (valid == 1)
            #
-           if valid and self.definition.validators and not self.definition.validators.verif(self.valeur):
-              if cr == 'oui' :
-                 self.cr.fatal(string.join(("Mot-clé : ",self.nom,"devrait avoir ",self.definition.validators.info())))
-              valid=0
+           if valid and self.definition.validators:
+              try:
+                 self.definition.validators.convert(self.valeur)
+              except ValidException,e:
+                 if cr == 'oui' :
+                    self.cr.fatal(string.join(("Mot-clé : ",self.nom,"devrait avoir ",self.definition.validators.info())))
+                 valid=0
            # fin des validateurs
            #
-       # cas d un item Parametre
-       if self.valeur.__class__.__name__ == 'ITEM_PARAMETRE':
-          valid=self.valeur.isvalid()
-          if valid == 0:
-              if cr == 'oui' :
-                self.cr.fatal(string.join( repr (self.valeur), " a un indice incorrect"))
-
         self.set_valid(valid)
         return self.valid
 
index 3e6aa3aca74218c54c3ab4e0e167b2f16d733124..23c34f7c6e6606712d7639ded22be2677147aec0 100644 (file)
@@ -9,8 +9,10 @@
    Ces comportements pourront etre rapatries dans le Noyau quand leur
    interface sera stabilisée.
 """
+class ValidException(Exception):pass
 
 import types
+from I_MCSIMP import ValidException
 
 class Valid:
    """
@@ -18,21 +20,215 @@ class Valid:
         que l'on trouve dans Ihm.
    """
 
-class ListVal(Valid):pass
+class ListVal(Valid):
+   """
+       Cette classe sert de classe mère pour tous les validateurs qui acceptent
+       des listes.
+   """
+   def is_list(self):
+       return 1
+
+   def get_into(self,liste_courante=None,into_courant=None):
+       """
+          Cette méthode get_into effectue un traitement général qui consiste
+          a filtrer la liste de choix into_courant, si elle existe, en ne
+          conservant que les valeurs valides (appel de la méthode valid).
+       """
+       if into_courant is None:
+          return None
+       else:
+          liste_choix=[]
+          for e in into_courant:
+              if self.verif(e):
+                 liste_choix.append(e)
+          return liste_choix
+
+   def convert(self,valeur):
+       """
+          Méthode verif pour les validateurs de listes. Cette méthode
+          fait appel à la méthode verif_item sur chaque élément de la
+          liste. Si valeur est un paramètre, on utilise sa valeur effective
+          valeur.valeur.
+       """
+       if type(valeur) in (types.ListType,types.TupleType):
+          for val in valeur:
+              self.convert_item(val)
+          return valeur
+       else:
+          return self.convert_item(valeur)
+
+
+class RangeVal(ListVal):
+      def convert_item(self,valeur):
+          if valeur > self.low and valeur < self.high:return valeur
+          raise ValidException("%s devrait etre comprise entre %s et %s" %(valeur,self.low,self.high))
+
+
+class CardVal(Valid):
+      def convert(self,valeur):
+          if type(valeur) in (types.ListType,types.TupleType):
+             l=len(valeur)
+          elif valeur is None:
+             l=0
+          else:
+             l=1
+          if self.max != '**' and l > self.max:raise ValidException("%s devrait etre de longueur inferieure a %s" %(valeur,self.max))
+          if self.min != '**' and l < self.min:raise ValidException("%s devrait etre de longueur superieure a %s" %(valeur,self.min))
+          return valeur
 
-class RangeVal(ListVal):pass
 
-class CardVal(Valid):pass
+class PairVal(ListVal):
+      def convert(self,valeur):
+          if type(valeur) in (types.ListType,types.TupleType):
+             for val in valeur:
+                if val % 2 != 0:raise ValidException("%s contient des valeurs non paires" % repr(valeur))
+          else:
+             if valeur % 2 != 0:raise ValidException("%s n'est pas pair" % repr(valeur))
+          return valeur
 
-class PairVal(ListVal):pass
 
-class EnumVal(ListVal):pass
+
+class EnumVal(ListVal):
+      def convert_item(self,valeur):
+          if valeur in self.into:return valeur
+          raise ValidException("%s contient des valeurs hors des choix possibles: %s " %(valeur,self.into))
+
           
-class NoRepeat(ListVal):pass
+class NoRepeat(ListVal):
+      """
+          Verification d'absence de doublons dans la liste.
+      """
+      def __init__(self):
+          self.cata_info=""
+
+      def info(self):
+          return ": pas de présence de doublon dans la liste"
+
+      def info_erreur_liste(self):
+          return "Les doublons ne sont pas permis"
 
-class LongStr(ListVal):pass
+      def verif_item(self,valeur):
+          return 1
+
+      def verif(self,valeur):
+          if type(valeur) in (types.ListType,types.TupleType):
+             liste=list(valeur)
+             for val in liste:
+                if liste.count(val)!=1 : return 0
+             return 1
+          else:
+             return 1
+
+      def convert_item(self,valeur):
+          if valeur in self.liste : raise ValidException("%s est un doublon" % valeur)
+          return valeur
+          
+      def convert(self,valeur):
+          adapt = getattr(valeur, '__adapt__', None)
+          if adapt is not None:
+             # l'objet valeur peut se verifier lui meme
+             return adapt(self.convert)
+
+          if type(valeur) == types.TupleType and not valeur[0] in ('RI','MP') or type(valeur) == types.ListType:
+            # Cas d'une liste de valeurs
+            # on s'arrete a la premiere erreur
+            self.liste=[]
+            for val in valeur:
+               adapt = getattr(val, '__adapt__', None)
+               if adapt is not None: 
+                  v=adapt(self.convert_item)
+               else:
+                  v=self.convert_item(val)
+               self.liste.append(v)
+          return valeur
+
+      def get_into(self,liste_courante=None,into_courant=None):
+          """
+          Methode get_into spécifique pour validateur NoRepeat, on retourne
+          une liste de choix qui ne contient aucune valeur de into_courant
+          déjà contenue dans liste_courante
+          """
+          if into_courant is None:
+             liste_choix=None
+          else:
+             liste_choix=[]
+             for e in into_courant:
+                 if e in liste_choix: continue
+                 if liste_courante is not None and e in liste_courante: continue
+                 liste_choix.append(e)
+          return liste_choix
+
+
+class LongStr(ListVal):
+      """
+          Verification de la longueur d une chaine
+      """
+      def __init__(self,low,high):
+          self.low=low
+          self.high=high
+          self.cata_info=""
+
+      def info(self):
+          return "longueur de la chaine entre %s et %s" %(self.low,self.high)
+
+      def info_erreur_item(self):
+          return "Longueur de la chaine incorrecte"
+
+      def verif_item(self,valeur):
+          low=self.low
+          high=self.high
+          if valeur[0]=="'" and valeur[-1]=="'" :
+             low=low+2
+             high=high+2
+          if len(valeur) < low :return 0
+          if len(valeur) > high:return 0
+          return 1
+
+      def convert(self,valeur):
+          adapt = getattr(valeur, '__adapt__', None)
+          if adapt is not None:
+             # l'objet valeur peut se verifier lui meme
+             return adapt(self.convert)
+
+          if type(valeur) == types.TupleType and not valeur[0] in ('RI','MP') or type(valeur) == types.ListType:
+            # Cas d'une liste de valeurs
+            # on s'arrete a la premiere erreur
+            for val in valeur:
+               self.convert_item(val)
+            return valeur
+          else:
+            return self.convert_item(valeur)
+
+      def convert_item(self,valeur):
+          low=self.low
+          high=self.high
+          if valeur[0]=="'" and valeur[-1]=="'" :
+             low=low+2
+             high=high+2
+          if len(valeur) < low or len(valeur) > high :
+             raise ValidException("%s n'est pas de la bonne longueur" % repr(valeur))
+          return valeur
+
+
+
+class OrdList(ListVal):
+      def convert(self,valeur):
+          if type(valeur) in (types.ListType,types.TupleType):
+             if self.ord=='croissant':
+                var=valeur[0]
+                for val in valeur[1:]:
+                   if val<var:raise ValidException("%s n'est pas par valeurs croissantes" % repr(valeur))
+                   var=val
+                return valeur
+             elif self.ord=='decroissant':
+                var=valeur[0]
+                for val in valeur[1:]:
+                   if val>var:raise ValidException("%s n'est pas par valeurs decroissantes" % repr(valeur))
+                   var=val
+                return valeur
+          else:
+             return valeur
 
-class OrdList(ListVal):pass
 
 CoercableFuncs = { types.IntType:     int,
                    types.LongType:    long,
@@ -40,13 +236,25 @@ CoercableFuncs = { types.IntType:     int,
                    types.ComplexType: complex,
                    types.UnicodeType: unicode }
 
-class TypeVal(ListVal):pass
+class TypeVal(ListVal):
+      def convert_item(self,valeur):
+          return   self.coerce(valeur)
 
 class InstanceVal(ListVal):pass
 
 class FunctionVal(Valid):pass
 
-class OrVal(Valid):pass
-
-class AndVal(Valid):pass
+class OrVal(Valid):
+      def convert(self,valeur):
+          for validator in self.validators:
+              try:
+                 return validator.verif(valeur)
+              except:
+                 pass
+          raise ValidException("%s n'est pas du bon type" % valeur)
 
+class AndVal(Valid):
+      def convert(self,valeur):
+          for validator in self.validators:
+              valeur=validator.convert(valeur)
+          return valeur