]> SALOME platform Git repositories - tools/eficas.git/blob - Ihm/I_MACRO_ETAPE.py
Salome HOME
CCAR: merge du developpement realise dans la branche BR_PN_VAL
[tools/eficas.git] / Ihm / I_MACRO_ETAPE.py
1 #            CONFIGURATION MANAGEMENT OF EDF VERSION
2 # ======================================================================
3 # COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
4 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
5 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
6 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
7 # (AT YOUR OPTION) ANY LATER VERSION.
8 #
9 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
10 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
11 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
12 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
13 #
14 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
15 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
16 #    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
17 #
18 #
19 # ======================================================================
20 """
21 """
22 # Modules Python
23 import sys
24 import traceback,types,string
25
26 # Modules Eficas
27 import I_ETAPE
28 from Noyau.N_ASSD import ASSD
29
30 # import rajoutés suite à l'ajout de Build_sd --> à résorber
31 import Noyau, Validation.V_MACRO_ETAPE
32 from Noyau import N_Exception
33 from Noyau.N_Exception import AsException
34 # fin import à résorber
35
36 class MACRO_ETAPE(I_ETAPE.ETAPE):
37
38   def __init__(self):
39       self.typret=None
40       self.recorded_units={}
41
42   def copy(self):
43       """ Méthode qui retourne une copie de self non enregistrée auprès du JDC
44           et sans sd
45           On surcharge la methode de ETAPE pour exprimer que les concepts crees
46           par la MACRO d'origine ne sont pas crees par la copie mais eventuellement 
47           seulement utilises
48       """
49       etape=I_ETAPE.ETAPE.copy(self)
50       etape.sdprods=[]
51       return etape
52
53   def get_sdprods(self,nom_sd):
54     """ 
55          Fonction : retourne le concept produit par l etape de nom nom_sd
56          s il existe sinon None
57     """
58     if self.sd and self.sd.nom == nom_sd :return self.sd
59     for co in self.sdprods:
60       if co.nom == nom_sd:return co
61     if type(self.definition.op_init) == types.FunctionType:
62       d={}
63       apply(self.definition.op_init,(self,d))
64       return d.get(nom_sd,None)
65     return None
66
67   def get_contexte_jdc(self,fichier,text):
68     """ 
69          Interprète text comme un texte de jdc et retourne le 
70          contexte final
71          cad le dictionnaire des sd disponibles à la dernière étape
72          Si text n'est pas un texte de jdc valide, retourne None
73          ou leve une exception
74          --> utilisée par ops.POURSUITE et INCLUDE
75     """
76     try:
77        # on essaie de créer un objet JDC auxiliaire avec un contexte initial
78        context_ini = self.parent.get_contexte_avant(self)
79
80        # Indispensable avant de creer un nouveau JDC
81        CONTEXT.unset_current_step()
82        args=self.jdc.args
83        prefix_include=None
84        if hasattr(self,'prefix'):
85           prefix_include=self.prefix
86        # ATTENTION : le dictionnaire recorded_units sert à memoriser les unites des 
87        # fichiers inclus. Il est preferable de garder le meme dictionnaire pendant
88        # tout le traitement et de ne pas le reinitialiser brutalement (utiliser clear plutot)
89        # si on ne veut pas perdre la memoire des unites.
90        # En principe si la memorisation est faite au bon moment il n'est pas necessaire
91        # de prendre cette precaution mais ce n'est pas vrai partout.
92        old_recorded_units=self.recorded_units.copy()
93        self.recorded_units.clear()
94
95        j=self.JdC_aux( procedure=text,cata=self.jdc.cata,
96                                 nom=fichier,
97                                 context_ini = context_ini,
98                                 appli=self.jdc.appli,
99                                 jdc_pere=self.jdc,etape_include=self,
100                                 prefix_include=prefix_include,
101                                 recorded_units=self.recorded_units,
102                                 old_recorded_units=old_recorded_units,**args)
103
104        j.analyse()
105        # On récupère les étapes internes (pour validation)
106        self.etapes=j.etapes
107     except:
108        traceback.print_exc()
109        # On force le contexte (etape courante) à self
110        CONTEXT.unset_current_step()
111        CONTEXT.set_current_step(self)
112        return None
113
114     if not j.cr.estvide():
115        # Erreurs dans l'INCLUDE. On garde la memoire du fichier mais on n'insere pas les concepts
116        # On force le contexte (etape courante) à self
117        CONTEXT.unset_current_step()
118        CONTEXT.set_current_step(self)
119        raise Exception("Impossible de relire le fichier\n"+str(j.cr))
120
121     cr=j.report()
122     if not cr.estvide():
123        # On force le contexte (etape courante) à self
124        CONTEXT.unset_current_step()
125        CONTEXT.set_current_step(self)
126        raise Exception("Le fichier include contient des erreurs\n"+str(j.cr))
127
128     # On recupere le contexte apres la derniere etape
129     j_context=j.get_contexte_avant(None)
130
131     # Cette verification n'est plus necessaire elle est integree dans le JDC_INCLUDE
132     self.verif_contexte(j_context)
133
134     # On remplit le dictionnaire des concepts produits inclus
135     # en retirant les concepts présents dans le  contexte initial
136     # On ajoute egalement le concept produit dans le sds_dict du parent
137     # sans verification car on est sur (verification integrée) que le nommage est possible
138     self.g_context.clear()
139     for k,v in j_context.items():
140        if not context_ini.has_key(k) or context_ini[k] != v:
141            self.g_context[k]=v
142            self.parent.sds_dict[k]=v
143
144
145     # On recupere le contexte courant
146     self.current_context=j.current_context
147     self.index_etape_courante=j.index_etape_courante
148
149     # XXX j.supprime() ???
150     # On rétablit le contexte (etape courante) à self
151     CONTEXT.unset_current_step()
152     CONTEXT.set_current_step(self)
153
154     return j_context
155
156   def verif_contexte(self,context):
157      """
158          On verifie que le contexte context peut etre inséré dans le jeu
159          de commandes à la position de self
160      """
161      for nom_sd,sd in context.items():
162         if not isinstance(sd,ASSD):continue
163         #if self.parent.get_sd_apres_etape(nom_sd,etape=self):
164         if self.parent.get_sd_apres_etape_avec_detruire(nom_sd,sd,etape=self):
165            # Il existe un concept produit par une etape apres self => impossible d'inserer
166            # On force le contexte (etape courante) à self
167            CONTEXT.unset_current_step()
168            CONTEXT.set_current_step(self)
169            raise Exception("Impossible d'inclure le fichier. Un concept de nom " + 
170                            "%s existe déjà dans le jeu de commandes." % nom_sd)
171
172   def reevalue_sd_jdc(self):
173      """
174          Avec la liste des SD qui ont été supprimées, propage la 
175          disparition de ces SD dans toutes les étapes et descendants
176      """
177      l_sd_supp,l_sd_repl = self.diff_contextes()
178      for sd in l_sd_supp:
179         self.parent.delete_concept_after_etape(self,sd)
180      for old_sd,sd in l_sd_repl:
181         self.parent.replace_concept_after_etape(self,old_sd,sd)
182
183   def diff_contextes(self):
184      """ 
185          Réalise la différence entre les 2 contextes 
186          old_contexte_fichier_init et contexte_fichier_init
187          cad retourne la liste des sd qui ont disparu ou ne derivent pas de la meme classe
188          et des sd qui ont ete remplacees
189      """
190      if not hasattr(self,'old_contexte_fichier_init'):return [],[]
191      l_sd_suppressed = []
192      l_sd_replaced = []
193      for old_key in self.old_contexte_fichier_init.keys():
194        if not self.contexte_fichier_init.has_key(old_key):
195          if isinstance(self.old_contexte_fichier_init[old_key],ASSD):
196            l_sd_suppressed.append(self.old_contexte_fichier_init[old_key])
197        else:
198          if isinstance(self.old_contexte_fichier_init[old_key],ASSD):
199             # Un concept de meme nom existe
200             old_class=self.old_contexte_fichier_init[old_key].__class__
201             if not isinstance(self.contexte_fichier_init[old_key],old_class):
202                # S'il n'est pas d'une classe derivee, on le supprime
203                l_sd_suppressed.append(self.old_contexte_fichier_init[old_key])
204             else:
205                l_sd_replaced.append((self.old_contexte_fichier_init[old_key],self.contexte_fichier_init[old_key]))
206      return l_sd_suppressed,l_sd_replaced
207       
208   def control_sdprods(self,d):
209       """
210           Cette methode doit updater le contexte fournit par
211           l'appelant en argument (d) en fonction de sa definition
212           tout en verifiant que ses concepts produits ne sont pas
213           deja definis dans le contexte
214       """
215       if hasattr(self,"fichier_unite"):
216          self.update_fichier_init(self.fichier_unite)
217          self.init_modif()
218
219       if type(self.definition.op_init) == types.FunctionType:
220         apply(self.definition.op_init,(self,d))
221       if self.sd:
222         if d.has_key(self.sd.nom):
223            # Le concept est deja defini
224            if self.reuse and self.reuse is d[self.sd.nom]:
225               # Le concept est reutilise : situation normale
226               pass
227            else:
228               # Redefinition du concept, on l'annule
229               #XXX on pourrait simplement annuler son nom pour conserver les objets
230               # l'utilisateur n'aurait alors qu'a renommer le concept (faisable??)
231               self.sd=self.reuse=self.sdnom=None
232               self.init_modif()
233         else:
234            # Le concept n'est pas defini, on peut updater d
235            d[self.sd.nom]=self.sd
236       # On verifie les concepts a droite du signe =
237       for co in self.sdprods:
238         if d.has_key(co.nom) and co is not d[co.nom] :
239            self.delete_concept(co)
240         else:
241            d[co.nom]=co
242        
243
244   def supprime_sdprods(self):
245       """
246           Fonction:
247           Lors d'une destruction d'etape, detruit tous les concepts produits
248           Un opérateur n a qu un concept produit
249           Une procedure n'en a aucun
250           Une macro en a en général plus d'un
251       """
252       if not self.is_reentrant() :
253          # l'étape n'est pas réentrante
254          # le concept retourné par l'étape est à supprimer car il était
255          # créé par l'étape
256          if self.sd != None :
257             self.parent.del_sdprod(self.sd)
258             self.parent.delete_concept(self.sd)
259       # On détruit les concepts à droite du signe =
260       for co in self.sdprods:
261          self.parent.del_sdprod(co)
262          self.parent.delete_concept(co)
263       # Si la macro a des etapes et des concepts inclus, on les detruit
264       for nom_sd,co in self.g_context.items():
265          if not isinstance(co,ASSD):continue
266          self.parent.del_sdprod(co)
267          self.parent.delete_concept(co)
268       # On met g_context à blanc
269       self.g_context={}
270          
271 #ATTENTION SURCHARGE: a garder en synchro ou a reintegrer dans le Noyau
272   def Build_sd(self,nom):
273       """
274            Methode de Noyau surchargee pour poursuivre malgre tout
275            si une erreur se produit pendant la creation du concept produit
276       """
277       try:
278          sd=Noyau.N_MACRO_ETAPE.MACRO_ETAPE.Build_sd(self,nom)
279          self.state="unchanged"
280          self.valid=1
281       except AsException,e:
282          # Une erreur s'est produite lors de la construction du concept
283          # Comme on est dans EFICAS, on essaie de poursuivre quand meme
284          # Si on poursuit, on a le choix entre deux possibilités :
285          # 1. on annule la sd associée à self
286          # 2. on la conserve mais il faut la retourner
287          # On choisit de l'annuler
288          # En plus il faut rendre coherents sdnom et sd.nom
289          self.sd=None
290          self.sdnom=None
291          self.state="unchanged"
292          self.valid=0
293
294       return self.sd
295
296 #ATTENTION : cette methode surcharge celle de Noyau (a garder en synchro ou a reintegrer)
297   def Build_sd_old(self,nom):
298      """
299         Construit le concept produit de l'opérateur. Deux cas 
300         peuvent se présenter :
301
302            - le parent n'est pas défini. Dans ce cas, l'étape prend en charge 
303              la création et le nommage du concept.
304
305            - le parent est défini. Dans ce cas, l'étape demande au parent la 
306              création et le nommage du concept.
307
308      """
309      if not self.isactif():return
310      # CCAR : meme modification que dans I_ETAPE
311      if not self.isvalid(sd='non') : return
312      self.sdnom=nom
313      try:
314         # On positionne la macro self en tant que current_step pour que les 
315         # étapes créées lors de l'appel à sd_prod et à op_init aient la macro
316         #  comme parent 
317         self.set_current_step()
318         if self.parent:
319            sd= self.parent.create_sdprod(self,nom)
320            if type(self.definition.op_init) == types.FunctionType: 
321               apply(self.definition.op_init,(self,self.parent.g_context))
322         else:
323            sd=self.get_sd_prod()
324            if sd != None and self.reuse == None:
325               # On ne nomme le concept que dans le cas de non reutilisation 
326               # d un concept
327               sd.nom=nom
328         self.reset_current_step()
329         # Si on est arrive ici, l'etape est valide
330         self.state="unchanged"
331         self.valid=1
332         if self.jdc and self.jdc.par_lot == "NON" :
333            self.Execute()
334         return sd
335      except AsException,e:
336         self.reset_current_step()
337         # Une erreur s'est produite lors de la construction du concept
338         # Comme on est dans EFICAS, on essaie de poursuivre quand meme
339         # Si on poursuit, on a le choix entre deux possibilités :
340         # 1. on annule la sd associée à self
341         # 2. on la conserve mais il faut qu'elle soit correcte et la retourner
342         # En plus il faut rendre coherents sdnom et sd.nom
343         # On choisit de retourner None et de mettre l'etape invalide 
344         self.sd=None
345         self.sdnom=None
346         self.state="unchanged"
347         self.valid=0
348         return self.sd
349         #raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
350         #                     'fichier : ',self.appel[1],e)
351      except EOFError:
352         raise
353      except :
354         self.reset_current_step()
355         l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2])
356         raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
357                           'fichier : ',self.appel[1]+'\n',
358                            string.join(l))
359
360   def make_contexte_include(self,fichier,text):
361     """
362         Cette méthode sert à créer un contexte en interprétant un texte source
363         Python
364     """
365     # on récupère le contexte d'un nouveau jdc dans lequel on interprete text
366     contexte = self.get_contexte_jdc(fichier,text)
367     if contexte == None :
368       raise Exception("Impossible de construire le jeu de commandes correspondant au fichier")
369     else:
370       # Pour les macros de type include : INCLUDE, INCLUDE_MATERIAU et POURSUITE
371       # l'attribut g_context est un dictionnaire qui contient les concepts produits par inclusion
372       # l'attribut contexte_fichier_init est un dictionnaire qui contient les concepts produits
373       # en sortie de macro. g_context est obtenu en retirant de contexte_fichier_init les concepts
374       # existants en debut de macro contenus dans context_ini (dans get_contexte_jdc)
375       # g_context est utilisé pour avoir les concepts produits par la macro
376       # contexte_fichier_init est utilisé pour avoir les concepts supprimés par la macro
377       self.contexte_fichier_init = contexte
378
379   def reevalue_fichier_init(self):
380       """Recalcule les concepts produits par le fichier enregistre"""
381       old_context=self.contexte_fichier_init
382       try:
383          self.make_contexte_include(self.fichier_ini ,self.fichier_text)
384       except:
385          l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
386          self.fichier_err = string.join(l)
387          #self.etapes=[]
388          self.g_context={}
389
390          self.old_contexte_fichier_init=old_context
391          self.contexte_fichier_init={}
392          self.reevalue_sd_jdc()
393          return
394
395       # L'evaluation s'est bien passee
396       self.fichier_err = None
397       self.old_contexte_fichier_init=old_context
398       self.reevalue_sd_jdc()
399
400   def update_fichier_init(self,unite):
401       """Reevalue le fichier init sans demander (dans la mesure du possible) a l'utilisateur 
402          les noms des fichiers
403          Ceci suppose que les relations entre unites et noms ont été memorisees préalablement
404       """
405       
406       self.fichier_err=None
407       self.old_contexte_fichier_init=self.contexte_fichier_init
408
409       if unite != self.fichier_unite or not self.parent.recorded_units.has_key(unite):
410          # Changement d'unite ou Nouvelle unite
411          f,text=self.get_file(unite=unite,fic_origine=self.parent.nom)
412          units={}
413          if f is not None:
414             self.fichier_ini = f
415             self.fichier_text=text
416          self.recorded_units=units
417          if self.fichier_ini is None and self.jdc.appli:
418             self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
419                      message="Ce fichier ne sera pas pris en compte\n"+"Le fichier associé n'est pas défini")
420       else:
421          # Meme unite existante
422          f,text,units=self.parent.recorded_units[unite]
423          self.fichier_ini = f
424          self.fichier_text=text
425          self.recorded_units=units
426
427       if self.fichier_ini is None:
428          # Le fichier n'est pas défini
429          self.fichier_err="Le fichier associé n'est pas défini"
430          self.parent.change_unit(unite,self,self.fichier_unite)
431          self.g_context={}
432          self.contexte_fichier_init={}
433          self.parent.reset_context()
434          self.reevalue_sd_jdc()
435          return
436
437       try:
438         self.make_contexte_include(self.fichier_ini,self.fichier_text)
439         # Les 3 attributs fichier_ini fichier_text recorded_units doivent etre corrects
440         # avant d'appeler change_unit
441         self.parent.change_unit(unite,self,self.fichier_unite)
442       except:
443         # Erreurs lors de l'evaluation de text dans un JDC auxiliaire
444         l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
445         # On conserve la memoire du nouveau fichier
446         # mais on n'utilise pas les concepts crees par ce fichier
447         # on met l'etape en erreur : fichier_err=string.join(l)
448         self.fichier_err=string.join(l)
449         self.parent.change_unit(unite,self,self.fichier_unite)
450         self.g_context={}
451         self.contexte_fichier_init={}
452
453       # Le contexte du parent doit etre reinitialise car les concepts produits ont changé
454       self.parent.reset_context()
455       # Si des concepts ont disparu lors du changement de fichier, on demande leur suppression
456       self.reevalue_sd_jdc()
457
458   def record_unite(self):
459       if self.nom == "POURSUITE":
460          self.parent.record_unit(None,self)
461       else:
462          if hasattr(self,'fichier_unite') : 
463             self.parent.record_unit(self.fichier_unite,self)
464
465   def make_poursuite(self):
466       """ Cette methode est appelée par la fonction sd_prod de la macro POURSUITE
467       """
468       if not hasattr(self,'fichier_ini') :
469          # Si le fichier n'est pas defini on le demande
470          f,text=self.get_file_memo(fic_origine=self.parent.nom)
471          # On memorise le fichier retourne
472          self.fichier_ini = f
473          self.fichier_unite = None
474          self.fichier_text = text
475          self.fichier_err=None
476          import Extensions.jdc_include
477          self.JdC_aux=Extensions.jdc_include.JdC_poursuite
478          self.contexte_fichier_init={}
479
480          if f is None:
481              self.fichier_err="Le fichier POURSUITE n'est pas defini"
482              self.parent.record_unit(None,self)
483              raise Exception(self.fichier_err)
484
485          try:
486            self.make_contexte_include(self.fichier_ini,self.fichier_text)
487            self.parent.record_unit(None,self)
488          except:
489            l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
490            if self.jdc.appli:
491               self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier poursuite",
492                                             message="Ce fichier ne sera pas pris en compte\n"+string.join(l)
493                                            )
494            self.parent.record_unit(None,self)
495            self.g_context={}
496            self.fichier_err = string.join(l)
497            self.contexte_fichier_init={}
498            raise
499
500       else:
501          # Si le fichier est deja defini on ne reevalue pas le fichier
502          # et on leve une exception si une erreur a été enregistrée
503          self.update_fichier_init(None)
504          if self.fichier_err is not None: raise Exception(self.fichier_err)
505
506   def get_file(self,unite=None,fic_origine=''):
507       """Retourne le nom du fichier et le source correspondant a l'unite unite
508          Initialise en plus recorded_units
509       """
510       units={}
511       if self.jdc :
512          f,text=self.jdc.get_file(unite=unite,fic_origine=fic_origine)
513       else:
514          f,text=None,None
515       self.recorded_units=units
516       return f,text
517
518   def get_file_memo(self,unite=None,fic_origine=''):
519       """Retourne le nom du fichier et le source correspondant a l'unite unite
520          Initialise en plus recorded_units
521       """
522       units={}
523       if self.parent.old_recorded_units.has_key(unite):
524          f,text,units=self.parent.old_recorded_units[unite]
525          self.recorded_units=units
526          return f,text
527       elif self.jdc :
528          f,text=self.jdc.get_file(unite=unite,fic_origine=fic_origine)
529       else:
530          f,text=None,None
531       self.recorded_units=units
532       if f is None and self.jdc.appli:
533          self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
534                           message="Ce fichier ne sera pas pris en compte\n"+"Le fichier associé n'est pas défini")
535       return f,text
536
537 #ATTENTION : cette methode surcharge celle de Noyau (a garder en synchro)
538   def make_include(self,unite=None):
539       """
540           Inclut un fichier dont l'unite logique est unite
541           Cette methode est appelee par la fonction sd_prod de la macro INCLUDE
542           Si l'INCLUDE est invalide, la methode doit produire une exception 
543           Sinon on retourne None. Les concepts produits par l'INCLUDE sont
544           pris en compte par le JDC parent lors du calcul du contexte (appel de ???)
545       """
546
547       # On supprime l'attribut unite qui bloque l'evaluation du source de l'INCLUDE
548       # car on ne s'appuie pas sur lui dans EFICAS mais sur l'attribut fichier_ini
549       del self.unite
550       # Si unite n'a pas de valeur, l'etape est forcement invalide. On peut retourner None
551       if not unite : return
552
553       if not hasattr(self,'fichier_ini') : 
554          # Si le fichier n'est pas defini on le demande
555          f,text=self.get_file_memo(unite=unite,fic_origine=self.parent.nom)
556          # On memorise le fichier retourne
557          self.fichier_ini  = f
558          self.fichier_text = text
559          self.contexte_fichier_init={}
560          self.fichier_unite=unite
561          self.fichier_err=None
562          import Extensions.jdc_include
563          self.JdC_aux=Extensions.jdc_include.JdC_include
564
565          if f is None:
566              self.fichier_err="Le fichier INCLUDE n est pas defini"
567              self.parent.record_unit(unite,self)
568              raise Exception(self.fichier_err)
569
570          try:
571            self.make_contexte_include(self.fichier_ini ,self.fichier_text)
572            self.parent.record_unit(unite,self)
573          except:
574            l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
575            if self.jdc.appli:
576               self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
577                                             message="Ce fichier ne sera pas pris en compte\n"+string.join(l)
578                                            )
579            self.parent.record_unit(unite,self)
580            self.g_context={}
581            self.fichier_err = string.join(l)
582            self.contexte_fichier_init={}
583            raise
584
585       else:
586          # Si le fichier est deja defini on ne reevalue pas le fichier
587          # et on leve une exception si une erreur a été enregistrée
588          self.update_fichier_init(unite)
589          self.fichier_unite=unite
590          if self.fichier_err is not None: raise Exception(self.fichier_err)
591         
592
593 #ATTENTION : cette methode surcharge celle de Noyau (a garder en synchro)
594   def make_contexte(self,fichier,text):
595     """
596         Cette méthode sert à créer un contexte pour INCLUDE_MATERIAU
597         en interprétant un texte source Python
598         Elle est appelee par la fonction sd_prd d'INCLUDE_MATERIAU
599     """
600     # On supprime l'attribut mat qui bloque l'evaluation du source de l'INCLUDE_MATERIAU
601     # car on ne s'appuie pas sur lui dans EFICAS mais sur l'attribut fichier_ini
602     if hasattr(self,'mat'):del self.mat
603     self.fichier_ini =fichier
604     self.fichier_unite =fichier
605     self.fichier_text=text
606     self.fichier_err=None 
607     self.contexte_fichier_init={}
608     # On specifie la classe a utiliser pour le JDC auxiliaire
609     import Extensions.jdc_include
610     self.JdC_aux=Extensions.jdc_include.JdC_include
611     try:
612        self.make_contexte_include(self.fichier_ini ,self.fichier_text)
613        self.parent.record_unit(self.fichier_unite,self)
614     except:
615        l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
616        self.fichier_err = string.join(l)
617        self.parent.record_unit(self.fichier_unite,self)
618        self.g_context={}
619        self.contexte_fichier_init={}
620        raise
621
622 #ATTENTION : cette methode surcharge celle de Noyau (a garder en synchro)
623   def update_sdprod(self,cr='non'):
624      # Cette methode peut etre appelee dans EFICAS avec des mots cles de 
625      # la commande modifies. Ceci peut conduire a la construction ou
626      # a la reconstruction d'etapes dans le cas d'INCLUDE ou d'INCLUDE_MATERIAU
627      # Il faut donc positionner le current_step avant l'appel
628      CONTEXT.unset_current_step()
629      CONTEXT.set_current_step(self)
630      valid=Validation.V_MACRO_ETAPE.MACRO_ETAPE.update_sdprod(self,cr=cr)
631      CONTEXT.unset_current_step()
632      return valid
633