1 #@ MODIF N_MACRO_ETAPE Noyau DATE 07/11/2011 AUTEUR COURTOIS M.COURTOIS
2 # -*- coding: iso-8859-1 -*-
3 # RESPONSABLE COURTOIS M.COURTOIS
4 # CONFIGURATION MANAGEMENT OF EDF VERSION
5 # ======================================================================
6 # COPYRIGHT (C) 1991 - 2011 EDF R&D WWW.CODE-ASTER.ORG
7 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
8 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
9 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
10 # (AT YOUR OPTION) ANY LATER VERSION.
12 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
13 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
14 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
15 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
17 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
18 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
19 # 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
22 # ======================================================================
26 Ce module contient la classe MACRO_ETAPE qui sert à vérifier et à exécuter
31 import types,sys,string
37 from N_Exception import AsException
39 from N_utils import AsType
41 from N_ASSD import ASSD
42 from N_info import message, SUPERV
44 class MACRO_ETAPE(N_ETAPE.ETAPE):
50 def __init__(self,oper=None,reuse=None,args={}):
54 - definition : objet portant les attributs de définition d'une étape
55 de type macro-commande. Il est initialisé par
58 - reuse : indique le concept d'entrée réutilisé. Il se trouvera donc
59 en sortie si les conditions d'exécution de l'opérateur
62 - valeur : arguments d'entrée de type mot-clé=valeur. Initialisé
66 self.definition = oper
70 self.parent = CONTEXT.get_current_step()
73 self.idracine = oper.label
74 self.appel = N_utils.callee_where()
78 self.current_context = {}
79 self.macro_const_context = {}
80 self.index_etape_courante = 0
82 self.index_etapes = {}
84 # Dans le cas d'une macro écrite en Python, l'attribut Outputs est un
85 # dictionnaire qui contient les concepts produits de sortie
86 # (nom : ASSD) déclarés dans la fonction sd_prod
92 self.UserError = "UserError"
94 def make_register(self):
96 Initialise les attributs jdc, id, niveau et réalise les enregistrements
100 self.jdc = self.parent.get_jdc_root()
101 self.id=self.parent.register(self)
103 self.UserError=self.jdc.UserError
105 self.jdc = self.parent =None
108 self.UserError="UserError"
110 def Build_sd(self,nom):
112 Construit le concept produit de l'opérateur. Deux cas
113 peuvent se présenter :
115 - le parent n'est pas défini. Dans ce cas, l'étape prend en charge
116 la création et le nommage du concept.
118 - le parent est défini. Dans ce cas, l'étape demande au parent la
119 création et le nommage du concept.
122 message.debug(SUPERV, "Build_sd %s", self.nom)
125 # On positionne la macro self en tant que current_step pour que les
126 # étapes créées lors de l'appel à sd_prod et à op_init aient la macro
128 self.set_current_step()
130 sd= self.parent.create_sdprod(self,nom)
131 if type(self.definition.op_init) == types.FunctionType:
132 apply(self.definition.op_init,(self,self.parent.g_context))
134 sd=self.get_sd_prod()
135 if sd != None and self.reuse == None:
136 # On ne nomme le concept que dans le cas de non reutilisation
139 self.reset_current_step()
140 except AsException,e:
141 self.reset_current_step()
142 raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
143 'fichier : ',self.appel[1],e)
144 except (EOFError, self.UserError):
145 # Le retablissement du step courant n'est pas strictement necessaire. On le fait pour des raisons de coherence
146 self.reset_current_step()
149 self.reset_current_step()
150 l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2])
151 raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
152 'fichier : ',self.appel[1]+'\n',
160 Marquage des concepts CO d'une macro-commande
162 # On marque les concepts CO pour verification ulterieure de leur bonne utilisation
165 #if not hasattr(c,"_etape") or c._etape is not c.etape:
169 def get_sd_prod(self):
171 Retourne le concept résultat d'une macro étape
172 La difference avec une etape ou une proc-etape tient a ce que
173 le concept produit peut exister ou pas
175 Si sd_prod == None le concept produit n existe pas on retourne None
178 - cas 1 : sd_prod n'est pas une fonction
179 il s'agit d'une sous classe de ASSD
180 on construit le sd à partir de cette classe
182 - cas 2 : sd_prod est une fonction
183 on l'évalue avec les mots-clés de l'étape (mc_liste)
184 on construit le sd à partir de la classe obtenue
187 sd_prod=self.definition.sd_prod
189 # On marque les concepts CO pour verification ulterieure de leur bonne utilisation
192 if type(self.definition.sd_prod) == types.FunctionType:
193 d=self.cree_dict_valeurs(self.mc_liste)
195 # la sd_prod d'une macro a l'objet macro_etape lui meme en premier argument
196 # Comme sd_prod peut invoquer la méthode type_sdprod qui ajoute
197 # les concepts produits dans self.sdprods, il faut le mettre à zéro avant de l'appeler
199 sd_prod= apply(sd_prod,(self,),d)
200 except (EOFError, self.UserError), exc:
203 if CONTEXT.debug: traceback.print_exc()
204 l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2])
205 raise AsException("impossible d affecter un type au resultat\n",string.join(l[2:]))
207 # on teste maintenant si la SD est réutilisée ou s'il faut la créer
208 if self.definition.reentrant != 'n' and self.reuse:
209 # Le concept produit est specifie reutilise (reuse=xxx). C'est une erreur mais non fatale.
210 # Elle sera traitee ulterieurement.
216 self.sd= sd_prod(etape=self)
218 # Si la commande est obligatoirement reentrante et reuse n'a pas ete specifie, c'est une erreur.
219 # On ne fait rien ici. L'erreur sera traitee par la suite.
221 if self.sd is not None and not isinstance(self.sd, ASSD):
222 raise AsException("""
223 Impossible de typer le résultat !
225 Utilisateur : Soit la valeur fournie derrière "reuse" est incorrecte,
226 soit il y a une "," à la fin d'une commande précédente.
227 Développeur : La fonction "sd_prod" retourne un type invalide.""")
230 def get_type_produit(self,force=0):
232 return self.get_type_produit_brut(force)
234 #traceback.print_exc()
237 def get_type_produit_brut(self,force=0):
239 Retourne le type du concept résultat de l'étape et eventuellement type
240 les concepts produits "à droite" du signe égal (en entrée)
243 - cas 1 : sd_prod de oper n'est pas une fonction
244 il s'agit d'une sous classe de ASSD
245 on retourne le nom de la classe
246 - cas 2 : il s'agit d'une fonction
247 on l'évalue avec les mots-clés de l'étape (mc_liste)
248 et on retourne son résultat
250 if not force and hasattr(self,'typret'): return self.typret
251 # On marque les concepts CO pour verification ulterieure de leur bonne utilisation
254 if type(self.definition.sd_prod) == types.FunctionType:
255 d=self.cree_dict_valeurs(self.mc_liste)
256 # Comme sd_prod peut invoquer la méthode type_sdprod qui ajoute
257 # les concepts produits dans self.sdprods, il faut le mettre à zéro
259 sd_prod= apply(self.definition.sd_prod,(self,),d)
261 sd_prod=self.definition.sd_prod
264 def get_contexte_avant(self,etape):
266 Retourne le dictionnaire des concepts connus avant etape
267 pour les commandes internes a la macro
268 On tient compte des commandes qui modifient le contexte
269 comme DETRUIRE ou les macros
271 # L'étape courante pour laquelle le contexte a été calculé est
272 # mémorisée dans self.index_etape_courante
273 # Si on insère des commandes (par ex, dans EFICAS), il faut
274 # préalablement remettre ce pointeur à 0
276 index_etape = self.index_etapes[etape]
278 index_etape=len(self.etapes)
280 if index_etape >= self.index_etape_courante:
281 # On calcule le contexte en partant du contexte existant
282 d=self.current_context
283 liste_etapes=self.etapes[self.index_etape_courante:index_etape]
285 d=self.current_context={}
286 liste_etapes=self.etapes
288 for e in liste_etapes:
293 self.index_etape_courante=index_etape
294 message.debug(SUPERV, "returns %s", d.keys())
299 Méthode qui supprime toutes les références arrières afin que
300 l'objet puisse etre correctement détruit par le garbage collector
302 N_MCCOMPO.MCCOMPO.supprime(self)
305 if self.sd : self.sd.supprime()
306 for concept in self.sdprods:
308 for etape in self.etapes:
311 def type_sdprod(self,co,t):
313 Cette methode a pour fonction de typer le concept co avec le type t
314 dans les conditions suivantes :
315 1. co est un concept produit de self
316 2. co est un concept libre : on le type et on l attribue à self
318 Elle enregistre egalement les concepts produits (on fait l hypothese
319 que la liste sdprods a été correctement initialisee, vide probablement)
321 if not hasattr(co,'etape'):
322 # Le concept vaut None probablement. On ignore l'appel
325 # On cherche a discriminer les differents cas de typage d'un concept
326 # produit par une macro qui est specifie dans un mot cle simple.
327 # On peut passer plusieurs fois par type_sdprod ce qui explique
328 # le nombre important de cas.
330 # Cas 1 : Le concept est libre. Il vient d'etre cree par CO(nom)
331 # Cas 2 : Le concept est produit par la macro. On est deja passe par type_sdprod.
332 # Cas semblable a Cas 1.
333 # Cas 3 : Le concept est produit par la macro englobante (parent). On transfere
334 # la propriete du concept de la macro parent a la macro courante (self)
335 # en verifiant que le type est valide
336 # Cas 4 : La concept est la propriete d'une etape fille. Ceci veut dire qu'on est
337 # deja passe par type_sdprod et que la propriete a ete transfere a une
338 # etape fille. Cas semblable a Cas 3.
339 # Cas 5 : Le concept est produit par une etape externe a la macro.
342 # Cas 1 : le concept est libre
343 # On l'attache a la macro et on change son type dans le type demande
344 # Recherche du mot cle simple associe au concept
345 mcs=self.get_mcs_with_co(co)
347 raise AsException("""Erreur interne.
348 Il ne devrait y avoir qu'un seul mot cle porteur du concept CO (%s)""" % co)
350 if not self.typeCO in mcs.definition.type:
351 raise AsException("""Erreur interne.
352 Impossible de changer le type du concept (%s). Le mot cle associe ne supporte pas CO mais seulement (%s)""" %(co,mcs.definition.type))
354 # affectation du bon type du concept et
356 self.sdprods.append(co)
358 elif co.etape == self:
359 # Cas 2 : le concept est produit par la macro (self)
360 # On est deja passe par type_sdprod (Cas 1 ou 3).
361 if co.etape == co._etape:
362 #Le concept a été créé par la macro (self)
363 #On peut changer son type
366 #Le concept a été créé par une macro parente
367 # Le type du concept doit etre coherent avec le type demande (seulement derive)
368 if not isinstance(co,t):
369 raise AsException("""Erreur interne.
370 Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co.__class__))
372 self.sdprods.append(co)
374 elif co.etape== self.parent:
375 # Cas 3 : le concept est produit par la macro parente (self.parent)
376 # on transfere la propriete du concept a la macro fille
377 # et on change le type du concept comme demande
378 # Au prealable, on verifie que le concept existant (co) est une instance
379 # possible du type demande (t)
380 # Cette règle est normalement cohérente avec les règles de vérification des mots-clés
381 if not isinstance(co,t):
382 raise AsException("""
383 Impossible de changer le type du concept produit (%s) en (%s).
384 Le type actuel (%s) devrait etre une classe derivee du nouveau type (%s)""" % (co,t,co.__class__,t))
385 mcs=self.get_mcs_with_co(co)
387 raise AsException("""Erreur interne.
388 Il ne devrait y avoir qu'un seul mot cle porteur du concept CO (%s)""" % co)
390 if not self.typeCO in mcs.definition.type:
391 raise AsException("""Erreur interne.
392 Impossible de changer le type du concept (%s). Le mot cle associe ne supporte pas CO mais seulement (%s)""" %(co,mcs.definition.type))
394 # On ne change pas le type car il respecte la condition isinstance(co,t)
396 self.sdprods.append(co)
398 elif self.issubstep(co.etape):
399 # Cas 4 : Le concept est propriété d'une sous etape de la macro (self).
400 # On est deja passe par type_sdprod (Cas 3 ou 1).
401 # Il suffit de le mettre dans la liste des concepts produits (self.sdprods)
402 # Le type du concept et t doivent etre derives.
403 # Il n'y a aucune raison pour que la condition ne soit pas verifiee.
404 if not isinstance(co,t):
405 raise AsException("""Erreur interne.
406 Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co.__class__))
407 self.sdprods.append(co)
410 # Cas 5 : le concept est produit par une autre étape
414 def issubstep(self,etape):
416 Cette methode retourne un entier indiquant si etape est une
417 sous etape de la macro self ou non
421 if etape in self.etapes:return 1
422 for etap in self.etapes:
423 if etap.issubstep(etape):return 1
426 def register(self,etape):
428 Enregistrement de etape dans le contexte de la macro : liste etapes
429 et demande d enregistrement global aupres du JDC
431 self.etapes.append(etape)
432 self.index_etapes[etape] = len(self.etapes) - 1
433 idetape=self.jdc.g_register(etape)
438 Methode appelee dans l __init__ d un ASSD a sa creation pour
439 s enregistrer (reserve aux ASSD créés au sein d'une MACRO)
442 return self.jdc.o_register(sd)
444 def create_sdprod(self,etape,nomsd):
446 Cette methode doit fabriquer le concept produit retourne
447 par l'etape etape et le nommer.
449 Elle est appelée à l'initiative de l'etape
450 pendant le processus de construction de cette etape : methode __call__
451 de la classe CMD (OPER ou MACRO)
452 Ce travail est réalisé par le contexte supérieur (etape.parent)
453 car dans certains cas, le concept ne doit pas etre fabriqué mais
454 l'etape doit simplement utiliser un concept préexistant.
455 - Cas 1 : etape.reuse != None : le concept est réutilisé
456 - Cas 2 : l'étape appartient à une macro qui a déclaré un concept
457 de sortie qui doit etre produit par cette etape.
459 if self.Outputs.has_key(nomsd):
460 # Il s'agit d'un concept de sortie de la macro. Il ne faut pas le créer
461 # Il faut quand meme appeler la fonction sd_prod si elle existe.
462 # get_type_produit le fait et donne le type attendu par la commande pour verification ultérieure.
463 sdprod=etape.get_type_produit_brut()
464 sd=self.Outputs[nomsd]
465 # On verifie que le type du concept existant sd.__class__ est un sur type de celui attendu
466 # Cette règle est normalement cohérente avec les règles de vérification des mots-clés
467 if not issubclass(sdprod,sd.__class__):
468 raise AsException("Le type du concept produit %s devrait etre une sur classe de %s" %(sd.__class__,sdprod))
469 # La propriete du concept est transferee a l'etape avec le type attendu par l'étape
472 if self.reuse == sd and etape.reuse != sd \
473 and getattr(sd, "executed", 0) == 1: # n'a pas été pas détruit
474 raise AsException("Le concept '%s' est réentrant dans la macro-commande %s. " \
475 "Il devrait donc l'être dans %s (produit sous le nom '%s')." \
476 % (sd.nom, self.nom, etape.nom, nomsd))
477 # On donne au concept le type produit par la sous commande.
478 # Le principe est le suivant : apres avoir verifie que le type deduit par la sous commande
479 # est bien coherent avec celui initialement affecte par la macro (voir ci dessus)
480 # on affecte au concept ce type car il peut etre plus precis (derive, en general)
482 # On force également le nom stocké dans l'attribut sdnom : on lui donne le nom
483 # du concept associé à nomsd
485 elif etape.definition.reentrant != 'n' and etape.reuse != None:
486 # On est dans le cas d'une commande avec reutilisation d'un concept existant
487 # get_sd_prod fait le necessaire : verifications, associations, etc. mais ne cree
488 # pas un nouveau concept. Il retourne le concept reutilise
489 sd= etape.get_sd_prod()
490 # Dans le cas d'un concept nomme automatiquement : _xxx, __xxx,
491 # On force le nom stocke dans l'attribut sdnom de l'objet etape : on lui donne le nom
492 # du concept reutilise (sd ou etape.reuse c'est pareil)
493 # Ceci est indispensable pour eviter des erreurs lors des verifications des macros
494 # En effet une commande avec reutilisation d'un concept verifie que le nom de
495 # la variable a gauche du signe = est le meme que celui du concept reutilise.
496 # Lorsqu'une telle commande apparait dans une macro, on supprime cette verification.
497 if (etape.sdnom == '' or etape.sdnom[0] == '_'):
500 # On est dans le cas de la creation d'un nouveau concept
501 sd= etape.get_sd_prod()
503 self.NommerSdprod(sd,nomsd)
506 def NommerSdprod(self,sd,sdnom,restrict='non'):
508 Cette methode est appelee par les etapes internes de la macro
509 La macro appelle le JDC pour valider le nommage
510 On considere que l espace de nom est unique et géré par le JDC
511 Si le nom est deja utilise, l appel leve une exception
512 Si restrict=='non', on insere le concept dans le contexte de la macro
513 Si restrict=='oui', on n'insere pas le concept dans le contexte de la macro
515 # Normalement, lorsqu'on appelle cette methode, on ne veut nommer que des concepts nouvellement crees.
516 # Le filtrage sur les concepts a creer ou a ne pas creer est fait dans la methode
517 # create_sdprod. La seule chose a verifier apres conversion eventuelle du nom
518 # est de verifier que le nom n'est pas deja attribue. Ceci est fait en delegant
519 # au JDC par l'intermediaire du parent.
521 #XXX attention inconsistence : gcncon n'est pas
522 # défini dans le package Noyau. La methode NommerSdprod pour
523 # les macros devrait peut etre etre déplacée dans Build ???
524 if self.Outputs.has_key(sdnom):
525 # Il s'agit d'un concept de sortie de la macro produit par une sous commande
526 sdnom=self.Outputs[sdnom].nom
527 elif sdnom != '' and sdnom[0] == '_':
528 # Si le nom du concept commence par le caractere _ on lui attribue
529 # un identificateur JEVEUX construit par gcncon et respectant
530 # la regle gcncon legerement adaptee ici
531 # nom commencant par __ : il s'agit de concepts qui seront detruits
532 # nom commencant par _ : il s'agit de concepts intermediaires qui seront gardes
533 # ATTENTION : il faut traiter différemment les concepts dont le nom
534 # commence par _ mais qui sont des concepts nommés automatiquement par
535 # une éventuelle sous macro.
536 # Le test suivant n'est pas tres rigoureux mais permet de fonctionner pour le moment (a améliorer)
537 if sdnom[1] in string.digits:
538 # Ce concept provient probablement d'une macro appelee par self
540 elif sdnom[1] == '_':
541 sdnom=self.gcncon('.')
543 sdnom=self.gcncon('_')
545 # On est dans le cas d'un nom de concept global.
548 if restrict == 'non':
549 # On demande le nommage au parent mais sans ajout du concept dans le contexte du parent
550 # car on va l'ajouter dans le contexte de la macro
551 self.parent.NommerSdprod(sd,sdnom,restrict='oui')
552 # On ajoute dans le contexte de la macro les concepts nommes
553 # Ceci est indispensable pour les CO (macro) dans un INCLUDE
554 self.g_context[sdnom]=sd
555 message.debug(SUPERV, "g_context[%s] = %s", sdnom, sd)
557 # La demande de nommage vient probablement d'une macro qui a mis
558 # le concept dans son contexte. On ne traite plus que le nommage (restrict="oui")
559 self.parent.NommerSdprod(sd,sdnom,restrict='oui')
561 def delete_concept_after_etape(self,etape,sd):
563 Met à jour les étapes de la MACRO qui sont après etape suite à
564 la disparition du concept sd
566 # Cette methode est définie dans le noyau mais ne sert que pendant la phase de creation
567 # des etapes et des concepts. Il n'y a aucun traitement particulier à réaliser
568 # Dans d'autres conditions, il faudrait surcharger cette méthode.
571 def accept(self,visitor):
573 Cette methode permet de parcourir l'arborescence des objets
574 en utilisant le pattern VISITEUR
576 visitor.visitMACRO_ETAPE(self)
578 def update_context(self,d):
580 Met à jour le contexte contenu dans le dictionnaire d
581 Une MACRO_ETAPE peut ajouter plusieurs concepts dans le contexte
582 Une fonction enregistree dans op_init peut egalement modifier le contexte
584 if type(self.definition.op_init) == types.FunctionType:
585 apply(self.definition.op_init,(self,d))
586 if self.sd != None:d[self.sd.nom]=self.sd
587 for co in self.sdprods:
590 def make_include(self,unite=None):
592 Inclut un fichier dont l'unite logique est unite
594 if not unite : return
595 f,text=self.get_file(unite=unite,fic_origine=self.parent.nom)
596 self.fichier_init = f
598 self.make_contexte(f,text)
600 def make_poursuite(self):
602 Inclut un fichier poursuite
605 f,text=self.get_file(fic_origine=self.parent.nom)
607 raise AsException("Impossible d'ouvrir la base pour une poursuite")
610 self.make_contexte(f,text)
612 def make_contexte(self,f,text):
614 Interprete le texte fourni (text) issu du fichier f
615 dans le contexte du parent.
616 Cette methode est utile pour le fonctionnement des
619 # on execute le texte fourni dans le contexte forme par
620 # le contexte de l etape pere (global au sens Python)
621 # et le contexte de l etape (local au sens Python)
622 code = compile(text,f,'exec')
623 d = self.macro_const_context
625 self.contexte_fichier_init = d
626 globs = self.get_global_contexte()
627 exec code in globs, d
628 # pour ne pas conserver des références sur tout
629 self.macro_const_context = {}
631 def get_global_contexte(self):
633 Cette methode retourne le contexte global fourni
634 par le parent(self) a une etape fille (l'appelant) pour
635 realiser des evaluations de texte Python (INCLUDE,...)
637 # Le contexte global est forme par concatenation du contexte
638 # du parent de self et de celui de l'etape elle meme (self)
639 d=self.parent.get_global_contexte()
640 d.update(self.g_context)
641 # en PAR_LOT='OUI', les concepts n'étant pas dans jdc.g_context,
642 # on demande au parent le contexte courant.
643 d.update(self.parent.get_contexte_avant(self))
646 def get_contexte_courant(self, etape_fille_du_jdc=None):
648 Retourne le contexte tel qu'il est au moment de l'exécution de
652 # update car par ricochet on modifierait jdc.current_context
653 ctx.update( self.parent.get_contexte_courant(self) )
654 # on peut mettre None car toujours en PAR_LOT='NON', donc la dernière
655 ctx.update( self.get_contexte_avant(None) )
658 def get_concept(self, nomsd):
660 Méthode pour recuperer un concept à partir de son nom
661 dans le contexte du jdc connu avant l'exécution de la macro courante.
663 # chercher dans self.get_contexte_avant, puis si non trouve
664 # self.parent.get_concept est peut-etre plus performant
665 return self.get_contexte_courant().get(nomsd.strip(), None)
668 """ Méthode qui retourne une copie de self non enregistrée auprès du JDC
670 On surcharge la methode de ETAPE pour exprimer que les concepts crees
671 par la MACRO d'origine ne sont pas crees par la copie mais eventuellement
674 etape=N_ETAPE.ETAPE.copy(self)
678 def copy_intern(self,etape):
679 """ Cette méthode effectue la recopie des etapes internes d'une macro
680 passée en argument (etape)
684 for etp in etape.etapes:
686 new_etp.copy_reuse(etp)
687 new_etp.copy_sdnom(etp)
688 new_etp.reparent(self)
690 new_sd = etp.sd.__class__(etape=new_etp)
693 new_sd.set_name(etp.sd.nom)
695 self.NommerSdprod(new_sd,etp.sd.nom)
696 new_etp.copy_intern(etp)
697 self.etapes.append(new_etp)
698 self.index_etapes[new_etp] = len(self.etapes) - 1
701 def reset_jdc(self,new_jdc):
703 Reinitialise l'etape avec un nouveau jdc parent new_jdc
705 if self.sd and self.reuse == None :
706 self.parent.NommerSdprod(self.sd,self.sd.nom)
707 for concept in self.sdprods:
708 self.parent.NommerSdprod(concept,concept.nom)
710 def reparent(self,parent):
712 Cette methode sert a reinitialiser la parente de l'objet
714 N_ETAPE.ETAPE.reparent(self,parent)
715 #on ne change pas la parenté des concepts. On s'assure uniquement que le jdc en référence est le bon
716 for concept in self.sdprods:
718 for e in self.etapes:
721 def update_const_context(self, d):
723 Met à jour le contexte des constantes pour l'évaluation de
724 formules dans la macro.
726 # Dans le jdc, const_context est mis à jour par exec_compile
727 # Dans la macro, on n'a pas le code à compiler pour récupèrer les
728 # constantes locales à la macro. On demande donc explicitement de
729 # définir les constantes "locales".
730 self.macro_const_context.update(d)
732 def sd_accessible(self):
733 """On peut acceder aux "valeurs" (jeveux) des ASSD dans
734 les macro-commandes qui sont localement en PAR_LOT="NON"
737 if CONTEXT.debug: print ' `- MACRO sd_accessible :', self.nom
738 return self.parent.sd_accessible() or not self.is_include()