text = text + t[0:-4] +'\n'
return text
- def init_couples_permis(self):
- """
- Crée la liste des couples permis parmi les self.args,
- càd pour chaque élément de self.args0 crée tous les couples possibles
- avec un élément de self.args1
- """
- liste = []
- for arg0 in self.args0:
- for arg1 in self.args1:
- liste.append((arg0,arg1))
- self.liste_couples = liste
-
for child in self.mc_liste :
child.replace_concept(old_sd,sd)
-#ATTENTION SURCHARGE: cette methode doit etre gardée en synchronisation avec Noyau
- def make_register(self):
- """
- Initialise les attributs jdc, id, niveau et réalise les
- enregistrements nécessaires
- Pour EFICAS, on tient compte des niveaux
- Surcharge la methode make_register du package Noyau
- """
- if self.parent :
- self.jdc = self.parent.get_jdc_root()
- self.id= self.parent.register(self)
- if self.definition.niveau :
- # La définition est dans un niveau. En plus on
- # l'enregistre dans le niveau
- self.nom_niveau_definition = self.definition.niveau.nom
- self.niveau = self.parent.dict_niveaux[self.nom_niveau_definition]
- self.niveau.register(self)
- else:
- # La définition est au niveau global
- self.nom_niveau_definition = 'JDC'
- self.niveau=self.parent
- else:
- self.jdc = self.parent =None
- self.id=None
- self.niveau=None
-
- def copy(self):
- """ Méthode qui retourne une copie de self non enregistrée auprès du JDC
- et sans sd
- """
- etape = copy(self)
- etape.sd = None
- etape.state = 'modified'
- etape.reuse = None
- etape.sdnom = None
- etape.etape=etape
- etape.mc_liste=[]
- for objet in self.mc_liste:
- new_obj = objet.copy()
- new_obj.reparent(etape)
- etape.mc_liste.append(new_obj)
- return etape
-
def get_noms_sd_oper_reentrant(self):
"""
Retourne la liste des noms de concepts utilisés à l'intérieur de la commande
l_noms.sort()
return l_noms
- def get_sd_utilisees(self):
- """
- Retourne la liste des concepts qui sont utilisés à l'intérieur d'une commande
- ( comme valorisation d'un MCS)
- """
- l=[]
- for child in self.mc_liste:
- l.extend(child.get_sd_utilisees())
- return l
-
def get_genealogie(self):
"""
Retourne la liste des noms des ascendants de l'objet self
"""
return [self.nom]
- def reparent(self,parent):
- """
- Cette methode sert a reinitialiser la parente de l'objet
- """
- self.parent=parent
- self.jdc=parent.get_jdc_root()
- self.etape=self
- for mocle in self.mc_liste:
- mocle.reparent(self)
-
def verif_existence_sd(self):
"""
Vérifie que les structures de données utilisées dans self existent bien dans le contexte
return self.sd
- def Build_sd_old(self,nom):
+#ATTENTION SURCHARGE: cette methode doit etre gardée en synchronisation avec Noyau
+ def make_register(self):
"""
- Construit le concept produit de l'opérateur. Deux cas
- peuvent se présenter :
-
- - le parent n'est pas défini. Dans ce cas, l'étape prend en charge la création
- et le nommage du concept.
-
- - le parent est défini. Dans ce cas, l'étape demande au parent la création et
- le nommage du concept.
-
+ Initialise les attributs jdc, id, niveau et réalise les
+ enregistrements nécessaires
+ Pour EFICAS, on tient compte des niveaux
+ Surcharge la methode make_register du package Noyau
"""
- if not self.isactif():return
- # FR : attention cette méthode ne devrait pas se trouver là car elle surcharge celle qui
- # se trouve dans N_ETAPE.py et elle est partie intégrante du noyau, mais, suite à l'absence de
- # test de validité de l'opérateur avant d'essayer de déterminer la sd produite, on n'arrivait
- # pas à relire avec EFICAS un fichier contenant une étape encore incomplète du style :
- # sansnom = AFFE_CHAR_CINE(MODELE=None)
- # Suite à la stabilisation du noyau d'Aster, je n'ai pas eu d'autre solution que de surcharger
- # cette méthode ici en rajoutant le test manquant ...
- # CCAR : cette modification ne corrige le probleme qu'en partie. Il faudrait probablement
- # supprimer les erreurs fatales (exception ) et retourner systematiquement un objet produit
- # meme en cas d'erreur et reporter l'emission du message d'erreur a la phase de validation
- #
- if not self.isvalid(sd='non') : return
- self.sdnom=nom
- try:
- if self.parent:
- sd= self.parent.create_sdprod(self,nom)
- if type(self.definition.op_init) == types.FunctionType:
- apply(self.definition.op_init,(self,self.parent.g_context))
+ if self.parent :
+ self.jdc = self.parent.get_jdc_root()
+ self.id= self.parent.register(self)
+ if self.definition.niveau :
+ # La définition est dans un niveau. En plus on
+ # l'enregistre dans le niveau
+ self.nom_niveau_definition = self.definition.niveau.nom
+ self.niveau = self.parent.dict_niveaux[self.nom_niveau_definition]
+ self.niveau.register(self)
else:
- sd=self.get_sd_prod()
- # On n'utilise pas self.definition.op_init car self.parent
- # n'existe pas
- if sd != None and self.reuse == None:
- # On ne nomme le concept que dans le cas de non reutilisation
- # d un concept
- sd.nom=nom
- if self.jdc and self.jdc.par_lot == "NON" :
- self.Execute()
- return sd
- except AsException,e:
- # Une erreur s'est produite lors de la construction du concept
- # Comme on est dans EFICAS, on essaie de poursuivre quand meme
- # Si on poursuit, on a le choix entre deux possibilités :
- # 1. on annule la sd associée à self
- # 2. on la conserve mais il faut la retourner
- # En plus il faut rendre coherents sdnom et sd.nom
- self.sd=None
- self.sdnom=None
- self.state="unchanged"
- self.valid=0
- return self.sd
+ # La définition est au niveau global
+ self.nom_niveau_definition = 'JDC'
+ self.niveau=self.parent
+ else:
+ self.jdc = self.parent =None
+ self.id=None
+ self.niveau=None
- #raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
- # 'fichier : ',self.appel[1],e)
- except EOFError:
- # XXX Normalement le contexte courant doit etre le parent.
- # Il n'y a pas de raison de remettre le contexte au parent
- #self.reset_current_step()
- raise
- except :
- l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2])
- raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
- 'fichier : ',self.appel[1]+'\n',
- string.join(l))
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
class FONCTION(ASSD):
def __init__(self,etape=None,sd=None,reg='oui'):
- #ASSD.__init__(self,etape=etape,sd=sd,reg=reg)
if reg=='oui':
self.jdc.register_fonction(self)
self.recorded_units={}
self.old_recorded_units={}
- def get_cmd(self,nomcmd):
- """
- Retourne l'objet de type COMMANDE de nom nomcmd
- """
- for cata in self.cata:
- if hasattr(cata,nomcmd):
- return getattr(cata,nomcmd)
-
def get_sd_avant_du_bon_type(self,etape,types_permis):
"""
Retourne la liste des concepts avant etape d'un type acceptable
if sd:return sd
return self.get_sd_apres_etape(nom_sd,etape,avec)
- def get_contexte_avant(self,etape):
- """
- Retourne le dictionnaire des concepts connus avant etape
- On tient compte des commandes qui modifient le contexte
- comme DETRUIRE ou les macros
- Si etape == None, on retourne le contexte en fin de JDC
- """
- # L'étape courante pour laquelle le contexte a été calculé est
- # mémorisée dans self.index_etape_courante
- # XXX on pourrait faire mieux dans le cas PAR_LOT="NON" : en
- # mémorisant l'étape
- # courante pendant le processus de construction des étapes.
- # Si on insère des commandes (par ex, dans EFICAS), il faut préalablement
- # remettre ce pointeur à 0
- if etape:
- index_etape=self.etapes.index(etape)
- else:
- index_etape=len(self.etapes)
- if index_etape >= self.index_etape_courante:
- # On calcule le contexte en partant du contexte existant
- d=self.current_context
- if self.index_etape_courante==0 and self.context_ini:
- d.update(self.context_ini)
- liste_etapes=self.etapes[self.index_etape_courante:index_etape]
- else:
- d=self.current_context={}
- if self.context_ini:d.update(self.context_ini)
- liste_etapes=self.etapes
-
- for e in liste_etapes:
- if e is etape:
- break
- if e.isactif():
- e.update_context(d)
- self.index_etape_courante=index_etape
- return d
-
def get_contexte_apres(self,etape):
"""
Retourne le dictionnaire des concepts connus apres etape
self.exec_compile()
self.active_etapes()
- def register(self,etape):
- """
- Cette méthode ajoute etape dans la liste
- des etapes self.etapes et retourne l identificateur d'étape
- fourni par l appel a g_register
-
- A quoi sert editmode ?
- - Si editmode vaut 1, on est en mode edition de JDC. On cherche
- à enregistrer une étape que l'on a créée avec eficas (en passant
- par addentite) auquel cas on ne veut récupérer que son numéro
- d'enregistrement et c'est addentité qui l'enregistre dans
- self.etapes à la bonne place...
- - Si editmode vaut 0, on est en mode relecture d'un fichier de
- commandes et on doit enregistrer l'étape à la fin de self.etapes
- (dans ce cas l'ordre des étapes est bien l'ordre chronologique
- de leur création )
- """
- if not self.editmode:
- self.etapes.append(etape)
- else:
- pass
- return self.g_register(etape)
-
def register_parametre(self,param):
"""
Cette méthode sert à ajouter un paramètre dans la liste des paramètres
if l : l_mc.extend(l)
return l_mc
- def get_file(self,unite=None,fic_origine=''):
- """
- Retourne le nom du fichier correspondant à un numero d'unité
- logique (entier) ainsi que le source contenu dans le fichier
- """
- if self.appli :
- # Si le JDC est relié à une application maitre, on délègue la recherche
- file,text = self.appli.get_file(unite,fic_origine)
- else:
- file = None
- if unite != None:
- if os.path.exists("fort."+str(unite)):
- file= "fort."+str(unite)
- if file == None :
- raise AsException("Impossible de trouver le fichier correspondant \
- a l unite %s" % unite)
- if not os.path.exists(file):
- raise AsException("%s n'est pas un fichier existant" % unite)
- fproc=open(file,'r')
- text=fproc.read()
- fproc.close()
- if file == None : return None,None
- text=string.replace(text,'\r\n','\n')
- linecache.cache[file]=0,0,string.split(text,'\n'),file
- return file,text
-
-
def get_genealogie(self):
"""
Retourne la liste des noms des ascendants de l'objet self
"""
return []
- def NommerSdprod(self,sd,sdnom,restrict='non'):
- """
- Nomme la SD apres avoir verifie que le nommage est possible :
- nom non utilise
- Si le nom est deja utilise, leve une exception
- Met le concept créé dans le concept global g_context
- """
- # XXX En mode editeur dans EFICAS, le nommage doit etre géré différemment
- # Le dictionnaire g_context ne représente pas le contexte
- # effectif avant une étape.
- # Il faut utiliser get_contexte_avant avec indication de l'étape
- # traitée.
- # Cette etape est indiquee par l'attribut _etape_context qui a ete
- # positionné préalablement par un appel à set_etape_context
-
- if CONTEXT.debug : print "JDC.NommerSdprod ",sd,sdnom
-
- if self._etape_context:
- o=self.get_contexte_avant(self._etape_context).get(sdnom,None)
- else:
- o=self.sds_dict.get(sdnom,None)
-
- if isinstance(o,ASSD):
- raise AsException("Nom de concept deja defini : %s" % sdnom)
-
- # ATTENTION : Il ne faut pas ajouter sd dans sds car il s y trouve deja.
- # Ajoute a la creation (appel de reg_sd).
- self.sds_dict[sdnom]=sd
- sd.nom=sdnom
-
- # En plus si restrict vaut 'non', on insere le concept dans le contexte du JDC
- if restrict == 'non':
- self.g_context[sdnom]=sd
-
-
def set_etape_context(self,etape):
"""
Positionne l'etape qui sera utilisee dans NommerSdProd pour
if fonction not in self.fonctions : self.fonctions.append(fonction)
self.g_context[fonction.nom]=fonction
- def delete_concept_after_etape(self,etape,sd):
- """
- Met à jour les étapes du JDC qui sont après etape en fonction
- de la disparition du concept sd
- """
- index = self.etapes.index(etape)+1
- if index == len(self.etapes) :
- return # etape est la dernière étape du jdc ...on ne fait rien !
- for child in self.etapes[index:]:
- child.delete_concept(sd)
-
def delete_concept(self,sd):
"""
Inputs :
else:
self.recorded_units[unit]=(etape.fichier_ini ,etape.fichier_text,etape.recorded_units)
-#ATTENTION SURCHARGE : cette methode surcharge la methode du package Validation : a reintegrer
+#ATTENTION SURCHARGE : cette methode doit etre gardée en synchronisation avec celle de Noyau
+ def register(self,etape):
+ """
+ Cette méthode ajoute etape dans la liste
+ des etapes self.etapes et retourne l identificateur d'étape
+ fourni par l appel a g_register
+
+ A quoi sert editmode ?
+ - Si editmode vaut 1, on est en mode edition de JDC. On cherche
+ à enregistrer une étape que l'on a créée avec eficas (en passant
+ par addentite) auquel cas on ne veut récupérer que son numéro
+ d'enregistrement et c'est addentité qui l'enregistre dans
+ self.etapes à la bonne place...
+ - Si editmode vaut 0, on est en mode relecture d'un fichier de
+ commandes et on doit enregistrer l'étape à la fin de self.etapes
+ (dans ce cas l'ordre des étapes est bien l'ordre chronologique
+ de leur création )
+ """
+ if not self.editmode:
+ self.etapes.append(etape)
+ else:
+ pass
+ return self.g_register(etape)
+
+#ATTENTION SURCHARGE : cette methode doit etre gardée en synchronisation avec celle de Noyau
+ def NommerSdprod(self,sd,sdnom,restrict='non'):
+ """
+ Nomme la SD apres avoir verifie que le nommage est possible :
+ nom non utilise
+ Si le nom est deja utilise, leve une exception
+ Met le concept créé dans le concept global g_context
+ """
+ # XXX En mode editeur dans EFICAS, le nommage doit etre géré différemment
+ # Le dictionnaire g_context ne représente pas le contexte
+ # effectif avant une étape.
+ # Il faut utiliser get_contexte_avant avec indication de l'étape
+ # traitée.
+ # Cette etape est indiquee par l'attribut _etape_context qui a ete
+ # positionné préalablement par un appel à set_etape_context
+
+ if CONTEXT.debug : print "JDC.NommerSdprod ",sd,sdnom
+
+ if self._etape_context:
+ o=self.get_contexte_avant(self._etape_context).get(sdnom,None)
+ else:
+ o=self.sds_dict.get(sdnom,None)
+
+ if isinstance(o,ASSD):
+ raise AsException("Nom de concept deja defini : %s" % sdnom)
+
+ # ATTENTION : Il ne faut pas ajouter sd dans sds car il s y trouve deja.
+ # Ajoute a la creation (appel de reg_sd).
+ self.sds_dict[sdnom]=sd
+ sd.nom=sdnom
+
+ # En plus si restrict vaut 'non', on insere le concept dans le contexte du JDC
+ if restrict == 'non':
+ self.g_context[sdnom]=sd
+
+#ATTENTION SURCHARGE : cette methode doit etre gardée en synchronisation avec celle de Noyau
+ def delete_concept_after_etape(self,etape,sd):
+ """
+ Met à jour les étapes du JDC qui sont après etape en fonction
+ de la disparition du concept sd
+ """
+ index = self.etapes.index(etape)+1
+ if index == len(self.etapes) :
+ return # etape est la dernière étape du jdc ...on ne fait rien !
+ for child in self.etapes[index:]:
+ child.delete_concept(sd)
+
+#ATTENTION SURCHARGE : les methodes ci-dessous surchargent des methodes de Noyau et Validation : a reintegrer
+
def __init__(self):
self.l_noms_entites=[]
+ def get_liste_cmd(self):
+ self.l_noms_entites.sort()
+ return self.l_noms_entites
+
#ATTENTION SURCHARGE: cette methode doit etre synchronisée avec celle du Noyau
def enregistre(self,commande):
"""
"""
N_JDC_CATA.JDC_CATA.enregistre(self,commande)
self.l_noms_entites.append(commande.nom)
-
- def get_liste_cmd(self):
- self.l_noms_entites.sort()
- return self.l_noms_entites
-
self.typret=None
self.recorded_units={}
- def copy(self):
- """ Méthode qui retourne une copie de self non enregistrée auprès du JDC
- et sans sd
- On surcharge la methode de ETAPE pour exprimer que les concepts crees
- par la MACRO d'origine ne sont pas crees par la copie mais eventuellement
- seulement utilises
- """
- etape=I_ETAPE.ETAPE.copy(self)
- etape.sdprods=[]
- return etape
-
def get_sdprods(self,nom_sd):
"""
Fonction : retourne le concept produit par l etape de nom nom_sd
# On met g_context à blanc
self.g_context={}
-#ATTENTION SURCHARGE: a garder en synchro ou a reintegrer dans le Noyau
- def Build_sd(self,nom):
- """
- Methode de Noyau surchargee pour poursuivre malgre tout
- si une erreur se produit pendant la creation du concept produit
- """
- try:
- sd=Noyau.N_MACRO_ETAPE.MACRO_ETAPE.Build_sd(self,nom)
- self.state="modified"
- except AsException,e:
- # Une erreur s'est produite lors de la construction du concept
- # Comme on est dans EFICAS, on essaie de poursuivre quand meme
- # Si on poursuit, on a le choix entre deux possibilités :
- # 1. on annule la sd associée à self
- # 2. on la conserve mais il faut la retourner
- # On choisit de l'annuler
- # En plus il faut rendre coherents sdnom et sd.nom
- self.sd=None
- self.sdnom=None
- self.state="unchanged"
- self.valid=0
-
- return self.sd
-
-#ATTENTION : cette methode surcharge celle de Noyau (a garder en synchro ou a reintegrer)
- def Build_sd_old(self,nom):
- """
- Construit le concept produit de l'opérateur. Deux cas
- peuvent se présenter :
-
- - le parent n'est pas défini. Dans ce cas, l'étape prend en charge
- la création et le nommage du concept.
-
- - le parent est défini. Dans ce cas, l'étape demande au parent la
- création et le nommage du concept.
-
- """
- if not self.isactif():return
- # CCAR : meme modification que dans I_ETAPE
- if not self.isvalid(sd='non') : return
- self.sdnom=nom
- try:
- # On positionne la macro self en tant que current_step pour que les
- # étapes créées lors de l'appel à sd_prod et à op_init aient la macro
- # comme parent
- self.set_current_step()
- if self.parent:
- sd= self.parent.create_sdprod(self,nom)
- if type(self.definition.op_init) == types.FunctionType:
- apply(self.definition.op_init,(self,self.parent.g_context))
- else:
- sd=self.get_sd_prod()
- if sd != None and self.reuse == None:
- # On ne nomme le concept que dans le cas de non reutilisation
- # d un concept
- sd.nom=nom
- self.reset_current_step()
- # Si on est arrive ici, l'etape est valide
- self.state="unchanged"
- self.valid=1
- if self.jdc and self.jdc.par_lot == "NON" :
- self.Execute()
- return sd
- except AsException,e:
- self.reset_current_step()
- # Une erreur s'est produite lors de la construction du concept
- # Comme on est dans EFICAS, on essaie de poursuivre quand meme
- # Si on poursuit, on a le choix entre deux possibilités :
- # 1. on annule la sd associée à self
- # 2. on la conserve mais il faut qu'elle soit correcte et la retourner
- # En plus il faut rendre coherents sdnom et sd.nom
- # On choisit de retourner None et de mettre l'etape invalide
- self.sd=None
- self.sdnom=None
- self.state="unchanged"
- self.valid=0
- return self.sd
- #raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
- # 'fichier : ',self.appel[1],e)
- except EOFError:
- raise
- except :
- self.reset_current_step()
- l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2])
- raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
- 'fichier : ',self.appel[1]+'\n',
- string.join(l))
-
def make_contexte_include(self,fichier,text):
"""
Cette méthode sert à créer un contexte en interprétant un texte source
if hasattr(self,'fichier_unite') :
self.parent.record_unit(self.fichier_unite,self)
- def make_poursuite(self):
- """ Cette methode est appelée par la fonction sd_prod de la macro POURSUITE
- """
- if not hasattr(self,'fichier_ini') :
- # Si le fichier n'est pas defini on le demande
- f,text=self.get_file_memo(fic_origine=self.parent.nom)
- # On memorise le fichier retourne
- self.fichier_ini = f
- self.fichier_unite = None
- self.fichier_text = text
- self.fichier_err=None
- import Extensions.jdc_include
- self.JdC_aux=Extensions.jdc_include.JdC_poursuite
- self.contexte_fichier_init={}
-
- if f is None:
- self.fichier_err="Le fichier POURSUITE n'est pas defini"
- self.parent.record_unit(None,self)
- raise Exception(self.fichier_err)
-
- try:
- self.make_contexte_include(self.fichier_ini,self.fichier_text)
- self.parent.record_unit(None,self)
- except:
- l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
- if self.jdc.appli:
- self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier poursuite",
- message="Ce fichier ne sera pas pris en compte\n"+string.join(l)
- )
- self.parent.record_unit(None,self)
- self.g_context={}
- self.fichier_err = string.join(l)
- self.contexte_fichier_init={}
- raise
-
- else:
- # Si le fichier est deja defini on ne reevalue pas le fichier
- # et on leve une exception si une erreur a été enregistrée
- self.update_fichier_init(None)
- if self.fichier_err is not None: raise Exception(self.fichier_err)
-
- def get_file(self,unite=None,fic_origine=''):
+ def get_file_memo(self,unite=None,fic_origine=''):
"""Retourne le nom du fichier et le source correspondant a l'unite unite
Initialise en plus recorded_units
"""
units={}
- if self.jdc :
+ if self.parent.old_recorded_units.has_key(unite):
+ f,text,units=self.parent.old_recorded_units[unite]
+ self.recorded_units=units
+ return f,text
+ elif self.jdc :
f,text=self.jdc.get_file(unite=unite,fic_origine=fic_origine)
else:
f,text=None,None
self.recorded_units=units
+ if f is None and self.jdc.appli:
+ self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
+ message="Ce fichier ne sera pas pris en compte\n"+"Le fichier associé n'est pas défini")
return f,text
- def get_file_memo(self,unite=None,fic_origine=''):
+#ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
+ def get_file(self,unite=None,fic_origine=''):
"""Retourne le nom du fichier et le source correspondant a l'unite unite
Initialise en plus recorded_units
"""
units={}
- if self.parent.old_recorded_units.has_key(unite):
- f,text,units=self.parent.old_recorded_units[unite]
- self.recorded_units=units
- return f,text
- elif self.jdc :
+ if self.jdc :
f,text=self.jdc.get_file(unite=unite,fic_origine=fic_origine)
else:
f,text=None,None
self.recorded_units=units
- if f is None and self.jdc.appli:
- self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
- message="Ce fichier ne sera pas pris en compte\n"+"Le fichier associé n'est pas défini")
return f,text
-#ATTENTION : cette methode surcharge celle de Noyau (a garder en synchro)
+#ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
def make_include(self,unite=None):
"""
Inclut un fichier dont l'unite logique est unite
if self.fichier_err is not None: raise Exception(self.fichier_err)
-#ATTENTION : cette methode surcharge celle de Noyau (a garder en synchro)
+#ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
def make_contexte(self,fichier,text):
"""
Cette méthode sert à créer un contexte pour INCLUDE_MATERIAU
self.contexte_fichier_init={}
raise
-#ATTENTION : cette methode surcharge celle de Noyau (a garder en synchro)
+#ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
def update_sdprod(self,cr='non'):
# Cette methode peut etre appelee dans EFICAS avec des mots cles de
# la commande modifies. Ceci peut conduire a la construction ou
CONTEXT.unset_current_step()
return valid
+#ATTENTION SURCHARGE: cette methode surcharge celle de Noyau a garder en synchro
+ def Build_sd(self,nom):
+ """
+ Methode de Noyau surchargee pour poursuivre malgre tout
+ si une erreur se produit pendant la creation du concept produit
+ """
+ try:
+ sd=Noyau.N_MACRO_ETAPE.MACRO_ETAPE.Build_sd(self,nom)
+ self.state="modified"
+ except AsException,e:
+ # Une erreur s'est produite lors de la construction du concept
+ # Comme on est dans EFICAS, on essaie de poursuivre quand meme
+ # Si on poursuit, on a le choix entre deux possibilités :
+ # 1. on annule la sd associée à self
+ # 2. on la conserve mais il faut la retourner
+ # On choisit de l'annuler
+ # En plus il faut rendre coherents sdnom et sd.nom
+ self.sd=None
+ self.sdnom=None
+ self.state="unchanged"
+ self.valid=0
+
+ return self.sd
+
+#ATTENTION SURCHARGE: cette methode surcharge celle de Noyau a garder en synchro
+ def make_poursuite(self):
+ """ Cette methode est appelée par la fonction sd_prod de la macro POURSUITE
+ """
+ if not hasattr(self,'fichier_ini') :
+ # Si le fichier n'est pas defini on le demande
+ f,text=self.get_file_memo(fic_origine=self.parent.nom)
+ # On memorise le fichier retourne
+ self.fichier_ini = f
+ self.fichier_unite = None
+ self.fichier_text = text
+ self.fichier_err=None
+ import Extensions.jdc_include
+ self.JdC_aux=Extensions.jdc_include.JdC_poursuite
+ self.contexte_fichier_init={}
+
+ if f is None:
+ self.fichier_err="Le fichier POURSUITE n'est pas defini"
+ self.parent.record_unit(None,self)
+ raise Exception(self.fichier_err)
+
+ try:
+ self.make_contexte_include(self.fichier_ini,self.fichier_text)
+ self.parent.record_unit(None,self)
+ except:
+ l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
+ if self.jdc.appli:
+ self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier poursuite",
+ message="Ce fichier ne sera pas pris en compte\n"+string.join(l)
+ )
+ self.parent.record_unit(None,self)
+ self.g_context={}
+ self.fichier_err = string.join(l)
+ self.contexte_fichier_init={}
+ raise
+
+ else:
+ # Si le fichier est deja defini on ne reevalue pas le fichier
+ # et on leve une exception si une erreur a été enregistrée
+ self.update_fichier_init(None)
+ if self.fichier_err is not None: raise Exception(self.fichier_err)
+
#
# ======================================================================
import I_MCCOMPO
-class MCBLOC(I_MCCOMPO.MCCOMPO):
- def makeobjet(self):
- return self.definition(val = None, nom = self.nom,parent = self.parent)
+class MCBLOC(I_MCCOMPO.MCCOMPO):pass
return 0
def isoblig(self):
- return self.definition.statut=='o'
+ return 0
def addentite(self,name,pos=None):
"""
nom = mc.nom
del self.jdc.mc_globaux[nom]
- def copy(self):
- """ Retourne une copie de self """
- objet = self.makeobjet()
- # FR : attention !!! avec makeobjet, objet a le même parent que self
- # ce qui n'est pas du tout bon dans le cas d'une copie !!!!!!!
- # FR : peut-on passer par là autrement que dans le cas d'une copie ???
- # FR --> je suppose que non
- # XXX CCAR : le pb c'est qu'on vérifie ensuite quel parent avait l'objet
- # Il me semble preferable de changer le parent a la fin quand la copie est acceptee
- objet.valeur = copy(self.valeur)
- objet.val = copy(self.val)
- objet.mc_liste=[]
- for obj in self.mc_liste:
- new_obj = obj.copy()
- new_obj.reparent(objet)
- objet.mc_liste.append(new_obj)
- return objet
-
- def get_sd_utilisees(self):
- """
- Retourne la liste des concepts qui sont utilisés à l'intérieur de self
- ( comme valorisation d'un MCS)
- """
- l=[]
- for child in self.mc_liste:
- l.extend(child.get_sd_utilisees())
- return l
-
def get_liste_mc_inconnus(self):
"""
Retourne la liste des mots-clés inconnus dans self
"""
liste_ajouts = []
liste_retraits = []
- dict = self.cree_dict_valeurs(self.mc_liste)
+ dict = self.cree_dict_condition(self.mc_liste)
for k,v in self.definition.entites.items():
if v.label=='BLOC' :
globs= self.jdc and self.jdc.condition_context or {}
liste_retraits.append(k)
return liste_ajouts,liste_retraits
- def reparent(self,parent):
- """
- Cette methode sert a reinitialiser la parente de l'objet
- """
- self.parent=parent
- self.jdc=parent.get_jdc_root()
- self.etape=parent.etape
- for mocle in self.mc_liste:
- mocle.reparent(self)
-
def verif_existence_sd(self):
"""
Vérifie que les structures de données utilisées dans self existent bien dans le contexte
else :
return 0
- def makeobjet(self):
- return self.definition(val = None, nom = self.nom,parent = self.parent)
+ def isoblig(self):
+ return self.definition.statut=='o'
Une MCList n'est jamais obligatoire (même si le MCFACT qu'elle représente l'est
"""
return 0
- #for i in self.data:
- # if i.isoblig():return 1
- #return 0
def liste_mc_presents(self):
return []
for child in self.data :
child.replace_concept(old_sd,sd)
- def copy(self):
- """
- Réalise la copie d'une MCList
- """
- liste = self.data[0].definition.list_instance()
- # FR -->Il faut spécifier un parent pour la méthode init qui attend 2 arguments ...
- liste.init(self.nom,self.parent)
- for objet in self:
- new_obj = objet.copy()
- # Pour etre coherent avec le constructeur de mots cles facteurs N_FACT.__call__
- # dans lequel le parent de l'element d'une MCList est le parent de la MCList
- new_obj.reparent(self.parent)
- liste.append(new_obj)
- return liste
-
def get_docu(self):
return self.data[0].definition.get_docu()
if self.parent:
self.parent.init_modif()
- def get_etape(self):
- """
- Retourne l'étape à laquelle appartient self
- Un objet de la catégorie etape doit retourner self pour indiquer que
- l'étape a été trouvée
- XXX double emploi avec self.etape ???
- """
- if self.parent == None: return None
- return self.parent.get_etape()
-
def get_genealogie(self):
"""
Retourne la liste des noms des ascendants.
dico=objet_cata.entites
return objet_cata.ordre_mc
- def reparent(self,parent):
- """
- Cette methode sert a reinitialiser la parente de l'objet
- """
- self.parent=parent
- self.jdc=parent.jdc
- self.etape=parent.etape
- for mcfact in self.data:
- mcfact.reparent(parent)
-
def verif_existence_sd(self):
"""
Vérifie que les structures de données utilisées dans self existent bien dans le contexte
for motcle in self.data :
motcle.verif_existence_sd()
- def get_sd_utilisees(self):
- """
- Retourne la liste des concepts qui sont utilisés à l'intérieur de self
- ( comme valorisation d'un MCS)
- """
- l=[]
- for motcle in self.data:
- l.extend(motcle.get_sd_utilisees())
- return l
-
def get_fr(self):
"""
Retourne la chaine d'aide contenue dans le catalogue
elif isinstance(self.valeur,ASSD):
# Cas des ASSD
txt=self.getval()
- elif type(self.valeur) == types.InstanceType and val.__class__.__name__ in ('PARAMETRE','PARAMETRE_EVAL'):
+ elif type(self.valeur) == types.InstanceType and self.valeur.__class__.__name__ in ('PARAMETRE','PARAMETRE_EVAL'):
# Cas des PARAMETRES
txt=str(self.valeur)
else:
def isoblig(self):
return self.definition.statut=='o'
-# def set_valeur(self,new_valeur,evaluation='oui'):
-# """
-# Remplace la valeur de self(si elle existe) par new_valeur
-# - si evaluation = 'oui' :
-# essaie d'évaluer new_valeur dans le contexte
-# - si evaluation = 'non' :
-# n'essaie pas d'évaluer (on stocke une string ou
-# une valeur de la liste into )
-# """
-# if evaluation == 'oui' and not self.wait_assd_or_geom():
-# valeur,test = self.eval_valeur(new_valeur)
-# if test :
-# self.val = new_valeur
-# self.valeur = valeur
-# self.init_modif()
-# self.fin_modif()
-# return 1
-# else:
-# # On n'a pas trouve de concept ni réussi à évaluer la valeur
-# # dans le contexte
-# # Si le mot cle simple attend un type CO on crée un objet de ce
-# # type de nom new_valeur
-# if self.wait_co():
-# try:
-# # Pour avoir la classe CO avec tous ses comportements
-# from Accas import CO
-# self.valeur=CO(new_valeur)
-# except:
-# traceback.print_exc()
-# return 0
-# self.init_modif()
-# self.val=self.valeur
-# self.fin_modif()
-# return 1
-# elif type(new_valeur)==types.StringType and self.wait_TXM():
-# self.init_modif()
-# self.val = new_valeur
-# self.valeur = new_valeur
-# self.fin_modif()
-# return 1
-# else:
-# return 0
-# else :
- # on ne fait aucune vérification ...
def set_valeur(self,new_valeur,evaluation='oui'):
self.init_modif()
self.valeur = new_valeur
self.val=sd
self.init_modif()
- def copy(self):
- """ Retourne une copie de self """
- objet = self.makeobjet()
- # il faut copier les listes et les tuples mais pas les autres valeurs
- # possibles (réel,SD,...)
- if type(self.valeur) in (types.ListType,types.TupleType):
- objet.valeur = copy(self.valeur)
- else:
- objet.valeur = self.valeur
- objet.val = objet.valeur
- return objet
-
- def makeobjet(self):
- return self.definition(val = None, nom = self.nom,parent = self.parent)
-
- def get_sd_utilisees(self):
- """
- Retourne une liste qui contient la SD utilisée par self si c'est le cas
- ou alors une liste vide
- """
- l=[]
- if type(self.valeur) == types.InstanceType:
- #XXX Est ce différent de isinstance(self.valeur,ASSD) ??
- if issubclass(self.valeur.__class__,ASSD) : l.append(self.valeur)
- return l
-
-
def set_valeur_co(self,nom_co):
"""
Affecte à self l'objet de type CO et de nom nom_co
self.etape.get_type_produit(force=1)
return 1,"Concept créé"
- def reparent(self,parent):
- """
- Cette methode sert a reinitialiser la parente de l'objet
- """
- self.parent=parent
- self.jdc=parent.jdc
- self.etape=parent.etape
-
def verif_existence_sd(self):
"""
Vérifie que les structures de données utilisées dans self existent bien dans le contexte
#ATTENTION SURCHARGE : toutes les methodes ci apres sont des surcharges du Noyau et de Validation
# Elles doivent etre reintegrees des que possible
- def is_complexe(self,valeur):
- """ Retourne 1 si valeur est un complexe, 0 sinon """
- if type(valeur) == types.InstanceType :
- #XXX je n'y touche pas pour ne pas tout casser mais il serait
- #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('C'), par exemple
- if valeur.__class__.__name__ in ('EVAL','complexe','PARAMETRE_EVAL'):
- return 1
- elif valeur.__class__.__name__ in ('PARAMETRE',):
- # il faut tester si la valeur du parametre est un entier
- #XXX ne serait ce pas plutot complexe ???? sinon expliquer
- return self.is_complexe(valeur.valeur)
- else:
- print "Objet non reconnu dans is_complexe %s" %`valeur`
- return 0
- # Pour permettre l'utilisation de complexes Python
- #elif type(valeur) == types.ComplexType:
- #return 1
- elif type(valeur) == types.ListType :
- # On n'autorise pas les listes de complexes
- return 0
- elif type(valeur) != types.TupleType :
- # Un complexe doit etre un tuple
- return 0
- else:
- if len(valeur) != 3 :
- return 0
- else:
- if type(valeur[0]) != types.StringType : return 0
- if string.strip(valeur[0]) not in ('RI','MP'):
- return 0
- else:
- if not self.is_reel(valeur[1]) or not self.is_reel(valeur[2]) : return 0
- else: return 1
-
- def is_reel(self,valeur):
- """
- Retourne 1 si valeur est un reel, 0 sinon
- """
- if type(valeur) == types.InstanceType :
- #XXX je n'y touche pas pour ne pas tout casser mais il serait
- #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('R'), par exemple
- #XXX ou valeur.is_reel()
- #XXX ou encore valeur.compare(self.is_reel)
- if valeur.__class__.__name__ in ('EVAL','reel','PARAMETRE_EVAL') :
- return 1
- elif valeur.__class__.__name__ in ('PARAMETRE',):
- # il faut tester si la valeur du parametre est un réel
- return self.is_reel(valeur.valeur)
- else:
- print "Objet non reconnu dans is_reel %s" %`valeur`
- return 0
- elif 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) == types.InstanceType :
- #XXX je n'y touche pas pour ne pas tout casser mais il serait
- #XXX préférable d'appeler une méthode de valeur : return valeur.is_type('I'), par exemple
- if valeur.__class__.__name__ in ('EVAL','entier','PARAMETRE_EVAL') :
- return 1
- elif valeur.__class__.__name__ in ('PARAMETRE',):
- # il faut tester si la valeur du parametre est un entier
- return self.is_entier(valeur.valeur)
- else:
- print "Objet non reconnu dans is_reel %s" %`valeur`
- return 0
- elif type(valeur) not in (types.IntType,types.LongType):
- # ce n'est pas un entier
- return 0
- else:
- return 1
-
- def is_object_from(self,objet,classe):
- """
- Retourne 1 si valeur est un objet de la classe classe ou d'une
- sous-classe de classe, 0 sinon
- """
- if type(objet) != types.InstanceType :
- return 0
- if not objet.__class__ == classe and not issubclass(objet.__class__,classe):
- return 0
- else:
- return 1
-
- def get_valid(self):
- if hasattr(self,'valid'):
- return self.valid
- else:
- self.valid=None
- return None
-
- def set_valid(self,valid):
- old_valid=self.get_valid()
- self.valid = valid
- self.state = 'unchanged'
- if not old_valid or old_valid != self.valid :
- self.init_modif_up()
-
- def isvalid(self,cr='non'):
- """
- Cette méthode retourne un indicateur de validité de l'objet de type MCSIMP
-
- - 0 si l'objet est invalide
- - 1 si l'objet est valide
-
- Le paramètre cr permet de paramétrer le traitement. Si cr == 'oui'
- la méthode construit également un comte-rendu de validation
- dans self.cr qui doit avoir été créé préalablement.
- """
- if self.state == 'unchanged':
- return self.valid
- else:
- v=self.valeur
- valid = 1
- # verifiaction presence
- if self.isoblig() and v == None :
- if cr == 'oui' :
- self.cr.fatal(string.join(("Mot-clé : ",self.nom," obligatoire non valorisé")))
- valid = 0
-
- if v is None:
- valid=0
- if cr == 'oui' :
- self.cr.fatal("None n'est pas une valeur autorisée")
- else:
- # type,into ...
- 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
- # fin des validateurs
- #
-
- self.set_valid(valid)
- return self.valid
-
- 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
- """
- if self.definition.into == None :
- #on est dans le cas d'un ensemble continu de valeurs possibles (intervalle)
- if type(self.valeur)==types.TupleType :
- test = 1
- for val in self.valeur :
- if type(val)!=types.StringType and type(val)!=types.InstanceType:
- test = test*self.isinintervalle(val,cr=cr)
- return test
- else :
- val = self.valeur
- if type(val)!=types.StringType and type(val)!=types.InstanceType:
- return self.isinintervalle(self.valeur,cr=cr)
- else :
- return 1
- else :
- # on est dans le cas d'un ensemble discret de valeurs possibles (into)
- # PN : pour résoudre le pb du copier /coller de la liste Ordonnee
- # if type(self.valeur) == types.TupleType :
- if type(self.valeur) in (types.ListType,types.TupleType) :
- for e in self.valeur:
- if e not in self.definition.into:
- if cr=='oui':
- self.cr.fatal(string.join(("La valeur :",`e`," n'est pas permise pour le mot-clé :",self.nom)))
- return 0
- else:
- if self.valeur == None or self.valeur not in self.definition.into:
- if cr=='oui':
- self.cr.fatal(string.join(("La valeur :",`self.valeur`," n'est pas permise pour le mot-clé :",self.nom)))
- return 0
- return 1
-
else:
return [string.strip(self.nom)]
- def reparent(self,parent):
- """
- Cette methode sert a reinitialiser la parente de l'objet
- """
- self.parent=parent
- self.jdc=parent.jdc
-
def get_fr(self):
"""
Retourne la chaine d'aide contenue dans le catalogue
except:
return ''
-
self.state="unchanged"
self.valid=0
- def Build_sd_old(self):
- """
- Cette methode applique la fonction op_init au contexte du parent
- et lance l'exécution en cas de traitement commande par commande
- Elle doit retourner le concept produit qui pour une PROC est toujours None
- En cas d'erreur, elle leve une exception : AsException ou EOFError
- """
- if not self.isactif():return
- try:
- if self.parent:
- if type(self.definition.op_init) == types.FunctionType:
- apply(self.definition.op_init,(self,self.parent.g_context))
- else:
- pass
- if self.jdc.par_lot == "NON" :
- self.Execute()
- except AsException,e:
- raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
- 'fichier : ',self.appel[1],e)
- except EOFError:
- raise
- except :
- l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2])
- raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
- 'fichier : ',self.appel[1]+'\n',
- string.join(l))
"""
import types
-import Noyau.N_VALIDATOR
class Valid:
"""
Cette classe est la classe mere de toutes les classes complémentaires
que l'on trouve dans Ihm.
- Elle porte les comportements par défaut des méthodes des validateurs.
"""
- def info_erreur_item(self):
- """
- Cette méthode permet d'avoir un message d'erreur pour un item
- dans une liste dans le cas ou le validateur fait des vérifications
- sur les items d'une liste. Si le validateur fait des vérifications
- sur la liste elle meme et non sur ses items, la méthode
- doit retourner une chaine vide.
- """
- return " "
+class ListVal(Valid):pass
- def aide(self):
- """
- Cette methode retourne une chaine de caractère qui permet à EFICAS de construire
- un message d'aide en ligne
- En général, le message retourné est le meme que celui retourné par la
- méthode info
- """
- return self.info()
+class RangeVal(ListVal):pass
- def info_erreur_liste(self):
- """
- Cette méthode a un comportement complémentaire de celui de info_erreur_item.
- Elle retourne un message d'erreur lié uniquement aux vérifications sur la liste
- elle meme et pas sur ses items. Dans le cas où le validateur ne fait pas de vérification
- sur des listes, elle retourne une chaine vide
- """
- return " "
+class CardVal(Valid):pass
- def is_list(self):
- """
- Cette méthode retourne un entier qui indique si le validateur permet les listes (valeur 1)
- ou ne les permet pas (valeur 0).
- Par défaut, un validateur n'autorise que des scalaires.
- """
- return 0
+class PairVal(ListVal):pass
- def has_into(self):
- """
- Cette méthode retourne un entier qui indique si le validateur propose une liste de choix (valeur 1)
- ou n'en propose pas.
- Par défaut, un validateur n'en propose pas.
- """
- return 0
-
- def valide_liste_partielle(self,liste_courante):
- """
- Cette methode retourne un entier qui indique si liste_courante est partiellement valide (valeur 1)
- ou invalide (valeur 0). La validation partielle concerne les listes en cours de construction : on
- veut savoir si la liste en construction peut etre complétée ou si elle peut déjà etre considérée
- comme invalide.
- En général un validateur effectue la meme validation pour les listes partielles et les
- listes complètes.
- """
- return self.verif(liste_courante)
-
- def verif_item(self,valeur):
- """
- La methode verif du validateur effectue une validation complete de la valeur.
- valeur peut etre un scalaire ou une liste. Le validateur doit traiter les 2
- aspects s'il accepte des listes (dans ce cas la methode is_list doit retourner 1).
- La methode valid_item sert pour effectuer des validations partielles de liste
- Elle doit uniquement verifier la validite d'un item de liste mais pas les caracteristiques
- de la liste
- """
- return 0
-
- def get_into(self,liste_courante=None,into_courant=None):
- """
- Cette méthode retourne la liste de choix proposée par le validateur. Si le validateur ne propose
- pas de liste de choix, la méthode retourne None.
- L'argument d'entrée liste_courante, s'il est différent de None, donne la liste des choix déjà
- effectués par l'utilisateur. Dans ce cas, la méthode get_into doit calculer la liste des choix
- en en tenant compte. Par exemple, si le validateur n'autorise pas les répétitions, la liste des
- choix retournée ne doit pas contenir les choix déjà contenus dans liste_courante.
- L'argument d'entrée into_courant, s'il est différent de None, donne la liste des choix proposés
- par d'autres validateurs. Dans ce cas, la méthode get_into doit calculer la liste des choix à retourner
- en se limitant à cette liste initiale. Par exemple, si into_courant vaut (1,2,3) et que le validateur
- propose la liste de choix (3,4,5), la méthode ne doit retourner que (3,).
-
- La méthode get_into peut retourner une liste vide [], ce qui veut dire qu'il n'y a pas (ou plus) de choix possible
- Cette situation peut etre normale : l''utilisateur a utilisé tous les choix, ou résulter d'une incohérence
- des validateurs : choix parmi (1,2,3) ET choix parmi (4,5,6). Il est impossible de faire la différence entre
- ces deux situations.
- """
- return into_courant
-
- def is_eval(self,valeur):
- """
- Cette méthode indique si valeur est un objet de type EVAL ou autre
- que l'on ne cherchera pas à evaluer et qui doit etre considere comme toujours valide
- Si c'est un objet de ce type elle retourne la valeur 1 sinon la valeur 0
- """
- if type(valeur) == types.InstanceType :
- if hasattr(valeur,'__class__'):
- if valeur.__class__.__name__ in ('EVAL','entier','reel','chaine','complexe','liste','PARAMETRE_EVAL') :
- return 1
- return 0
-
- def is_param(self,valeur):
- """
- Cette méthode indique si valeur est un objet de type PARAMETRE
- dont on cherchera à evaluer la valeur (valeur.valeur)
- """
- if type(valeur) == types.InstanceType :
- if valeur.__class__.__name__ in ('PARAMETRE',):
- return 1
- return 0
-
- def is_unknown(self,valeur):
- """
- Cette méthode indique si valeur est un objet de type inconnu
- c'est à dire ni de type EVAL ni de type PARAMETRE
- """
- if type(valeur) == types.InstanceType :
- if not self.is_eval(valeur) and not self.is_param(valeur):
- return 1
- return 0
-
- def surcharge_verif(self,methode_verif_initiale,valeur):
- if type(valeur) == types.InstanceType :
- #CCAR: pour le moment on fait comme dans is_entier de V_MCSIMP.py
- # mais il serait préférable d'appeler une méthode de valeur : valeur.AsType()
- # qui donnerait le type générique de l'objet.
- # Pour un objet de "type" entier on obtiendrait par exemple 'I'
- if valeur.__class__.__name__ in ('EVAL','entier','reel','chaine','complexe','liste','PARAMETRE_EVAL') :
- # On ne vérifie pas le type d'un EVAL ou d'un objet de classe entier, .... C'est toujours valide
- return 1
- elif valeur.__class__.__name__ in ('PARAMETRE',):
- # Dans le cas d'un parametre, il faut tester si la valeur du parametre est un entier
- valeur=valeur.valeur
- else:
- # Objet inconnu : invalide
- print "Objet non reconnu dans surcharge_verif : %s" %`valeur`
- return 0
-
- return methode_verif_initiale(self,valeur)
-
-class FunctionVal(Valid):pass
-
-class OrVal(Valid):
- def verif_item(self,valeur):
- for validator in self.validators:
- v=validator.verif_item(valeur)
- if v :
- return 1
- return 0
-
- def info_erreur_item(self):
- l=[]
- for v in self.validators:
- err=v.info_erreur_item()
- if err != " " : l.append(err)
- chaine=" \n ou ".join(l)
- return chaine
-
- def info_erreur_liste(self):
- l=[]
- for v in self.validators:
- err=v.info_erreur_liste()
- if err != " " : l.append(err)
- chaine=" \n ou ".join(l)
- return chaine
-
- def is_list(self):
- """
- Si plusieurs validateurs sont reliés par un OU
- il suffit qu'un seul des validateurs attende une liste
- pour qu'on considère que leur union attende une liste.
- """
- for validator in self.validators:
- v=validator.is_list()
- if v :
- return 1
- return 0
-
- def has_into(self):
- """
- Dans le cas ou plusieurs validateurs sont reliés par un OU
- il faut que tous les validateurs proposent un choix pour
- qu'on considère que leur union propose un choix.
- Exemple : Enum(1,2,3) OU entier pair, ne propose pas de choix
- En revanche, Enum(1,2,3) OU Enum(4,5,6) propose un choix (1,2,3,4,5,6)
- """
- for validator in self.validators:
- v=validator.has_into()
- if not v :
- return 0
- return 1
-
- def get_into(self,liste_courante=None,into_courant=None):
- """
- Dans le cas ou plusieurs validateurs sont reliés par un OU
- tous les validateurs doivent proposer un choix pour
- qu'on considère que leur union propose un choix.
- Tous les choix proposés par les validateurs sont réunis (opérateur d'union)
- Exemple : Enum(1,2,3) OU entier pair, ne propose pas de choix
- En revanche, Enum(1,2,3) OU Enum(4,5,6) propose un choix (1,2,3,4,5,6)
- """
- validator_into=[]
- for validator in self.validators:
- v_into=validator.get_into(liste_courante,into_courant)
- if v_into is None:
- return v_into
- validator_into.extend(v_into)
- return validator_into
-
- def valide_liste_partielle(self,liste_courante=None):
- """
- Méthode de validation de liste partielle pour le validateur Or.
- Si un des validateurs gérés par le validateur Or considère la liste comme
- valide, le validateur Or la considère comme valide.
- """
- for validator in self.validators:
- v=validator.valide_liste_partielle(liste_courante)
- if v :
- return 1
- return 0
-
-class AndVal(Valid):
- def info(self):
- return "\n et ".join([v.info() for v in self.validators])
-
- def info_erreur_item(self):
- chaine=""
- a=1
- for v in self.validators:
- if v.info_erreur_item() != " " :
- if a==1:
- chaine=v.info_erreur_item()
- a=0
- else:
- chaine=chaine+" \n et "+v.info_erreur_item()
- return chaine
-
- def info_erreur_liste(self):
- a=1
- for v in self.validators:
- if v.info_erreur_liste() != " " :
- if a==1:
- chaine=v.info_erreur_liste()
- a=0
- else:
- chaine=chaine+" \n et "+v.info_erreur_liste()
- return chaine
-
- def verif_item(self,valeur):
- for validator in self.validators:
- v=validator.verif_item(valeur)
- if not v :
- # L'info n'est probablement pas la meme que pour verif ???
- self.local_info=validator.info()
- return 0
- return 1
-
- def valide_liste_partielle(self,liste_courante=None):
- """
- Méthode de validation de liste partielle pour le validateur And.
- Tous les validateurs gérés par le validateur And doivent considèrer la liste comme
- valide, pour que le validateur And la considère comme valide.
- """
- for validator in self.validators:
- v=validator.valide_liste_partielle(liste_courante)
- if not v :
- return 0
- return 1
-
- def is_list(self):
- """
- Si plusieurs validateurs sont reliés par un ET
- il faut que tous les validateurs attendent une liste
- pour qu'on considère que leur intersection attende une liste.
- Exemple Range(2,5) ET Card(1) n'attend pas une liste
- Range(2,5) ET Pair attend une liste
- """
- for validator in self.validators:
- v=validator.is_list()
- if v == 0 :
- return 0
- return 1
-
- def has_into(self):
- """
- Dans le cas ou plusieurs validateurs sont reliés par un ET
- il suffit qu'un seul validateur propose un choix pour
- qu'on considère que leur intersection propose un choix.
- Exemple : Enum(1,2,3) ET entier pair, propose un choix
- En revanche, entier pair ET superieur à 10 ne propose pas de choix
- """
- for validator in self.validators:
- v=validator.has_into()
- if v :
- return 1
- return 0
-
-
- def get_into(self,liste_courante=None,into_courant=None):
- """
- Dans le cas ou plusieurs validateurs sont reliés par un ET
- il suffit qu'un seul validateur propose un choix pour
- qu'on considère que leur intersection propose un choix.
-
- Tous les choix proposés par les validateurs sont croisés (opérateur d'intersection)
- Exemple : Enum(1,2,3) ET entier pair, propose un choix (2,)
- En revanche, Enum(1,2,3) ET Enum(4,5,6) ne propose pas de choix
- """
- for validator in self.validators:
- into_courant=validator.get_into(liste_courante,into_courant)
- if into_courant in ([],None):
- return into_courant
- return into_courant
-
-class CardVal(Valid):
- def info(self):
- return "longueur de liste comprise entre %s et %s" % (self.min,self.max)
-
- def is_list(self):
- if self.max == '**' or self.max > 1:
- return 1
- else:
- return 0
-
- def verif_item(self,valeur):
- return 1
-
- def valide_liste_partielle(self,liste_courante=None):
- validite=1
- if liste_courante != None :
- if len(liste_courante) > self.max :
- validite=0
- return validite
-
- def get_into(self,liste_courante=None,into_courant=None):
- if into_courant is None:
- return None
- elif liste_courante is None:
- return into_courant
- elif self.max == '**':
- return into_courant
- elif len(liste_courante) < self.max:
- return into_courant
- else:
- return []
-
- def info_erreur_liste(self):
- return "La cardinalité de la liste doit être comprise entre %s et %s" % (self.min,self.max)
-
-class ListVal(Valid):
- 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
-
-class EnumVal(ListVal):
- def verif_item(self,valeur):
- if valeur not in self.into:return 0
- return 1
-
- def has_into(self):
- return 1
-
- def get_into(self,liste_courante=None,into_courant=None):
- if into_courant is None:
- liste_choix= list(self.into)
- else:
- liste_choix=[]
- for e in into_courant:
- if e in self.into:
- liste_choix.append(e)
- return liste_choix
-
- def info_erreur_item(self):
- return "La valeur n'est pas dans la liste des choix possibles"
+class EnumVal(ListVal):pass
-class LongStr(ListVal):
- def info_erreur_item(self):
- return "Longueur de la chaine incorrecte"
+class NoRepeat(ListVal):pass
- 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
-
-class RangeVal(ListVal):
- def verif_item(self,valeur):
- if valeur < self.low :return 0
- if valeur > self.high:return 0
- return 1
+class LongStr(ListVal):pass
- def info_erreur_item(self) :
- return "La valeur doit être comprise entre %s et %s" % (self.low,self.high)
+class OrdList(ListVal):pass
CoercableFuncs = { types.IntType: int,
types.LongType: long,
types.ComplexType: complex,
types.UnicodeType: unicode }
-class TypeVal(ListVal):
- """
- Cette classe est un validateur qui controle qu'une valeur
- est bien du type Python attendu.
- Pour une liste on verifie que tous les elements sont du bon type.
- """
- def __init__(self, aType):
- if type(aType) != types.TypeType:
- aType=type(aType)
- self.aType=aType
- try:
- self.coerce=CoercableFuncs[ aType ]
- except:
- self.coerce = self.identity
-
- def info(self):
- return "valeur de %s" % self.aType
+class TypeVal(ListVal):pass
- def identity ( self, value ):
- if type( value ) == self.aType:
- return value
- raise ValError
+class InstanceVal(ListVal):pass
- def verif(self,valeur):
- if type(valeur) in (types.ListType,types.TupleType):
- for val in valeur:
- valid=self.verif_item(val)
- if valid == 0:return 0
- return 1
- else:
- return self.verif_item(valeur)
-
- def verif_item(self,valeur):
- try:
- self.coerce(valeur)
- except:
- return 0
- return 1
-
-class PairVal(ListVal):
-
- def info_erreur_item(self):
- return "La valeur saisie doit être paire"
-
- #ATTENTION METHODE SURCHARGEE: a resorber dans une future version
- def verif_item(self,valeur):
- if self.is_eval(valeur):
- return 1
- elif self.is_param(valeur):
- valeur=valeur.valeur
- elif self.is_unknown(valeur):
- return 0
- return valeur % 2 == 0
-
- def verif(self,valeur):
- if self.is_param(valeur):
- valeur=valeur.valeur
- if type(valeur) in (types.ListType,types.TupleType):
- for val in valeur:
- if not self.verif_item(val):
- return 0
- return 1
- else:
- return self.verif_item(valeur)
-
- def verif_old(self,valeur):
- print "Ihm.I_MCSIMP.PairVal.verif: ",valeur
- return self.surcharge_verif(Noyau.N_VALIDATOR.PairVal.verif,valeur)
-
-class InstanceVal(ListVal):
- def verif_item(self,valeur):
- if not isinstance(valeur,self.aClass): return 0
- return 1
-
-class NoRepeat(ListVal):
- def info(self):
- return "pas de presence de doublon dans la liste"
-
- def info_erreur_liste(self):
- return "Les doublons ne sont pas permis"
-
- def verif_item(self,valeur):
- return 1
+class FunctionVal(Valid):pass
- 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:
- return 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 OrdList(ListVal):
- def verif_item(self,valeur):
- return 1
+class OrVal(Valid):pass
- def get_into(self,liste_courante=None,into_courant=None):
- """
- Methode get_into spécifique pour validateur OrdList
- on retourne une liste de choix qui ne contient aucune valeur de into_courant
- dont la valeur est inférieure à la dernière valeur de liste_courante, si
- elle est différente de None.
- """
- if into_courant is None:
- return None
- elif not liste_courante :
- return into_courant
- else:
- liste_choix=[]
- last_val=liste_choix[-1]
- for e in into_courant:
- if self.ord=='croissant' and e <= last_val:continue
- if self.ord=='decroissant' and e >= last_val:continue
- liste_choix.append(e)
- return liste_choix
+class AndVal(Valid):pass
- def info_erreur_liste(self) :
- return "La liste doit être en ordre "+self.ord
-