#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'):
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
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
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
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):
# 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,...)
"""
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
#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
#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)
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())
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
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),
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):
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):
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)
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 :
"""
#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 = []
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=[]
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)
else:
return self.valeur
+ def __adapt__(self,validator):
+ return validator(self.eval())
+
class COMBI_PARAMETRE :
def __init__(self,chainevaleur,valeur):
self.chainevaleur=chainevaleur
#
# ======================================================================
+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__)
+
"""
#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:
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):
"""
#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
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
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,
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)
#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:
# 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'):
import I_OBJECT
import CONNECTOR
+from I_VALIDATOR import ValidException
+
class MCSIMP(I_OBJECT.OBJECT):
def GetNomConcept(self):
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 :
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):
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:
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éé"
"""
#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()
# 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
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
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:
"""
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,
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