1 #@ MODIF N_MACRO_ETAPE Noyau DATE 23/03/2010 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 - 2002 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
43 class MACRO_ETAPE(N_ETAPE.ETAPE):
49 def __init__(self,oper=None,reuse=None,args={}):
53 - definition : objet portant les attributs de définition d'une étape
54 de type macro-commande. Il est initialisé par
57 - reuse : indique le concept d'entrée réutilisé. Il se trouvera donc
58 en sortie si les conditions d'exécution de l'opérateur
61 - valeur : arguments d'entrée de type mot-clé=valeur. Initialisé
65 self.definition = oper
69 self.parent = CONTEXT.get_current_step()
72 self.idracine = oper.label
73 self.appel = N_utils.callee_where()
77 self.current_context = {}
78 self.macro_const_context = {}
79 self.index_etape_courante = 0
81 self.index_etapes = {}
83 # Dans le cas d'une macro écrite en Python, l'attribut Outputs est un
84 # dictionnaire qui contient les concepts produits de sortie
85 # (nom : ASSD) déclarés dans la fonction sd_prod
91 self.UserError = "UserError"
93 def make_register(self):
95 Initialise les attributs jdc, id, niveau et réalise les enregistrements
99 self.jdc = self.parent.get_jdc_root()
100 self.id=self.parent.register(self)
102 self.UserError=self.jdc.UserError
104 self.jdc = self.parent =None
107 self.UserError="UserError"
109 def Build_sd(self,nom):
111 Construit le concept produit de l'opérateur. Deux cas
112 peuvent se présenter :
114 - le parent n'est pas défini. Dans ce cas, l'étape prend en charge
115 la création et le nommage du concept.
117 - le parent est défini. Dans ce cas, l'étape demande au parent la
118 création et le nommage du concept.
123 # On positionne la macro self en tant que current_step pour que les
124 # étapes créées lors de l'appel à sd_prod et à op_init aient la macro
126 self.set_current_step()
128 sd= self.parent.create_sdprod(self,nom)
129 if type(self.definition.op_init) == types.FunctionType:
130 apply(self.definition.op_init,(self,self.parent.g_context))
132 sd=self.get_sd_prod()
133 if sd != None and self.reuse == None:
134 # On ne nomme le concept que dans le cas de non reutilisation
137 self.reset_current_step()
138 except AsException,e:
139 self.reset_current_step()
140 raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
141 'fichier : ',self.appel[1],e)
142 except (EOFError,self.UserError):
143 # Le retablissement du step courant n'est pas strictement necessaire. On le fait pour des raisons de coherence
144 self.reset_current_step()
147 self.reset_current_step()
148 l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2])
149 raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
150 'fichier : ',self.appel[1]+'\n',
158 Marquage des concepts CO d'une macro-commande
160 # On marque les concepts CO pour verification ulterieure de leur bonne utilisation
163 #if not hasattr(c,"_etape") or c._etape is not c.etape:
167 def get_sd_prod(self):
169 Retourne le concept résultat d'une macro étape
170 La difference avec une etape ou une proc-etape tient a ce que
171 le concept produit peut exister ou pas
173 Si sd_prod == None le concept produit n existe pas on retourne None
176 - cas 1 : sd_prod n'est pas une fonction
177 il s'agit d'une sous classe de ASSD
178 on construit le sd à partir de cette classe
180 - cas 2 : sd_prod est une fonction
181 on l'évalue avec les mots-clés de l'étape (mc_liste)
182 on construit le sd à partir de la classe obtenue
185 sd_prod=self.definition.sd_prod
187 # On marque les concepts CO pour verification ulterieure de leur bonne utilisation
190 if type(self.definition.sd_prod) == types.FunctionType:
191 d=self.cree_dict_valeurs(self.mc_liste)
193 # la sd_prod d'une macro a l'objet macro_etape lui meme en premier argument
194 # Comme sd_prod peut invoquer la méthode type_sdprod qui ajoute
195 # les concepts produits dans self.sdprods, il faut le mettre à zéro avant de l'appeler
197 sd_prod= apply(sd_prod,(self,),d)
198 except (EOFError,self.UserError):
201 if CONTEXT.debug: traceback.print_exc()
202 l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2])
203 raise AsException("impossible d affecter un type au resultat\n",string.join(l[2:]))
205 # on teste maintenant si la SD est réutilisée ou s'il faut la créer
206 if self.definition.reentrant != 'n' and self.reuse:
207 # Le concept produit est specifie reutilise (reuse=xxx). C'est une erreur mais non fatale.
208 # Elle sera traitee ulterieurement.
214 self.sd= sd_prod(etape=self)
216 # Si la commande est obligatoirement reentrante et reuse n'a pas ete specifie, c'est une erreur.
217 # On ne fait rien ici. L'erreur sera traitee par la suite.
219 if self.sd is not None and not isinstance(self.sd, ASSD):
220 raise AsException("""
221 Impossible de typer le résultat !
223 Utilisateur : Soit la valeur fournie derrière "reuse" est incorrecte,
224 soit il y a une "," à la fin d'une commande précédente.
225 Développeur : La fonction "sd_prod" retourne un type invalide.""")
228 def get_type_produit(self,force=0):
230 return self.get_type_produit_brut(force)
232 #traceback.print_exc()
235 def get_type_produit_brut(self,force=0):
237 Retourne le type du concept résultat de l'étape et eventuellement type
238 les concepts produits "à droite" du signe égal (en entrée)
241 - cas 1 : sd_prod de oper n'est pas une fonction
242 il s'agit d'une sous classe de ASSD
243 on retourne le nom de la classe
244 - cas 2 : il s'agit d'une fonction
245 on l'évalue avec les mots-clés de l'étape (mc_liste)
246 et on retourne son résultat
248 if not force and hasattr(self,'typret'): return self.typret
249 # On marque les concepts CO pour verification ulterieure de leur bonne utilisation
252 if type(self.definition.sd_prod) == types.FunctionType:
253 d=self.cree_dict_valeurs(self.mc_liste)
254 # Comme sd_prod peut invoquer la méthode type_sdprod qui ajoute
255 # les concepts produits dans self.sdprods, il faut le mettre à zéro
257 sd_prod= apply(self.definition.sd_prod,(self,),d)
259 sd_prod=self.definition.sd_prod
262 def get_contexte_avant(self,etape):
264 Retourne le dictionnaire des concepts connus avant etape
265 pour les commandes internes a la macro
266 On tient compte des commandes qui modifient le contexte
267 comme DETRUIRE ou les macros
269 # L'étape courante pour laquelle le contexte a été calculé est
270 # mémorisée dans self.index_etape_courante
271 # Si on insère des commandes (par ex, dans EFICAS), il faut
272 # préalablement remettre ce pointeur à 0
274 index_etape = self.index_etapes[etape]
276 index_etape=len(self.etapes)
278 if index_etape >= self.index_etape_courante:
279 # On calcule le contexte en partant du contexte existant
280 d=self.current_context
281 liste_etapes=self.etapes[self.index_etape_courante:index_etape]
283 d=self.current_context={}
284 liste_etapes=self.etapes
286 for e in liste_etapes:
291 self.index_etape_courante=index_etape
296 Méthode qui supprime toutes les références arrières afin que
297 l'objet puisse etre correctement détruit par le garbage collector
299 N_MCCOMPO.MCCOMPO.supprime(self)
302 if self.sd : self.sd.supprime()
303 for concept in self.sdprods:
305 for etape in self.etapes:
308 def type_sdprod(self,co,t):
310 Cette methode a pour fonction de typer le concept co avec le type t
311 dans les conditions suivantes :
312 1. co est un concept produit de self
313 2. co est un concept libre : on le type et on l attribue à self
315 Elle enregistre egalement les concepts produits (on fait l hypothese
316 que la liste sdprods a été correctement initialisee, vide probablement)
318 if not hasattr(co,'etape'):
319 # Le concept vaut None probablement. On ignore l'appel
322 # On cherche a discriminer les differents cas de typage d'un concept
323 # produit par une macro qui est specifie dans un mot cle simple.
324 # On peut passer plusieurs fois par type_sdprod ce qui explique
325 # le nombre important de cas.
327 # Cas 1 : Le concept est libre. Il vient d'etre cree par CO(nom)
328 # Cas 2 : Le concept est produit par la macro. On est deja passe par type_sdprod.
329 # Cas semblable a Cas 1.
330 # Cas 3 : Le concept est produit par la macro englobante (parent). On transfere
331 # la propriete du concept de la macro parent a la macro courante (self)
332 # en verifiant que le type est valide
333 # Cas 4 : La concept est la propriete d'une etape fille. Ceci veut dire qu'on est
334 # deja passe par type_sdprod et que la propriete a ete transfere a une
335 # etape fille. Cas semblable a Cas 3.
336 # Cas 5 : Le concept est produit par une etape externe a la macro.
339 # Cas 1 : le concept est libre
340 # On l'attache a la macro et on change son type dans le type demande
341 # Recherche du mot cle simple associe au concept
342 mcs=self.get_mcs_with_co(co)
344 raise AsException("""Erreur interne.
345 Il ne devrait y avoir qu'un seul mot cle porteur du concept CO (%s)""" % co)
347 if not self.typeCO in mcs.definition.type:
348 raise AsException("""Erreur interne.
349 Impossible de changer le type du concept (%s). Le mot cle associe ne supporte pas CO mais seulement (%s)""" %(co,mcs.definition.type))
351 # affectation du bon type du concept et
352 # initialisation de sa partie "sd"
353 if CONTEXT.debug:print "changement de type:",co,t
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 : prefix et gcncon ne sont pas
522 # définis dans le package Noyau. La methode NommerSdprod pour
523 # les macros devrait peut etre etre déplacée dans Build ???
525 if CONTEXT.debug : print "MACRO.NommerSdprod: ",sd,sdnom
527 if hasattr(self,'prefix'):
528 # Dans le cas de l'include_materiau on ajoute un prefixe au nom du concept
529 if sdnom != self.prefix:sdnom=self.prefix+sdnom
531 if self.Outputs.has_key(sdnom):
532 # Il s'agit d'un concept de sortie de la macro produit par une sous commande
533 sdnom=self.Outputs[sdnom].nom
534 elif sdnom != '' and sdnom[0] == '_':
535 # Si le nom du concept commence par le caractere _ on lui attribue
536 # un identificateur JEVEUX construit par gcncon et respectant
537 # la regle gcncon legerement adaptee ici
538 # nom commencant par __ : il s'agit de concepts qui seront detruits
539 # nom commencant par _ : il s'agit de concepts intermediaires qui seront gardes
540 # ATTENTION : il faut traiter différemment les concepts dont le nom
541 # commence par _ mais qui sont des concepts nommés automatiquement par
542 # une éventuelle sous macro.
543 # Le test suivant n'est pas tres rigoureux mais permet de fonctionner pour le moment (a améliorer)
544 if sdnom[1] in string.digits:
545 # Ce concept provient probablement d'une macro appelee par self
547 elif sdnom[1] == '_':
548 sdnom=self.gcncon('.')
550 sdnom=self.gcncon('_')
552 # On est dans le cas d'un nom de concept global.
555 if restrict == 'non':
556 # On demande le nommage au parent mais sans ajout du concept dans le contexte du parent
557 # car on va l'ajouter dans le contexte de la macro
558 self.parent.NommerSdprod(sd,sdnom,restrict='oui')
559 # On ajoute dans le contexte de la macro les concepts nommes
560 # Ceci est indispensable pour les CO (macro) dans un INCLUDE
561 self.g_context[sdnom]=sd
563 # La demande de nommage vient probablement d'une macro qui a mis
564 # le concept dans son contexte. On ne traite plus que le nommage (restrict="oui")
565 self.parent.NommerSdprod(sd,sdnom,restrict='oui')
567 def delete_concept_after_etape(self,etape,sd):
569 Met à jour les étapes de la MACRO qui sont après etape suite à
570 la disparition du concept sd
572 # Cette methode est définie dans le noyau mais ne sert que pendant la phase de creation
573 # des etapes et des concepts. Il n'y a aucun traitement particulier à réaliser
574 # Dans d'autres conditions, il faudrait surcharger cette méthode.
577 def accept(self,visitor):
579 Cette methode permet de parcourir l'arborescence des objets
580 en utilisant le pattern VISITEUR
582 visitor.visitMACRO_ETAPE(self)
584 def update_context(self,d):
586 Met à jour le contexte contenu dans le dictionnaire d
587 Une MACRO_ETAPE peut ajouter plusieurs concepts dans le contexte
588 Une fonction enregistree dans op_init peut egalement modifier le contexte
590 if type(self.definition.op_init) == types.FunctionType:
591 apply(self.definition.op_init,(self,d))
592 if self.sd != None:d[self.sd.nom]=self.sd
593 for co in self.sdprods:
596 def make_include(self,unite=None):
598 Inclut un fichier dont l'unite logique est unite
600 if not unite : return
601 f,text=self.get_file(unite=unite,fic_origine=self.parent.nom)
602 self.fichier_init = f
604 self.make_contexte(f,text)
606 def make_poursuite(self):
608 Inclut un fichier poursuite
611 f,text=self.get_file(fic_origine=self.parent.nom)
613 raise AsException("Impossible d'ouvrir la base pour une poursuite")
616 self.make_contexte(f,text)
618 def make_contexte(self,f,text):
620 Interprete le texte fourni (text) issu du fichier f
621 dans le contexte du parent.
622 Cette methode est utile pour le fonctionnement des
625 # on execute le texte fourni dans le contexte forme par
626 # le contexte de l etape pere (global au sens Python)
627 # et le contexte de l etape (local au sens Python)
628 code=compile(text,f,'exec')
631 self.contexte_fichier_init = d
632 globs=self.parent.get_global_contexte()
635 def get_global_contexte(self):
637 Cette methode retourne le contexte global fourni
638 par le parent(self) a une etape fille (l'appelant) pour
639 realiser des evaluations de texte Python (INCLUDE,...)
641 # Le contexte global est forme par concatenation du contexte
642 # du parent de self et de celui de l'etape elle meme (self)
643 d=self.parent.get_global_contexte()
644 d.update(self.g_context)
647 def get_contexte_courant(self, etape_fille_du_jdc=None):
649 Retourne le contexte tel qu'il est au moment de l'exécution de
652 ctx = self.parent.get_contexte_courant(self)
653 # on peut mettre None car toujours en PAR_LOT='NON', donc la dernière
654 ctx.update( self.get_contexte_avant(None) )
657 def get_concept(self, nomsd):
659 Méthode pour recuperer un concept à partir de son nom
660 dans le contexte du jdc connu avant l'exécution de la macro courante.
662 # chercher dans self.get_contexte_avant, puis si non trouve
663 # self.parent.get_concept est peut-etre plus performant
664 return self.get_contexte_courant().get(nomsd.strip(), None)
667 """ Méthode qui retourne une copie de self non enregistrée auprès du JDC
669 On surcharge la methode de ETAPE pour exprimer que les concepts crees
670 par la MACRO d'origine ne sont pas crees par la copie mais eventuellement
673 etape=N_ETAPE.ETAPE.copy(self)
677 def copy_intern(self,etape):
678 """ Cette méthode effectue la recopie des etapes internes d'une macro
679 passée en argument (etape)
683 for etp in etape.etapes:
685 new_etp.copy_reuse(etp)
686 new_etp.copy_sdnom(etp)
687 new_etp.reparent(self)
689 new_sd = etp.sd.__class__(etape=new_etp)
692 new_sd.set_name(etp.sd.nom)
694 self.NommerSdprod(new_sd,etp.sd.nom)
695 new_etp.copy_intern(etp)
696 self.etapes.append(new_etp)
697 self.index_etapes[new_etp] = len(self.etapes) - 1
700 def reset_jdc(self,new_jdc):
702 Reinitialise l'etape avec un nouveau jdc parent new_jdc
704 if self.sd and self.reuse == None :
705 self.parent.NommerSdprod(self.sd,self.sd.nom)
706 for concept in self.sdprods:
707 self.parent.NommerSdprod(concept,concept.nom)
709 def reparent(self,parent):
711 Cette methode sert a reinitialiser la parente de l'objet
713 N_ETAPE.ETAPE.reparent(self,parent)
714 #on ne change pas la parenté des concepts. On s'assure uniquement que le jdc en référence est le bon
715 for concept in self.sdprods:
717 for e in self.etapes:
720 def update_const_context(self, d):
722 Met à jour le contexte des constantes pour l'évaluation de
723 formules dans la macro.
725 # Dans le jdc, const_context est mis à jour par exec_compile
726 # Dans la macro, on n'a pas le code à compiler pour récupèrer les
727 # constantes locales à la macro. On demande donc explicitement de
728 # définir les constantes "locales".
729 self.macro_const_context.update(d)
731 def sd_accessible(self):
732 """On peut acceder aux "valeurs" (jeveux) des ASSD dans
733 les macro-commandes qui sont localement en PAR_LOT="NON"
734 sauf pour INCLUDE et INCLUDE_MATERIAU.
736 if CONTEXT.debug: print ' `- MACRO sd_accessible :', self.nom
737 return self.parent.sd_accessible() or not self.nom.startswith('INCLUDE')