From 39964aa219dc9723cb71d0b163ed3b1116573510 Mon Sep 17 00:00:00 2001 From: Pascale Noyret Date: Mon, 7 Nov 2011 10:41:45 +0000 Subject: [PATCH] NEW 11 --- Noyau/N_ASSD.py | 135 +++++++++++++-------- Noyau/N_BLOC.py | 72 +++++++---- Noyau/N_CR.py | 10 -- Noyau/N_ENTITE.py | 98 +++++++++------ Noyau/N_ETAPE.py | 157 ++++++++++++------------ Noyau/N_FONCTION.py | 181 +++++++++++++-------------- Noyau/N_JDC.py | 114 ++++++++--------- Noyau/N_MACRO.py | 43 +++---- Noyau/N_MACRO_ETAPE.py | 150 +++++++++++------------ Noyau/N_MCCOMPO.py | 111 ++++++++++------- Noyau/N_MCSIMP.py | 95 ++++++++------- Noyau/N_OPER.py | 39 +++--- Noyau/N_OPS.py | 45 +++++++ Noyau/N_PROC.py | 35 +++--- Noyau/N_SIMP.py | 20 +-- Noyau/N__F.py | 35 +++--- Noyau/N_info.py | 269 +++++++++++++++++++++++++++++++++++++++++ Noyau/N_types.py | 5 +- Noyau/N_utils.py | 86 +++++++++---- Noyau/asojb.py | 6 +- Noyau/basetype.py | 63 +++++----- Noyau/context.py | 35 +++--- 22 files changed, 1124 insertions(+), 680 deletions(-) create mode 100644 Noyau/N_OPS.py create mode 100644 Noyau/N_info.py diff --git a/Noyau/N_ASSD.py b/Noyau/N_ASSD.py index ecbc64f0..780d5ad2 100644 --- a/Noyau/N_ASSD.py +++ b/Noyau/N_ASSD.py @@ -1,31 +1,31 @@ -#@ MODIF N_ASSD Noyau DATE 09/11/2010 AUTEUR COURTOIS M.COURTOIS +#@ MODIF N_ASSD Noyau DATE 30/08/2011 AUTEUR COURTOIS M.COURTOIS # -*- coding: iso-8859-1 -*- # RESPONSABLE COURTOIS M.COURTOIS # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== -# COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG +# COPYRIGHT (C) 1991 - 2011 EDF R&D WWW.CODE-ASTER.ORG # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY -# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR -# (AT YOUR OPTION) ANY LATER VERSION. +# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR +# (AT YOUR OPTION) ANY LATER VERSION. # -# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT -# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF -# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU -# GENERAL PUBLIC LICENSE FOR MORE DETAILS. +# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT +# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF +# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU +# GENERAL PUBLIC LICENSE FOR MORE DETAILS. # -# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE -# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, -# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. -# -# +# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE +# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, +# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. # ====================================================================== - """ """ +from N_utils import import_object +from N_info import message, SUPERV + class ASSD(object): """ Classe de base pour definir des types de structures de donnees ASTER @@ -33,26 +33,26 @@ class ASSD(object): """ idracine="SD" - def __init__(self,etape=None,sd=None,reg='oui'): + def __init__(self, etape=None, sd=None, reg='oui'): """ reg est un paramètre qui vaut oui ou non : - si oui (défaut) : on enregistre la SD auprès du JDC - si non : on ne l'enregistre pas """ - self.etape=etape - self.sd=sd - self.nom=None + self.etape = etape + self.sd = sd + self.nom = None if etape: - self.parent=etape.parent + self.parent = etape.parent else: - self.parent=CONTEXT.get_current_step() + self.parent = CONTEXT.get_current_step() if self.parent : self.jdc = self.parent.get_jdc_root() else: self.jdc = None if not self.parent: - self.id=None + self.id = None elif reg == 'oui' : self.id = self.parent.reg_sd(self) else : @@ -61,20 +61,48 @@ class ASSD(object): self.executed = 0 # permet de savoir si le catalogue de SD a déjà été supprimé (1) ou non (0) self.sd_deleted = 0 - + # attributs pour le Catalogue de Structure de Données Jeveux + # "self.cata_sdj" est un attribut de classe + #XXX si on nomme ces attributs _sdj/_class_sdj, pb en poursuite : + #XXX dans rebuild_sd, self n'a pas ces attributs qui ne sont donc + #XXX pas recopiés... !? + self.ptr_class_sdj = None + self.ptr_sdj = None + + def _get_sdj(self): + """Retourne le catalogue de SD associé au concept.""" + if self.ptr_sdj is None: + cata_sdj = getattr(self, 'cata_sdj', None) + assert cata_sdj, "L'attribut 'cata_sdj' doit être défini pour la classe %s" \ + % self.__class__.__name__ + assert self.nom, "L'attribut 'nom' n'a pas été renseigné !" + if self.ptr_class_sdj is None: + self.ptr_class_sdj = import_object(cata_sdj) + self.ptr_sdj = self.ptr_class_sdj(nomj=self.nom) + return self.ptr_sdj + + def _del_sdj(self): + """Suppression du catalogue de SD.""" + if self.ptr_sdj is not None: + self.ptr_sdj.supprime(True) + self.ptr_sdj = None + self.ptr_class_sdj = None + + sdj = property(_get_sdj, None, _del_sdj) + + def __getitem__(self,key): return self.etape[key] - + def set_name(self, nom): """Positionne le nom de self (et appelle sd_init) """ self.nom = nom - # initialise la partie "sd" (pas pour entier, reel, formule) - sup = super(ASSD, self) - if hasattr(sup, 'nomj'): # == AsBase - sup.__init__(nomj=nom) - self.reparent_sd() - + + def change_type(self, new_type): + """Type connu a posteriori (type CO).""" + self.__class__ = new_type + def reparent_sd(self): """Repositionne le parent des attributs de la SD associée. """ @@ -94,42 +122,36 @@ class ASSD(object): if hasattr(self, nam) and getattr(self, nam) is None: setattr(self, nam, getattr(new, nam)) self.reparent_sd() - def get_name(self): """ Retourne le nom de self, éventuellement en le demandant au JDC """ if not self.nom : try: - self.nom=self.parent.get_name(self) or self.id + self.nom = self.parent.get_name(self) or self.id except: - self.nom="" + self.nom = "" if self.nom.find('sansnom') != -1 or self.nom == '': self.nom = self.id return self.nom def supprime(self): - """ - Cassage des boucles de références pour destruction du JDC """ + Cassage des boucles de références pour destruction du JDC + """ + self.supprime_sd() self.etape = None self.sd = None self.jdc = None self.parent = None - def supprime_sd(self, delete=False): - """Supprime la partie du catalogue de SD. - Si `delete` vaut False, on ne supprime que les références - pour permettre la destruction complète lors de la suppression - de l'ASSD. - Si `delete` vaut True, on supprime immédiatement les - objets du catalogue de SD.""" - sup = super(ASSD, self) - if hasattr(sup, 'nomj'): # == AsBase - if self.sd_deleted == 1: - return - sup.supprime(delete) - self.sd_deleted = 1 + def supprime_sd(self): + """Supprime la partie du catalogue de SD.""" + # 'del self.sdj' appellerait la méthode '_get_sdj()'... + self._del_sdj() + + def __del__(self): + message.debug(SUPERV, "__del__ ASSD %s <%s>", getattr(self, 'nom', 'unknown'), self) def accept(self,visitor): """ @@ -142,7 +164,7 @@ class ASSD(object): """ Cette methode permet de pickler les objets ASSD Ceci est possible car on coupe les liens avec les objets - parent, etape et jdc qui conduiraient à pickler de nombreux + parent, etape et jdc qui conduiraient à pickler de nombreux objets inutiles ou non picklables. En sortie, l'objet n'est plus tout à fait le même ! """ @@ -176,6 +198,17 @@ class ASSD(object): class assd(ASSD): - def __convert__(cls,valeur): - return valeur - __convert__=classmethod(__convert__) + def __convert__(cls, valeur): + # On accepte les vraies ASSD et les objets 'entier' et 'reel' + # qui font tout pour se faire passer pour de vrais entiers/réels. + if isinstance(valeur, ASSD) or type(valeur) in (int, float): + return valeur + raise ValueError("On attend un objet concept.") + __convert__ = classmethod(__convert__) + + +class not_checked(ASSD): + def __convert__(cls, valeur): + return valeur + __convert__ = classmethod(__convert__) + diff --git a/Noyau/N_BLOC.py b/Noyau/N_BLOC.py index 65617612..93340df8 100644 --- a/Noyau/N_BLOC.py +++ b/Noyau/N_BLOC.py @@ -1,30 +1,30 @@ -#@ MODIF N_BLOC Noyau DATE 07/09/2009 AUTEUR COURTOIS M.COURTOIS +#@ MODIF N_BLOC Noyau DATE 30/08/2011 AUTEUR COURTOIS M.COURTOIS # -*- coding: iso-8859-1 -*- # RESPONSABLE COURTOIS M.COURTOIS # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== -# COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG +# COPYRIGHT (C) 1991 - 2011 EDF R&D WWW.CODE-ASTER.ORG # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY -# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR -# (AT YOUR OPTION) ANY LATER VERSION. +# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR +# (AT YOUR OPTION) ANY LATER VERSION. +# +# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT +# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF +# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU +# GENERAL PUBLIC LICENSE FOR MORE DETAILS. +# +# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE +# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, +# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. # -# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT -# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF -# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU -# GENERAL PUBLIC LICENSE FOR MORE DETAILS. # -# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE -# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, -# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. -# -# # ====================================================================== -""" +""" Ce module contient la classe de definition BLOC - qui permet de spécifier les caractéristiques des blocs de mots clés + qui permet de spécifier les caractéristiques des blocs de mots clés """ import types,string,sys @@ -33,6 +33,7 @@ import traceback import N_ENTITE import N_MCBLOC from N_Exception import AsException +from N_types import force_list class BLOC(N_ENTITE.ENTITE): """ @@ -40,8 +41,8 @@ class BLOC(N_ENTITE.ENTITE): Cette classe a deux attributs de classe : - - class_instance qui indique la classe qui devra etre utilisée - pour créer l'objet qui servira à controler la conformité d'un + - class_instance qui indique la classe qui devra etre utilisée + pour créer l'objet qui servira à controler la conformité d'un bloc de mots-clés avec sa définition - label qui indique la nature de l'objet de définition (ici, BLOC) @@ -51,7 +52,7 @@ class BLOC(N_ENTITE.ENTITE): def __init__(self,fr="",ang="",docu="",regles=(),statut='f',condition=None, **args): - + """ Un bloc est caractérisé par les attributs suivants : @@ -60,9 +61,9 @@ class BLOC(N_ENTITE.ENTITE): - regles : liste d'objets de type REGLE pour vérifier la cohérence des sous-objets - statut : obligatoire ('o') ou facultatif ('f') - condition : chaine de caractère evaluable par l'interpreteur Python - - entites : dictionnaire contenant les sous-objets de self (mots-clés). - La clé du dictionnaire est le nom du mot-clé et la valeur l'objet de - définition correspondant. Cet attribut est initialisé avec l'argument + - entites : dictionnaire contenant les sous-objets de self (mots-clés). + La clé du dictionnaire est le nom du mot-clé et la valeur l'objet de + définition correspondant. Cet attribut est initialisé avec l'argument args de la méthode __init__ """ @@ -109,24 +110,25 @@ class BLOC(N_ENTITE.ENTITE): def verif_presence(self,dict,globs): """ Cette méthode vérifie si le dictionnaire passé en argument (dict) - est susceptible de contenir un bloc de mots-clés conforme à la + est susceptible de contenir un bloc de mots-clés conforme à la définition qu'il porte. Si la réponse est oui, la méthode retourne 1 Si la réponse est non, la méthode retourne 0 - + Le dictionnaire dict a pour clés les noms des mots-clés et pour valeurs les valeurs des mots-clés """ - # On recopie le dictionnaire pour protéger l'original - dico=dict.copy() + # On recopie le dictionnaire pour protéger l'original + dico = bloc_utils() + dico.update(dict) if self.condition != None : try: test = eval(self.condition,globs,dico) return test except NameError: - # erreur 'normale' : un mot-clé n'est pas présent et on veut l'évaluer dans la condition + # erreur 'normale' : un mot-cle n'est pas present et on veut l'evaluer dans la condition if CONTEXT.debug: l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2]) print "WARNING : Erreur a l'evaluation de la condition "+string.join(l) @@ -143,3 +145,21 @@ class BLOC(N_ENTITE.ENTITE): else : return 0 + +def bloc_utils(): + """Définit un ensemble de fonctions utilisables pour écrire les + conditions de BLOC.""" + def au_moins_un(mcsimp, valeurs): + """Valide si la (ou une) valeur de 'mcsimp' est au moins une fois dans + la ou les 'valeurs'. Similaire à la règle AU_MOINS_UN, 'mcsimp' peut + contenir plusieurs valeurs.""" + test = set(force_list(mcsimp)) + valeurs = set(force_list(valeurs)) + return not test.isdisjoint(valeurs) + + def aucun(mcsimp, valeurs): + """Valide si aucune des valeurs de 'mcsimp' n'est dans 'valeurs'.""" + return not au_moins_un(mcsimp, valeurs) + + return locals() + diff --git a/Noyau/N_CR.py b/Noyau/N_CR.py index cb1d7a26..37f3eb3f 100644 --- a/Noyau/N_CR.py +++ b/Noyau/N_CR.py @@ -136,16 +136,6 @@ class CR : else: if not subcr.estvide(): s=s+str(subcr) - - # convert all (eventually unicode) strings to 8-bit strings to - # avoid further encoding problems - if isinstance(self.debut, unicode): - self.debut = self.debut.encode("iso-8859-1") - if isinstance(s, unicode): - s = s.encode("iso-8859-1") - if isinstance(self.fin, unicode): - self.fin = self.fin.encode("iso-8859-1") - if s != '': s=self.debut+'\n'+self.indent(s)+self.fin+'\n' else : diff --git a/Noyau/N_ENTITE.py b/Noyau/N_ENTITE.py index 5db7f216..eafce7ad 100644 --- a/Noyau/N_ENTITE.py +++ b/Noyau/N_ENTITE.py @@ -1,32 +1,33 @@ -#@ MODIF N_ENTITE Noyau DATE 07/09/2009 AUTEUR COURTOIS M.COURTOIS +#@ MODIF N_ENTITE Noyau DATE 30/08/2011 AUTEUR COURTOIS M.COURTOIS # -*- coding: iso-8859-1 -*- # RESPONSABLE COURTOIS M.COURTOIS # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== -# COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG +# COPYRIGHT (C) 1991 - 2011 EDF R&D WWW.CODE-ASTER.ORG # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY -# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR -# (AT YOUR OPTION) ANY LATER VERSION. +# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR +# (AT YOUR OPTION) ANY LATER VERSION. +# +# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT +# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF +# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU +# GENERAL PUBLIC LICENSE FOR MORE DETAILS. +# +# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE +# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, +# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. # -# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT -# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF -# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU -# GENERAL PUBLIC LICENSE FOR MORE DETAILS. # -# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE -# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, -# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. -# -# # ====================================================================== -""" +""" Ce module contient la classe ENTITE qui est la classe de base de toutes les classes de definition d'EFICAS. """ +import re import N_CR import N_VALIDATOR @@ -41,14 +42,14 @@ class ENTITE: def __init__(self,validators=None): """ - Initialise les deux attributs regles et entites d'une classe dérivée - à : pas de règles et pas de sous-entités. - - L'attribut regles doit contenir la liste des regles qui s'appliquent - sur ses sous-entités + Initialise les deux attributs regles et entites d'une classe derivee + : pas de regles et pas de sous-entites. + + L'attribut regles doit contenir la liste des regles qui s'appliquent + sur ses sous-entites - L'attribut entités doit contenir le dictionnaires des sous-entités - (clé = nom, valeur=objet) + L'attribut entites doit contenir le dictionnaires des sous-entites + (cle = nom, valeur=objet) """ self.regles=() self.entites={} @@ -60,9 +61,9 @@ class ENTITE: def affecter_parente(self): """ Cette methode a pour fonction de donner un nom et un pere aux - sous entités qui n'ont aucun moyen pour atteindre leur parent + sous entites qui n'ont aucun moyen pour atteindre leur parent directement - Il s'agit principalement des mots cles + Il s'agit principalement des mots cles """ for k,v in self.entites.items(): v.pere = self @@ -70,39 +71,39 @@ class ENTITE: def verif_cata(self): """ - Cette methode sert à valider les attributs de l'objet de définition + Cette methode sert a valider les attributs de l'objet de definition """ - raise "La méthode verif_cata de la classe %s doit etre implémentée" % self.__class__.__name__ + raise "La methode verif_cata de la classe %s doit etre implementee" % self.__class__.__name__ def __call__(self): """ - Cette methode doit retourner un objet dérivé de la classe OBJECT + Cette methode doit retourner un objet derive de la classe OBJECT """ - raise "La méthode __call__ de la classe %s doit etre implémentée" % self.__class__.__name__ + raise "La methode __call__ de la classe %s doit etre implementee" % self.__class__.__name__ def report(self): """ - Cette méthode construit pour tous les objets dérivés de ENTITE un - rapport de validation de la définition portée par cet objet + Cette methode construit pour tous les objets derives de ENTITE un + rapport de validation de la definition portee par cet objet """ self.cr = self.CR() self.verif_cata() for k,v in self.entites.items() : try : cr = v.report() - cr.debut = "Début "+v.__class__.__name__+ ' : ' + k + cr.debut = "Debut "+v.__class__.__name__+ ' : ' + k cr.fin = "Fin "+v.__class__.__name__+ ' : ' + k self.cr.add(cr) except: self.cr.fatal("Impossible d'obtenir le rapport de %s %s" %(k,`v`)) print "Impossible d'obtenir le rapport de %s %s" %(k,`v`) - print "père =",self + print "pere =",self return self.cr def verif_cata_regles(self): """ - Cette méthode vérifie pour tous les objets dérivés de ENTITE que - les objets REGLES associés ne portent que sur des sous-entités + Cette methode verifie pour tous les objets derives de ENTITE que + les objets REGLES associes ne portent que sur des sous-entites existantes """ for regle in self.regles : @@ -112,6 +113,35 @@ class ENTITE: l.append(mc) if l != [] : txt = str(regle) - self.cr.fatal("Argument(s) non permis : %s pour la règle : %s" %(`l`,txt)) + self.cr.fatal("Argument(s) non permis : %s pour la regle : %s" %(`l`,txt)) + def check_definition(self, parent): + """Verifie la definition d'un objet composite (commande, fact, bloc).""" + args = self.entites.copy() + mcs = set() + for nom, val in args.items(): + if val.label == 'SIMP': + mcs.add(nom) + #XXX + #if val.max != 1 and val.type == 'TXM': + #print "#CMD", parent, nom + elif val.label == 'FACT': + val.check_definition(parent) + #PNPNPN surcharge + # CALC_SPEC ! + #assert self.label != 'FACT', \ + # 'Commande %s : Mot-clef facteur present sous un mot-clef facteur : interdit !' \ + # % parent + else: + continue + del args[nom] + # seuls les blocs peuvent entrer en conflit avec les mcs du plus haut niveau + for nom, val in args.items(): + if val.label == 'BLOC': + mcbloc = val.check_definition(parent) + #XXX + #print "#BLOC", parent, re.sub('\s+', ' ', val.condition) + #assert mcs.isdisjoint(mcbloc), "Commande %s : Mot(s)-clef(s) vu(s) plusieurs fois : %s" \ + # % (parent, tuple(mcs.intersection(mcbloc))) + return mcs diff --git a/Noyau/N_ETAPE.py b/Noyau/N_ETAPE.py index baf39a40..5031451b 100644 --- a/Noyau/N_ETAPE.py +++ b/Noyau/N_ETAPE.py @@ -1,29 +1,29 @@ -#@ MODIF N_ETAPE Noyau DATE 16/11/2009 AUTEUR COURTOIS M.COURTOIS +#@ MODIF N_ETAPE Noyau DATE 12/10/2011 AUTEUR COURTOIS M.COURTOIS # -*- coding: iso-8859-1 -*- # RESPONSABLE COURTOIS M.COURTOIS # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== -# COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG +# COPYRIGHT (C) 1991 - 2011 EDF R&D WWW.CODE-ASTER.ORG # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY -# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR -# (AT YOUR OPTION) ANY LATER VERSION. +# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR +# (AT YOUR OPTION) ANY LATER VERSION. +# +# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT +# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF +# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU +# GENERAL PUBLIC LICENSE FOR MORE DETAILS. +# +# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE +# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, +# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. # -# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT -# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF -# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU -# GENERAL PUBLIC LICENSE FOR MORE DETAILS. # -# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE -# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, -# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. -# -# # ====================================================================== -""" - Ce module contient la classe ETAPE qui sert à vérifier et à exécuter +""" + Ce module contient la classe ETAPE qui sert a verifier et a executer une commande """ @@ -39,29 +39,30 @@ from N_Exception import AsException import N_utils from N_utils import AsType from N_ASSD import ASSD +from N_info import message, SUPERV class ETAPE(N_MCCOMPO.MCCOMPO): """ - Cette classe hérite de MCCOMPO car ETAPE est un OBJECT composite + Cette classe herite de MCCOMPO car ETAPE est un OBJECT composite """ nature = "OPERATEUR" - # L'attribut de classe codex est utilisé pour rattacher le module de calcul éventuel (voir Build) - # On le met à None pour indiquer qu'il n'y a pas de module de calcul rattaché + # L'attribut de classe codex est utilise pour rattacher le module de calcul eventuel (voir Build) + # On le met a None pour indiquer qu'il n'y a pas de module de calcul rattache codex=None def __init__(self,oper=None,reuse=None,args={}): """ Attributs : - - definition : objet portant les attributs de définition d'une étape de type opérateur. Il - est initialisé par l'argument oper. + - definition : objet portant les attributs de definition d'une etape de type operateur. Il + est initialise par l'argument oper. - - reuse : indique le concept d'entrée réutilisé. Il se trouvera donc en sortie - si les conditions d'exécution de l'opérateur l'autorise + - reuse : indique le concept d'entree reutilise. Il se trouvera donc en sortie + si les conditions d'execution de l'operateur l'autorise - - valeur : arguments d'entrée de type mot-clé=valeur. Initialisé avec l'argument args. + - valeur : arguments d'entree de type mot-cle=valeur. Initialise avec l'argument args. """ self.definition=oper @@ -80,8 +81,8 @@ class ETAPE(N_MCCOMPO.MCCOMPO): def make_register(self): """ - Initialise les attributs jdc, id, niveau et réalise les - enregistrements nécessaires + Initialise les attributs jdc, id, niveau et realise les + enregistrements necessaires """ if self.parent : self.jdc = self.parent.get_jdc_root() @@ -94,8 +95,8 @@ class ETAPE(N_MCCOMPO.MCCOMPO): def nettoiargs(self): """ - Cette methode a pour fonction de retirer tous les arguments egaux à None - de la liste des arguments. Ils sont supposés non présents et donc retirés. + Cette methode a pour fonction de retirer tous les arguments egaux a None + de la liste des arguments. Ils sont supposes non presents et donc retires. """ for k in self.valeur.keys(): if self.valeur[k] == None:del self.valeur[k] @@ -109,28 +110,29 @@ class ETAPE(N_MCCOMPO.MCCOMPO): def Build_sd(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 + Construit le concept produit de l'operateur. Deux cas + peuvent se presenter : + + - le parent n'est pas defini. Dans ce cas, l'etape prend en charge la creation et le nommage du concept. - - le parent est défini. Dans ce cas, l'étape demande au parent la création et + - le parent est defini. Dans ce cas, l'etape demande au parent la creation et le nommage du concept. """ + message.debug(SUPERV, "Build_sd %s", self.nom) self.sdnom=nom try: if self.parent: sd= self.parent.create_sdprod(self,nom) - if type(self.definition.op_init) == types.FunctionType: + if type(self.definition.op_init) == types.FunctionType: apply(self.definition.op_init,(self,self.parent.g_context)) else: sd=self.get_sd_prod() - # On n'utilise pas self.definition.op_init car self.parent + # 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 + # On ne nomme le concept que dans le cas de non reutilisation # d un concept sd.set_name(nom) except AsException,e: @@ -157,15 +159,15 @@ class ETAPE(N_MCCOMPO.MCCOMPO): def get_sd_prod(self): """ - Retourne le concept résultat de l'étape + Retourne le concept resultat de l'etape Deux cas : - cas 1 : sd_prod de oper n'est pas une fonction il s'agit d'une sous classe de ASSD - on construit le sd à partir de cette classe + on construit le sd a partir de cette classe et on le retourne - cas 2 : il s'agit d'une fonction - on l'évalue avec les mots-clés de l'étape (mc_liste) - on construit le sd à partir de la classe obtenue + on l'evalue avec les mots-cles de l'etape (mc_liste) + on construit le sd a partir de la classe obtenue et on le retourne """ if type(self.definition.sd_prod) == types.FunctionType: @@ -183,23 +185,23 @@ class ETAPE(N_MCCOMPO.MCCOMPO): # sys.exc_info()[0],sys.exc_info()[1],) else: sd_prod=self.definition.sd_prod - # on teste maintenant si la SD est réutilisée ou s'il faut la créer + # on teste maintenant si la SD est reutilisee ou s'il faut la creer if self.definition.reentrant != 'n' and self.reuse: # Le concept produit est specifie reutilise (reuse=xxx). C'est une erreur mais non fatale. # Elle sera traitee ulterieurement. self.sd=self.reuse else: self.sd= sd_prod(etape=self) - # Si l'operateur est obligatoirement reentrant et reuse n'a pas ete specifie, c'est une erreur. + # Si l'operateur est obligatoirement reentrant et reuse n'a pas ete specifie, c'est une erreur. # On ne fait rien ici. L'erreur sera traiter par la suite. - # précaution + # precaution if self.sd is not None and not isinstance(self.sd, ASSD): raise AsException(""" -Impossible de typer le résultat ! +Impossible de typer le resultat ! Causes possibles : - Utilisateur : Soit la valeur fournie derrière "reuse" est incorrecte, - soit il y a une "," à la fin d'une commande précédente. - Développeur : La fonction "sd_prod" retourne un type invalide.""") + Utilisateur : Soit la valeur fournie derriere "reuse" est incorrecte, + soit il y a une "," a la fin d'une commande precedente. + Developpeur : La fonction "sd_prod" retourne un type invalide.""") return self.sd def get_type_produit(self): @@ -210,14 +212,14 @@ Causes possibles : def get_type_produit_brut(self): """ - Retourne le type du concept résultat de l'étape + Retourne le type du concept resultat de l'etape Deux cas : - cas 1 : sd_prod de oper n'est pas une fonction il s'agit d'une sous classe de ASSD on retourne le nom de la classe - cas 2 : il s'agit d'une fonction - on l'évalue avec les mots-clés de l'étape (mc_liste) - et on retourne son résultat + on l'evalue avec les mots-cles de l'etape (mc_liste) + et on retourne son resultat """ if type(self.definition.sd_prod) == types.FunctionType: d=self.cree_dict_valeurs(self.mc_liste) @@ -228,26 +230,30 @@ Causes possibles : 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 + Retourne l'etape a laquelle appartient self + Un objet de la categorie etape doit retourner self pour indiquer que + l'etape a ete trouvee XXX fait double emploi avec self.etape ???? """ return self def supprime(self): """ - Méthode qui supprime toutes les références arrières afin que l'objet puisse - etre correctement détruit par le garbage collector + Methode qui supprime toutes les references arrieres afin que l'objet puisse + etre correctement detruit par le garbage collector """ N_MCCOMPO.MCCOMPO.supprime(self) - self.jdc=None - self.appel=None - if self.sd : self.sd.supprime() + self.jdc = None + self.appel = None + for name in dir(self): + if name.startswith( '_cache_' ): + setattr(self, name, None) + if self.sd: + self.sd.supprime() def isactif(self): - """ - Indique si l'étape est active (1) ou inactive (0) + """ + Indique si l'etape est active (1) ou inactive (0) """ return self.actif @@ -256,27 +262,30 @@ Causes possibles : Methode utilisee pour que l etape self se declare etape courante. Utilise par les macros """ + message.debug(SUPERV, "call etape.set_current_step", stack_id=-1) cs= CONTEXT.get_current_step() if self.parent != cs : - raise "L'étape courante %s devrait etre le parent de self : %s" % (cs,self) + raise AsException("L'etape courante", cs.nom, cs, + "devrait etre le parent de", self.nom, self) else : CONTEXT.unset_current_step() CONTEXT.set_current_step(self) def reset_current_step(self): - """ - Methode utilisee par l'etape self qui remet son etape parent comme - etape courante + """ + Methode utilisee par l'etape self qui remet son etape parent comme + etape courante """ cs= CONTEXT.get_current_step() if self != cs : - raise "L'étape courante %s devrait etre self : %s" % (cs,self) + raise AsException("L'etape courante", cs.nom, cs, + "devrait etre", self.nom, self) else : CONTEXT.unset_current_step() CONTEXT.set_current_step(self.parent) def issubstep(self,etape): - """ + """ Cette methode retourne un entier indiquant si etape est une sous etape de self ou non 1 = oui @@ -286,7 +295,7 @@ Causes possibles : return 0 def get_file(self,unite=None,fic_origine=''): - """ + """ Retourne le nom du fichier associe a l unite logique unite (entier) ainsi que le source contenu dans le fichier """ @@ -296,9 +305,9 @@ Causes possibles : if unite != None: if os.path.exists("fort."+str(unite)): file= "fort."+str(unite) - if file == None : + if file == None : raise AsException("Impossible de trouver le fichier correspondant a l unite %s" % unite) - if not os.path.exists(file): + if not os.path.exists(file): raise AsException("%s n'est pas un fichier existant" % unite) fproc=open(file,'r') text=string.replace(fproc.read(),'\r\n','\n') @@ -325,7 +334,7 @@ Causes possibles : def copy(self): """ Méthode qui retourne une copie de self non enregistrée auprès du JDC - et sans sd + et sans sd """ etape = copy(self) etape.sd = None @@ -341,13 +350,13 @@ Causes possibles : return etape def copy_reuse(self,old_etape): - """ Méthode qui copie le reuse d'une autre étape. + """ Méthode qui copie le reuse d'une autre étape. """ if hasattr(old_etape,"reuse") : self.reuse = old_etape.reuse def copy_sdnom(self,old_etape): - """ Méthode qui copie le sdnom d'une autre étape. + """ Méthode qui copie le sdnom d'une autre étape. """ if hasattr(old_etape,"sdnom") : self.sdnom = old_etape.sdnom @@ -410,7 +419,7 @@ Causes possibles : def is_include(self): - """Permet savoir si on a affaire à une commande de type INCLUDE/INCLUDE_MATERIAU + """Permet savoir si on a affaire à la commande INCLUDE car le comportement de ces macros est particulier. """ return self.nom.startswith('INCLUDE') @@ -427,6 +436,4 @@ Causes possibles : """ # pourrait être appelée par une commande fortran faisant appel à des fonctions python # on passe la main au parent - return self.parent.get_concept() - - + return self.parent.get_concept(nomsd) diff --git a/Noyau/N_FONCTION.py b/Noyau/N_FONCTION.py index 83d00e3b..971af636 100644 --- a/Noyau/N_FONCTION.py +++ b/Noyau/N_FONCTION.py @@ -1,121 +1,110 @@ -#@ MODIF N_FONCTION Noyau DATE 10/11/2009 AUTEUR COURTOIS M.COURTOIS +#@ MODIF N_FONCTION Noyau DATE 28/06/2011 AUTEUR COURTOIS M.COURTOIS # -*- coding: iso-8859-1 -*- # RESPONSABLE COURTOIS M.COURTOIS # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== -# COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG +# COPYRIGHT (C) 1991 - 2011 EDF R&D WWW.CODE-ASTER.ORG # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY -# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR -# (AT YOUR OPTION) ANY LATER VERSION. +# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR +# (AT YOUR OPTION) ANY LATER VERSION. +# +# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT +# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF +# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU +# GENERAL PUBLIC LICENSE FOR MORE DETAILS. +# +# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE +# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, +# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. # -# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT -# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF -# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU -# GENERAL PUBLIC LICENSE FOR MORE DETAILS. # -# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE -# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, -# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. -# -# # ====================================================================== -# attention ! cet import permet d'avoir, dans les formules, le comportement +# Attention : cet import permet d'avoir, en Python, le comportement # de la division réelle pour les entiers, et non la division entière -# 1/2=0.5 (et non 0) +# 1/2=0.5 (et non 0). Comportement par défaut dans Python 3.0. from __future__ import division from N_ASSD import ASSD -from asojb import AsBase +from N_info import message, SUPERV -class FONCTION(ASSD):pass +class FONCTION(ASSD): + pass -class formule(ASSD,AsBase): - def __init__(self,**args): - ASSD.__init__(self,**args) - self.nompar =None - self.expression=None +class formule(ASSD): + def __init__(self, *args, **kwargs): + ASSD.__init__(self, *args, **kwargs) + self.nompar = None + self.expression = None - def __call__(self,*val): - context = {} - # cas de INCLUDE (ou POURSUITE dans Eficas) - context.update(getattr(self.parent, 'contexte_fichier_init', {})) - # récupération des constantes locales en cas de MACRO - context.update(getattr(self.parent, 'macro_const_context', {})) - i=0 - for param in self.nompar : - context[param]=val[i] - i=i+1 - try : - res=eval(self.expression,self.jdc.const_context, context) - except : - print 75*'!' - print '! ' + '%-72s' % ('Erreur evaluation formule '+self.nom) + '!' - print 75*'!' - raise - return res + def __call__(self, *val): + context = {} + # cas de INCLUDE (ou POURSUITE dans Eficas) + context.update(getattr(self.parent, 'contexte_fichier_init', {})) + # récupération des constantes locales en cas de MACRO + context.update(getattr(self.parent, 'macro_const_context', {})) + for param, value in zip(self.nompar, val): + context[param] = value + try: + res = eval(self.expression, self.jdc.const_context, context) + except Exception, exc: + message.error(SUPERV, "ERREUR LORS DE L'ÉVALUATION DE LA FORMULE '%s' " \ + ":\n>> %s",self.nom, str(exc)) + raise + return res - def setFormule(self,nom_para,texte): - """ - Cette methode sert a initialiser les attributs - nompar, expression et code qui sont utilisés - dans l'évaluation de la formule - """ - self.nompar = nom_para - self.expression = texte - try : - self.code=compile(texte,texte,'eval') - except SyntaxError : - print 75*'!' - print '! ' + '%-72s' % ('Erreur evaluation formule '+self.nom) + '!' - print 75*'!' - raise + def setFormule(self, nom_para, texte): + """Cette methode sert a initialiser les attributs + nompar, expression et code qui sont utilisés + dans l'évaluation de la formule.""" + self.nompar = nom_para + self.expression = texte + try : + self.code = compile(texte, texte, 'eval') + except SyntaxError, exc: + message.error(SUPERV, "ERREUR LORS DE LA CREATION DE LA FORMULE '%s' " \ + ":\n>> %s", self.nom, str(exc)) + raise - def __setstate__(self,state): - """ - Cette methode sert a restaurer l'attribut code - lors d'un unpickle - """ - self.__dict__.update(state) # update attributes - self.setFormule(self.nompar,self.expression) # restore code attribute - - def __getstate__(self): - """ - Pour les formules, il faut enlever l'attribut code - qui n'est pas picklable - """ - d=ASSD.__getstate__(self) - del d['code'] - return d + def __setstate__(self,state): + """Cette methode sert a restaurer l'attribut code lors d'un unpickle.""" + self.__dict__.update(state) # update attributes + self.setFormule(self.nompar, self.expression) # restore code attribute - def Parametres(self): - """Equivalent de fonction.Parametres pour pouvoir utiliser des formules - à la place de fonctions dans certaines macro-commandes. - """ - from SD.sd_fonction import sd_formule - from Utilitai.Utmess import UTMESS - if self.accessible(): - TypeProl={'E':'EXCLU', 'L':'LINEAIRE', 'C':'CONSTANT', 'I':'INTERPRE' } - sd = sd_formule(self.get_name()) - prol = sd.PROL.get() - nova = sd.NOVA.get() - if prol is None or nova is None: - UTMESS('F', 'SDVERI_2', valk=[objev]) - dico={ - 'INTERPOL' : ['LIN','LIN'], - 'NOM_PARA' : [s.strip() for s in nova], - 'NOM_RESU' : prol[3][0:16].strip(), - 'PROL_DROITE' : TypeProl['E'], - 'PROL_GAUCHE' : TypeProl['E'], - } - else: - raise Accas.AsException("Erreur dans fonction.Parametres en PAR_LOT='OUI'") - return dico + def __getstate__(self): + """Pour les formules, il faut enlever l'attribut code qui n'est + pas picklable.""" + d = ASSD.__getstate__(self) + del d['code'] + return d + def Parametres(self): + """Equivalent de fonction.Parametres pour pouvoir utiliser des formules + à la place de fonctions dans certaines macro-commandes. + """ + from SD.sd_fonction import sd_formule + from Utilitai.Utmess import UTMESS + if self.accessible(): + TypeProl={ 'E':'EXCLU', 'L':'LINEAIRE', 'C':'CONSTANT', 'I':'INTERPRE' } + sd = sd_formule(self.get_name()) + prol = sd.PROL.get() + nova = sd.NOVA.get() + if prol is None or nova is None: + UTMESS('F', 'SDVERI_2', valk=[objev]) + dico={ + 'INTERPOL' : ['LIN','LIN'], + 'NOM_PARA' : [s.strip() for s in nova], + 'NOM_RESU' : prol[3][0:16].strip(), + 'PROL_DROITE' : TypeProl['E'], + 'PROL_GAUCHE' : TypeProl['E'], + } + else: + raise Accas.AsException("Erreur dans fonction.Parametres en PAR_LOT='OUI'") + return dico -class formule_c(formule): - pass +class formule_c(formule): + pass diff --git a/Noyau/N_JDC.py b/Noyau/N_JDC.py index a5b37c4a..4efa4842 100644 --- a/Noyau/N_JDC.py +++ b/Noyau/N_JDC.py @@ -1,24 +1,24 @@ -#@ MODIF N_JDC Noyau DATE 24/08/2010 AUTEUR COURTOIS M.COURTOIS +#@ MODIF N_JDC Noyau DATE 28/06/2011 AUTEUR COURTOIS M.COURTOIS # -*- coding: iso-8859-1 -*- # RESPONSABLE COURTOIS M.COURTOIS # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== -# COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG +# COPYRIGHT (C) 1991 - 2011 EDF R&D WWW.CODE-ASTER.ORG # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY -# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR -# (AT YOUR OPTION) ANY LATER VERSION. +# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR +# (AT YOUR OPTION) ANY LATER VERSION. +# +# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT +# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF +# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU +# GENERAL PUBLIC LICENSE FOR MORE DETAILS. +# +# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE +# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, +# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. # -# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT -# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF -# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU -# GENERAL PUBLIC LICENSE FOR MORE DETAILS. # -# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE -# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, -# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. -# -# # ====================================================================== @@ -35,8 +35,7 @@ import N_OBJECT import N_CR from N_Exception import AsException from N_ASSD import ASSD - - +from N_info import message, SUPERV MemoryErrorMsg = """MemoryError : @@ -87,7 +86,7 @@ NONE = None self.procedure=procedure self.definition = definition self.cata=cata - if type(self.cata) != types.TupleType and cata != None: + if type(self.cata) != types.TupleType and cata != None: self.cata=(self.cata,) self._build_reserved_kw_list() self.cata_ordonne_dico=cata_ord_dico @@ -95,12 +94,12 @@ NONE = None self.appli=appli self.parent=parent self.context_ini=context_ini - # On conserve les arguments supplémentaires. Il est possible de passer - # des informations globales au JDC par ce moyen. Il pourrait etre plus - # sur de mettre en place le mecanisme des mots-cles pour verifier la + # On conserve les arguments supplémentaires. Il est possible de passer + # des informations globales au JDC par ce moyen. Il pourrait etre plus + # sur de mettre en place le mecanisme des mots-cles pour verifier la # validité des valeurs passées. # Ceci reste à faire - # On initialise avec les parametres de la definition puis on + # On initialise avec les parametres de la definition puis on # update avec ceux du JDC self.args=self.definition.args self.args.update(args) @@ -116,7 +115,7 @@ NONE = None # # Creation de l objet compte rendu pour collecte des erreurs # - self.cr = self.CR(debut = "CR phase d'initialisation", + self.cr = self.CR(debut = "CR phase d'initialisation", fin = "fin CR phase d'initialisation") # on met le jdc lui-meme dans le context global pour l'avoir sous # l'etiquette "jdc" dans le fichier de commandes @@ -137,11 +136,11 @@ NONE = None def compile(self): """ Cette methode compile la chaine procedure - Si des erreurs se produisent, elles sont consignées dans le + Si des erreurs se produisent, elles sont consignées dans le compte-rendu self.cr """ try: - if self.appli != None : + if self.appli != None : self.appli.affiche_infos('Compilation du fichier de commandes en cours ...') self.proc_compile=compile(self.procedure,self.nom,'exec') except SyntaxError, e: @@ -195,13 +194,14 @@ Causes possibles : for sdnom,sd in self.context_ini.items(): if isinstance(sd,ASSD):self.sds_dict[sdnom]=sd - if self.appli != None : + if self.appli != None : self.appli.affiche_infos('Interprétation du fichier de commandes en cours ...') # On sauve le contexte pour garder la memoire des constantes - # En mode edition (EFICAS) ou lors des verifications le contexte + # En mode edition (EFICAS) ou lors des verifications le contexte # est recalculé # mais les constantes sont perdues self.const_context=self.g_context + message.debug(SUPERV, "pass") exec self.proc_compile in self.g_context CONTEXT.unset_current_step() @@ -231,10 +231,10 @@ Causes possibles : etype, value, tb = sys.exc_info() l= traceback.extract_tb(tb) s= traceback.format_exception_only("Erreur de nom",e)[0][:-1] - message = "erreur de syntaxe, %s ligne %d" % (s,l[-1][1]) + msg = "erreur de syntaxe, %s ligne %d" % (s,l[-1][1]) if CONTEXT.debug : traceback.print_exc() - self.cr.exception(message) + self.cr.exception(msg) CONTEXT.unset_current_step() except self.UserError,exc_val: @@ -242,10 +242,10 @@ Causes possibles : CONTEXT.unset_current_step() self.affiche_fin_exec() self.traiter_fin_exec('commande') - + except : # erreur inattendue - # sys_exc_typ,sys_exc_value,sys_exc_frame = sys_exc.info() + # sys_exc_typ,sys_exc_value,sys_exc_frame = sys_exc.info() # (tuple de 3 éléments) if CONTEXT.debug : traceback.print_exc() @@ -272,14 +272,14 @@ Causes possibles : Par defaut il n'y a pas de traitement. Elle doit etre surchargee pour en introduire un """ - print "FIN D'EXECUTION",mode,etape + message.info(SUPERV, "FIN D'EXECUTION %s %s", mode, etape) def traiter_user_exception(self,exc_val): - """Cette methode realise un traitement sur les exceptions utilisateur - Par defaut il n'y a pas de traitement. La méthode doit etre + """Cette methode realise un traitement sur les exceptions utilisateur + Par defaut il n'y a pas de traitement. La méthode doit etre surchargée pour en introduire un. """ - return + return def register(self,etape): """ @@ -288,6 +288,7 @@ Causes possibles : """ self.etapes.append(etape) self.index_etapes[etape] = len(self.etapes) - 1 + message.debug(SUPERV, "#%d %s", self.index_etapes[etape], etape.nom) return self.g_register(etape) def o_register(self,sd): @@ -307,42 +308,40 @@ Causes possibles : return idetape def create_sdprod(self,etape,nomsd): - """ + """ Cette methode doit fabriquer le concept produit retourne par l'etape etape et le nommer. Elle est appelée à l'initiative de l'etape - pendant le processus de construction de cette etape : + pendant le processus de construction de cette etape : methode __call__ de la classe CMD (OPER ou MACRO) - Ce travail est réalisé par le contexte supérieur - (etape.parent) car dans certains cas, le concept ne doit - pas etre fabriqué mais l'etape doit simplement utiliser + Ce travail est réalisé par le contexte supérieur + (etape.parent) car dans certains cas, le concept ne doit + pas etre fabriqué mais l'etape doit simplement utiliser un concept préexistant. Deux cas possibles : - Cas 1 : etape.reuse != None : le concept est réutilisé - - Cas 2 : l'étape appartient à une macro qui a déclaré un - concept de sortie qui doit etre produit par cette + - Cas 2 : l'étape appartient à une macro qui a déclaré un + concept de sortie qui doit etre produit par cette etape. Dans le cas du JDC, le deuxième cas ne peut pas se produire. """ sd= etape.get_sd_prod() if sd != None and (etape.definition.reentrant == 'n' or etape.reuse is None) : - # ATTENTION : On ne nomme la SD que dans le cas de non reutilisation + # ATTENTION : On ne nomme la SD que dans le cas de non reutilisation # d un concept. Commande non reentrante ou reuse absent. self.NommerSdprod(sd,nomsd) return sd def NommerSdprod(self,sd,sdnom,restrict='non'): - """ - Nomme la SD apres avoir verifie que le nommage est possible : nom + """ + 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 """ - if CONTEXT.debug : print "JDC.NommerSdprod ",sd,sdnom - o=self.sds_dict.get(sdnom,None) if isinstance(o,ASSD): raise AsException("Nom de concept deja defini : %s" % sdnom) @@ -357,10 +356,11 @@ Causes possibles : # En plus si restrict vaut 'non', on insere le concept dans le contexte du JDC if restrict == 'non': self.g_context[sdnom]=sd + message.debug(SUPERV, "g_context[%r] = %s", sdnom, sd) def reg_sd(self,sd): - """ - Methode appelee dans l __init__ d un ASSD lors de sa creation + """ + Methode appelee dans l __init__ d un ASSD lors de sa creation pour s enregistrer """ self.sds.append(sd) @@ -371,8 +371,8 @@ Causes possibles : Met à jour les étapes du JDC qui sont après etape suite à la disparition du concept sd """ - # Cette methode est définie dans le noyau mais ne sert que pendant - # la phase de creation des etapes et des concepts. Il n'y a aucun + # Cette methode est définie dans le noyau mais ne sert que pendant + # la phase de creation des etapes et des concepts. Il n'y a aucun # traitement particulier à réaliser. # Dans d'autres conditions, il faut surcharger cette méthode return @@ -384,10 +384,10 @@ Causes possibles : def get_file(self,unite=None,fic_origine=''): """ - Retourne le nom du fichier correspondant à un numero d'unité + Retourne le nom du fichier correspondant à un numero d'unité logique (entier) ainsi que le source contenu dans le fichier """ - if self.appli is not None: + 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: @@ -409,10 +409,10 @@ Causes possibles : return file,text def set_par_lot(self,par_lot): - """ - Met le mode de traitement a PAR LOT + """ + Met le mode de traitement a PAR LOT ou a COMMANDE par COMMANDE - en fonction de la valeur du mot cle PAR_LOT et + en fonction de la valeur du mot cle PAR_LOT et du contexte : application maitre ou pas """ if self.appli == None: @@ -431,7 +431,7 @@ Causes possibles : def interact(self): """ - Cette methode a pour fonction d'ouvrir un interpreteur + Cette methode a pour fonction d'ouvrir un interpreteur pour que l'utilisateur entre des commandes interactivement """ CONTEXT.set_current_step(self) @@ -459,9 +459,9 @@ Causes possibles : 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 + # 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 + # 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 diff --git a/Noyau/N_MACRO.py b/Noyau/N_MACRO.py index 6d5b70fc..dc513333 100644 --- a/Noyau/N_MACRO.py +++ b/Noyau/N_MACRO.py @@ -1,28 +1,28 @@ -#@ MODIF N_MACRO Noyau DATE 07/09/2009 AUTEUR COURTOIS M.COURTOIS +#@ MODIF N_MACRO Noyau DATE 30/08/2011 AUTEUR COURTOIS M.COURTOIS # -*- coding: iso-8859-1 -*- # RESPONSABLE COURTOIS M.COURTOIS # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== -# COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG +# COPYRIGHT (C) 1991 - 2011 EDF R&D WWW.CODE-ASTER.ORG # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY -# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR -# (AT YOUR OPTION) ANY LATER VERSION. +# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR +# (AT YOUR OPTION) ANY LATER VERSION. +# +# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT +# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF +# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU +# GENERAL PUBLIC LICENSE FOR MORE DETAILS. +# +# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE +# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, +# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. # -# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT -# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF -# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU -# GENERAL PUBLIC LICENSE FOR MORE DETAILS. # -# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE -# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, -# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. -# -# # ====================================================================== -""" +""" Ce module contient la classe de definition MACRO qui permet de spécifier les caractéristiques d'une macro-commande """ @@ -31,16 +31,17 @@ import types,string,traceback import N_ENTITE import N_MACRO_ETAPE +import N_OPS import nommage class MACRO(N_ENTITE.ENTITE): """ Classe pour definir une macro-commande - Cette classe a trois attributs de classe + Cette classe a trois attributs de classe - - class_instance qui indique la classe qui devra etre utilisée - pour créer l'objet qui servira à controler la conformité d'un + - class_instance qui indique la classe qui devra etre utilisée + pour créer l'objet qui servira à controler la conformité d'un macro-commande avec sa définition - label qui indique la nature de l'objet de définition (ici, MACRO) @@ -121,7 +122,7 @@ class MACRO(N_ENTITE.ENTITE): self.fichier_ini = fichier_ini # Attribut op_init : Fonction a appeler a la construction de l operateur sauf si == None self.op_init=op_init - self.entites=args + self.entites = args current_cata=CONTEXT.get_current_cata() if niveau == None: self.niveau=None @@ -131,6 +132,7 @@ class MACRO(N_ENTITE.ENTITE): self.niveau.enregistre(self) self.UIinfo=UIinfo self.affecter_parente() + self.check_definition(self.nom) def __call__(self,reuse=None,**args): """ @@ -167,8 +169,8 @@ class MACRO(N_ENTITE.ENTITE): """ if self.op is not None and (type(self.op) != types.IntType or self.op > 0) : self.cr.fatal("L'attribut 'op' doit etre un entier signé : %s" %`self.op`) - if self.proc is not None and type(self.proc) != types.FunctionType: - self.cr.fatal("L'attribut op doit etre une fonction Python : %s" % `self.proc`) + if self.proc is not None and not isinstance(self.proc, N_OPS.OPS): + self.cr.fatal("L'attribut op doit etre une instance d'OPS : %s" % `self.proc`) if type(self.regles) != types.TupleType : self.cr.fatal("L'attribut 'regles' doit etre un tuple : %s" %`self.regles`) if type(self.fr) != types.StringType : @@ -188,4 +190,3 @@ class MACRO(N_ENTITE.ENTITE): """ self.niveau=None - diff --git a/Noyau/N_MACRO_ETAPE.py b/Noyau/N_MACRO_ETAPE.py index 7b59d5c0..585d5135 100644 --- a/Noyau/N_MACRO_ETAPE.py +++ b/Noyau/N_MACRO_ETAPE.py @@ -1,28 +1,28 @@ -#@ MODIF N_MACRO_ETAPE Noyau DATE 23/03/2010 AUTEUR COURTOIS M.COURTOIS +#@ MODIF N_MACRO_ETAPE Noyau DATE 12/10/2011 AUTEUR COURTOIS M.COURTOIS # -*- coding: iso-8859-1 -*- # RESPONSABLE COURTOIS M.COURTOIS # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== -# COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG +# COPYRIGHT (C) 1991 - 2011 EDF R&D WWW.CODE-ASTER.ORG # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY -# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR -# (AT YOUR OPTION) ANY LATER VERSION. +# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR +# (AT YOUR OPTION) ANY LATER VERSION. +# +# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT +# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF +# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU +# GENERAL PUBLIC LICENSE FOR MORE DETAILS. +# +# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE +# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, +# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. # -# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT -# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF -# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU -# GENERAL PUBLIC LICENSE FOR MORE DETAILS. # -# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE -# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, -# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. -# -# # ====================================================================== -""" +""" Ce module contient la classe MACRO_ETAPE qui sert à vérifier et à exécuter une commande """ @@ -39,6 +39,7 @@ import N_utils from N_utils import AsType from N_CO import CO from N_ASSD import ASSD +from N_info import message, SUPERV class MACRO_ETAPE(N_ETAPE.ETAPE): """ @@ -50,15 +51,15 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): """ Attributs : - - definition : objet portant les attributs de définition d'une étape - de type macro-commande. Il est initialisé par + - definition : objet portant les attributs de définition d'une étape + de type macro-commande. Il est initialisé par l'argument oper. - reuse : indique le concept d'entrée réutilisé. Il se trouvera donc - en sortie si les conditions d'exécution de l'opérateur + en sortie si les conditions d'exécution de l'opérateur l'autorise - - valeur : arguments d'entrée de type mot-clé=valeur. Initialisé + - valeur : arguments d'entrée de type mot-clé=valeur. Initialisé avec l'argument args. """ @@ -80,8 +81,8 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): self.etapes = [] self.index_etapes = {} self.sds = [] - # Dans le cas d'une macro écrite en Python, l'attribut Outputs est un - # dictionnaire qui contient les concepts produits de sortie + # Dans le cas d'une macro écrite en Python, l'attribut Outputs est un + # dictionnaire qui contient les concepts produits de sortie # (nom : ASSD) déclarés dans la fonction sd_prod self.Outputs = {} self.sd = None @@ -108,30 +109,31 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): def Build_sd(self,nom): """ - Construit le concept produit de l'opérateur. Deux cas + 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 + + - 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 + - le parent est défini. Dans ce cas, l'étape demande au parent la création et le nommage du concept. """ + message.debug(SUPERV, "Build_sd %s", self.nom) self.sdnom=nom try: - # On positionne la macro self en tant que current_step pour que les + # 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 + # comme parent self.set_current_step() if self.parent: sd= self.parent.create_sdprod(self,nom) - if type(self.definition.op_init) == types.FunctionType: + 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 + # On ne nomme le concept que dans le cas de non reutilisation # d un concept sd.set_name(nom) self.reset_current_step() @@ -139,7 +141,7 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): self.reset_current_step() raise AsException("Etape ",self.nom,'ligne : ',self.appel[0], 'fichier : ',self.appel[1],e) - except (EOFError,self.UserError): + except (EOFError, self.UserError): # Le retablissement du step courant n'est pas strictement necessaire. On le fait pour des raisons de coherence self.reset_current_step() raise @@ -160,7 +162,7 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): # On marque les concepts CO pour verification ulterieure de leur bonne utilisation l=self.get_all_co() for c in l: - #if not hasattr(c,"_etape") or c._etape is not c.etape: + #if not hasattr(c,"_etape") or c._etape is not c.etape: c._etape=self return l @@ -195,7 +197,7 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): # les concepts produits dans self.sdprods, il faut le mettre à zéro avant de l'appeler self.sdprods=[] sd_prod= apply(sd_prod,(self,),d) - except (EOFError,self.UserError): + except (EOFError, self.UserError), exc: raise except: if CONTEXT.debug: traceback.print_exc() @@ -213,8 +215,8 @@ class MACRO_ETAPE(N_ETAPE.ETAPE): else: self.sd= sd_prod(etape=self) self.typret=sd_prod - # Si la commande est obligatoirement reentrante et reuse n'a pas ete specifie, c'est une erreur. - # On ne fait rien ici. L'erreur sera traitee par la suite. + # Si la commande est obligatoirement reentrante et reuse n'a pas ete specifie, c'est une erreur. + # On ne fait rien ici. L'erreur sera traitee par la suite. # précaution if self.sd is not None and not isinstance(self.sd, ASSD): raise AsException(""" @@ -266,7 +268,7 @@ Causes possibles : On tient compte des commandes qui modifient le contexte comme DETRUIRE ou les macros """ - # L'étape courante pour laquelle le contexte a été calculé est + # L'étape courante pour laquelle le contexte a été calculé est # mémorisée dans self.index_etape_courante # Si on insère des commandes (par ex, dans EFICAS), il faut # préalablement remettre ce pointeur à 0 @@ -289,11 +291,12 @@ Causes possibles : if e.isactif(): e.update_context(d) self.index_etape_courante=index_etape + message.debug(SUPERV, "returns %s", d.keys()) return d def supprime(self): """ - Méthode qui supprime toutes les références arrières afin que + Méthode qui supprime toutes les références arrières afin que l'objet puisse etre correctement détruit par le garbage collector """ N_MCCOMPO.MCCOMPO.supprime(self) @@ -318,7 +321,7 @@ Causes possibles : if not hasattr(co,'etape'): # Le concept vaut None probablement. On ignore l'appel return - # + # # On cherche a discriminer les differents cas de typage d'un concept # produit par une macro qui est specifie dans un mot cle simple. # On peut passer plusieurs fois par type_sdprod ce qui explique @@ -331,7 +334,7 @@ Causes possibles : # la propriete du concept de la macro parent a la macro courante (self) # en verifiant que le type est valide # Cas 4 : La concept est la propriete d'une etape fille. Ceci veut dire qu'on est - # deja passe par type_sdprod et que la propriete a ete transfere a une + # deja passe par type_sdprod et que la propriete a ete transfere a une # etape fille. Cas semblable a Cas 3. # Cas 5 : Le concept est produit par une etape externe a la macro. # @@ -341,24 +344,21 @@ Causes possibles : # Recherche du mot cle simple associe au concept mcs=self.get_mcs_with_co(co) if len(mcs) != 1: - raise AsException("""Erreur interne. + raise AsException("""Erreur interne. Il ne devrait y avoir qu'un seul mot cle porteur du concept CO (%s)""" % co) mcs=mcs[0] if not self.typeCO in mcs.definition.type: - raise AsException("""Erreur interne. + raise AsException("""Erreur interne. Impossible de changer le type du concept (%s). Le mot cle associe ne supporte pas CO mais seulement (%s)""" %(co,mcs.definition.type)) - co.etape=self + co.etape = self # affectation du bon type du concept et - # initialisation de sa partie "sd" - if CONTEXT.debug:print "changement de type:",co,t co.change_type(t) - self.sdprods.append(co) - elif co.etape== self: + elif co.etape == self: # Cas 2 : le concept est produit par la macro (self) # On est deja passe par type_sdprod (Cas 1 ou 3). - if co.etape==co._etape: + if co.etape == co._etape: #Le concept a été créé par la macro (self) #On peut changer son type co.change_type(t) @@ -366,7 +366,7 @@ Impossible de changer le type du concept (%s). Le mot cle associe ne supporte pa #Le concept a été créé par une macro parente # Le type du concept doit etre coherent avec le type demande (seulement derive) if not isinstance(co,t): - raise AsException("""Erreur interne. + raise AsException("""Erreur interne. Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co.__class__)) self.sdprods.append(co) @@ -375,7 +375,7 @@ Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co # Cas 3 : le concept est produit par la macro parente (self.parent) # on transfere la propriete du concept a la macro fille # et on change le type du concept comme demande - # Au prealable, on verifie que le concept existant (co) est une instance + # Au prealable, on verifie que le concept existant (co) est une instance # possible du type demande (t) # Cette règle est normalement cohérente avec les règles de vérification des mots-clés if not isinstance(co,t): @@ -384,11 +384,11 @@ Impossible de changer le type du concept produit (%s) en (%s). Le type actuel (%s) devrait etre une classe derivee du nouveau type (%s)""" % (co,t,co.__class__,t)) mcs=self.get_mcs_with_co(co) if len(mcs) != 1: - raise AsException("""Erreur interne. + raise AsException("""Erreur interne. Il ne devrait y avoir qu'un seul mot cle porteur du concept CO (%s)""" % co) mcs=mcs[0] if not self.typeCO in mcs.definition.type: - raise AsException("""Erreur interne. + raise AsException("""Erreur interne. Impossible de changer le type du concept (%s). Le mot cle associe ne supporte pas CO mais seulement (%s)""" %(co,mcs.definition.type)) co.etape=self # On ne change pas le type car il respecte la condition isinstance(co,t) @@ -396,13 +396,13 @@ Impossible de changer le type du concept (%s). Le mot cle associe ne supporte pa self.sdprods.append(co) elif self.issubstep(co.etape): - # Cas 4 : Le concept est propriété d'une sous etape de la macro (self). + # Cas 4 : Le concept est propriété d'une sous etape de la macro (self). # On est deja passe par type_sdprod (Cas 3 ou 1). # Il suffit de le mettre dans la liste des concepts produits (self.sdprods) - # Le type du concept et t doivent etre derives. + # Le type du concept et t doivent etre derives. # Il n'y a aucune raison pour que la condition ne soit pas verifiee. if not isinstance(co,t): - raise AsException("""Erreur interne. + raise AsException("""Erreur interne. Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co.__class__)) self.sdprods.append(co) @@ -412,7 +412,7 @@ Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co return def issubstep(self,etape): - """ + """ Cette methode retourne un entier indiquant si etape est une sous etape de la macro self ou non 1 = oui @@ -424,8 +424,8 @@ Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co return 0 def register(self,etape): - """ - Enregistrement de etape dans le contexte de la macro : liste etapes + """ + Enregistrement de etape dans le contexte de la macro : liste etapes et demande d enregistrement global aupres du JDC """ self.etapes.append(etape) @@ -434,7 +434,7 @@ Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co return idetape def reg_sd(self,sd): - """ + """ Methode appelee dans l __init__ d un ASSD a sa creation pour s enregistrer (reserve aux ASSD créés au sein d'une MACRO) """ @@ -442,7 +442,7 @@ Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co return self.jdc.o_register(sd) def create_sdprod(self,etape,nomsd): - """ + """ Cette methode doit fabriquer le concept produit retourne par l'etape etape et le nommer. @@ -479,19 +479,19 @@ Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co # est bien coherent avec celui initialement affecte par la macro (voir ci dessus) # on affecte au concept ce type car il peut etre plus precis (derive, en general) sd.__class__=sdprod - # On force également le nom stocké dans l'attribut sdnom : on lui donne le nom + # On force également le nom stocké dans l'attribut sdnom : on lui donne le nom # du concept associé à nomsd etape.sdnom=sd.nom elif etape.definition.reentrant != 'n' and etape.reuse != None: # On est dans le cas d'une commande avec reutilisation d'un concept existant - # get_sd_prod fait le necessaire : verifications, associations, etc. mais ne cree + # get_sd_prod fait le necessaire : verifications, associations, etc. mais ne cree # pas un nouveau concept. Il retourne le concept reutilise sd= etape.get_sd_prod() # Dans le cas d'un concept nomme automatiquement : _xxx, __xxx, - # On force le nom stocke dans l'attribut sdnom de l'objet etape : on lui donne le nom + # On force le nom stocke dans l'attribut sdnom de l'objet etape : on lui donne le nom # du concept reutilise (sd ou etape.reuse c'est pareil) # Ceci est indispensable pour eviter des erreurs lors des verifications des macros - # En effet une commande avec reutilisation d'un concept verifie que le nom de + # En effet une commande avec reutilisation d'un concept verifie que le nom de # la variable a gauche du signe = est le meme que celui du concept reutilise. # Lorsqu'une telle commande apparait dans une macro, on supprime cette verification. if (etape.sdnom == '' or etape.sdnom[0] == '_'): @@ -504,7 +504,7 @@ Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co return sd def NommerSdprod(self,sd,sdnom,restrict='non'): - """ + """ Cette methode est appelee par les etapes internes de la macro La macro appelle le JDC pour valider le nommage On considere que l espace de nom est unique et géré par le JDC @@ -518,16 +518,9 @@ Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co # est de verifier que le nom n'est pas deja attribue. Ceci est fait en delegant # au JDC par l'intermediaire du parent. - #XXX attention inconsistence : prefix et gcncon ne sont pas - # définis dans le package Noyau. La methode NommerSdprod pour + #XXX attention inconsistence : gcncon n'est pas + # défini dans le package Noyau. La methode NommerSdprod pour # les macros devrait peut etre etre déplacée dans Build ??? - - if CONTEXT.debug : print "MACRO.NommerSdprod: ",sd,sdnom - - if hasattr(self,'prefix'): - # Dans le cas de l'include_materiau on ajoute un prefixe au nom du concept - if sdnom != self.prefix:sdnom=self.prefix+sdnom - if self.Outputs.has_key(sdnom): # Il s'agit d'un concept de sortie de la macro produit par une sous commande sdnom=self.Outputs[sdnom].nom @@ -549,7 +542,7 @@ Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co else: sdnom=self.gcncon('_') else: - # On est dans le cas d'un nom de concept global. + # On est dans le cas d'un nom de concept global. pass if restrict == 'non': @@ -559,6 +552,7 @@ Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co # On ajoute dans le contexte de la macro les concepts nommes # Ceci est indispensable pour les CO (macro) dans un INCLUDE self.g_context[sdnom]=sd + message.debug(SUPERV, "g_context[%s] = %s", sdnom, sd) else: # La demande de nommage vient probablement d'une macro qui a mis # le concept dans son contexte. On ne traite plus que le nommage (restrict="oui") @@ -649,7 +643,9 @@ Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co Retourne le contexte tel qu'il est au moment de l'exécution de l'étape courante. """ - ctx = self.parent.get_contexte_courant(self) + ctx = {} + # update car par ricochet on modifierait jdc.current_context + ctx.update( self.parent.get_contexte_courant(self) ) # on peut mettre None car toujours en PAR_LOT='NON', donc la dernière ctx.update( self.get_contexte_avant(None) ) return ctx @@ -675,7 +671,7 @@ Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co return etape def copy_intern(self,etape): - """ Cette méthode effectue la recopie des etapes internes d'une macro + """ Cette méthode effectue la recopie des etapes internes d'une macro passée en argument (etape) """ self.etapes=[] @@ -695,7 +691,7 @@ Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co new_etp.copy_intern(etp) self.etapes.append(new_etp) self.index_etapes[new_etp] = len(self.etapes) - 1 - + def reset_jdc(self,new_jdc): """ @@ -731,8 +727,8 @@ Le type demande (%s) et le type du concept (%s) devraient etre derives""" %(t,co def sd_accessible(self): """On peut acceder aux "valeurs" (jeveux) des ASSD dans les macro-commandes qui sont localement en PAR_LOT="NON" - sauf pour INCLUDE et INCLUDE_MATERIAU. + sauf pour INCLUDE. """ if CONTEXT.debug: print ' `- MACRO sd_accessible :', self.nom - return self.parent.sd_accessible() or not self.nom.startswith('INCLUDE') + return self.parent.sd_accessible() or not self.is_include() diff --git a/Noyau/N_MCCOMPO.py b/Noyau/N_MCCOMPO.py index cca7f6fe..7092fd34 100644 --- a/Noyau/N_MCCOMPO.py +++ b/Noyau/N_MCCOMPO.py @@ -1,29 +1,29 @@ -#@ MODIF N_MCCOMPO Noyau DATE 07/09/2009 AUTEUR COURTOIS M.COURTOIS +#@ MODIF N_MCCOMPO Noyau DATE 30/08/2011 AUTEUR COURTOIS M.COURTOIS # -*- coding: iso-8859-1 -*- # RESPONSABLE COURTOIS M.COURTOIS # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== -# COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG +# COPYRIGHT (C) 1991 - 2011 EDF R&D WWW.CODE-ASTER.ORG # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY -# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR -# (AT YOUR OPTION) ANY LATER VERSION. +# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR +# (AT YOUR OPTION) ANY LATER VERSION. +# +# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT +# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF +# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU +# GENERAL PUBLIC LICENSE FOR MORE DETAILS. +# +# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE +# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, +# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. # -# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT -# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF -# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU -# GENERAL PUBLIC LICENSE FOR MORE DETAILS. # -# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE -# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, -# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. -# -# # ====================================================================== -""" - Ce module contient la classe MCCOMPO qui sert à factoriser les comportements +""" + Ce module contient la classe MCCOMPO qui sert à factoriser les comportements des OBJECT composites """ @@ -33,11 +33,11 @@ import N_OBJECT class MCCOMPO(N_OBJECT.OBJECT): """ Classe support d'un OBJECT composite - + """ def build_mc(self): - """ + """ Construit la liste des sous-entites du MCCOMPO à partir du dictionnaire des arguments (valeur) """ @@ -66,7 +66,7 @@ class MCCOMPO(N_OBJECT.OBJECT): # si une valeur existe dans args ou est obligatoire (generique si toutes les # entites ont l attribut statut ) # - objet=self.definition.entites[k](val=args.get(k,None),nom=k,parent=self) + objet=v(val=args.get(k,None),nom=k,parent=self) mc_liste.append(objet) # Si l'objet a une position globale on l'ajoute aux listes correspondantes if hasattr(objet.definition,'position'): @@ -77,7 +77,8 @@ class MCCOMPO(N_OBJECT.OBJECT): if args.has_key(k): del args[k] - # Phase 1.2 : on traite les autres entites que SIMP + # Phase 1.2 : on traite les autres entites que SIMP + # (FACT en fait car un BLOC ne peut avoir le meme nom qu'un mot-clef) for k,v in self.definition.entites.items(): if v.label == 'SIMP':continue if args.has_key(k) or v.statut=='o' : @@ -86,7 +87,7 @@ class MCCOMPO(N_OBJECT.OBJECT): # si une valeur existe dans args ou est obligatoire (generique si toutes les # entites ont l attribut statut ) # - objet=self.definition.entites[k](val=args.get(k,None),nom=k,parent=self) + objet=v(val=args.get(k,None),nom=k,parent=self) mc_liste.append(objet) if args.has_key(k): del args[k] @@ -116,7 +117,7 @@ class MCCOMPO(N_OBJECT.OBJECT): # On conserve les arguments superflus dans l'attribut reste_val self.reste_val=args - # On ordonne la liste ainsi créée suivant l'ordre du catalogue + # On ordonne la liste ainsi créée suivant l'ordre du catalogue # (utile seulement pour IHM graphique) mc_liste = self.ordonne_liste(mc_liste) # on retourne la liste ainsi construite @@ -135,28 +136,28 @@ class MCCOMPO(N_OBJECT.OBJECT): return mc_liste def cree_dict_valeurs(self,liste=[],condition=0): - """ + """ Cette méthode crée un contexte (sous la forme d'un dictionnaire) à partir des valeurs des mots clés contenus dans l'argument liste. - L'opération consiste à parcourir la liste (d'OBJECT) et à la + L'opération consiste à parcourir la liste (d'OBJECT) et à la transformer en un dictionnaire dont les clés sont les noms des mots clés et les valeurs dépendent du type d'OBJECT. Ce dictionnaire servira de liste d'arguments d'appel pour les fonctions sd_prod de commandes et ops de macros ou de contexte d'évaluation des conditions de présence de BLOC. - Si l'argument condition de la méthode vaut 1, on ne + Si l'argument condition de la méthode vaut 1, on ne remonte pas les valeurs des mots clés contenus dans des blocs pour eviter les bouclages. - Cette méthode réalise les opérations suivantes en plus de transformer + Cette méthode réalise les opérations suivantes en plus de transformer la liste en dictionnaire : - ajouter tous les mots-clés non présents avec la valeur None - - ajouter tous les mots-clés globaux (attribut position = 'global' + - ajouter tous les mots-clés globaux (attribut position = 'global' et 'global_jdc') - L'argument liste est, en général, une mc_liste en cours de + L'argument liste est, en général, une mc_liste en cours de construction, contenant les mots-clés locaux et les blocs déjà créés. """ @@ -167,16 +168,22 @@ class MCCOMPO(N_OBJECT.OBJECT): # représentatif du contexte. Les blocs sont retournés par get_valeur # sous la forme d'un dictionnaire : les mots-clés fils de blocs sont # donc remontés au niveau du contexte. - if not condition:dico.update(v.get_valeur()) + if not condition: + dadd = v.get_valeur() + assert intersection_vide(dico, dadd) + dico.update(dadd) else: + assert not dico.has_key(v.nom), "deja vu : %s" % v.nom dico[v.nom]=v.get_valeur() - # On rajoute tous les autres mots-clés locaux possibles avec la valeur + # On rajoute tous les autres mots-clés locaux possibles avec la valeur # par défaut ou None # Pour les mots-clés facteurs, on ne traite que ceux avec statut défaut ('d') # et caché ('c') # On n'ajoute aucune information sur les blocs. Ils n'ont pas de défaut seulement # une condition. + #XXX remplacer le not has_key par un dico différent et faire dico2.update(dico) + # ce n'est qu'un pb de perf for k,v in self.definition.entites.items(): if not dico.has_key(k): if v.label == 'SIMP': @@ -215,7 +222,7 @@ class MCCOMPO(N_OBJECT.OBJECT): return dico def recherche_mc_globaux(self): - """ + """ Retourne la liste des mots-clés globaux de l'étape à laquelle appartient self et des mots-clés globaux du jdc """ @@ -224,7 +231,7 @@ class MCCOMPO(N_OBJECT.OBJECT): dict_mc_globaux_fac = self.recherche_mc_globaux_facultatifs() for k,v in etape.mc_globaux.items(): dict_mc_globaux_fac[k]=v.get_valeur() - if self.jdc : + if self.jdc : for k,v in self.jdc.mc_globaux.items(): dict_mc_globaux_fac[k]=v.get_valeur() return dict_mc_globaux_fac @@ -232,9 +239,10 @@ class MCCOMPO(N_OBJECT.OBJECT): return {} def recherche_mc_globaux_facultatifs(self): - """ + """ Cette méthode interroge la définition de self et retourne la liste des mots-clés fils - directs de self de type 'global' + directs de self de type 'global'. + position='global' n'est donc possible (et n'a de sens) qu'au plus haut niveau. """ dico={} etape = self.get_etape() @@ -248,7 +256,7 @@ class MCCOMPO(N_OBJECT.OBJECT): return dico def supprime(self): - """ + """ Méthode qui supprime toutes les références arrières afin que l'objet puisse etre correctement détruit par le garbage collector """ @@ -264,8 +272,8 @@ class MCCOMPO(N_OBJECT.OBJECT): def get_mocle(self,key): """ - Retourne la valeur du sous mot-clé key - Ce sous mot-clé peut exister, avoir une valeur par defaut ou etre + Retourne la valeur du sous mot-clé key + Ce sous mot-clé peut exister, avoir une valeur par defaut ou etre dans un BLOC fils de self """ # on cherche dans les mots cles presents, le mot cle de nom key @@ -297,7 +305,7 @@ class MCCOMPO(N_OBJECT.OBJECT): if not mc.isBLOC() : continue try: return mc.get_mocle(key) - except: + except: # On n a rien trouve dans ce bloc, on passe au suivant pass # On a rien trouve, le mot cle est absent. @@ -305,10 +313,10 @@ class MCCOMPO(N_OBJECT.OBJECT): raise IndexError,"Le mot cle %s n existe pas dans %s" % (key,self) def get_child(self,name,restreint = 'non'): - """ + """ Retourne le fils de self de nom name ou None s'il n'existe pas Si restreint vaut oui : ne regarde que dans la mc_liste - Si restreint vaut non : regarde aussi dans les entites possibles + Si restreint vaut non : regarde aussi dans les entites possibles avec defaut (Ce dernier cas n'est utilisé que dans le catalogue) """ for v in self.mc_liste: @@ -333,8 +341,8 @@ class MCCOMPO(N_OBJECT.OBJECT): etape.mc_globaux[nom]=mc def append_mc_global_jdc(self,mc): - """ - Ajoute le mot-clé mc à la liste des mots-clés globaux du jdc + """ + Ajoute le mot-clé mc à la liste des mots-clés globaux du jdc """ nom = mc.nom self.jdc.mc_globaux[nom]=mc @@ -368,9 +376,9 @@ class MCCOMPO(N_OBJECT.OBJECT): mocle.reparent(self) def get_sd_utilisees(self): - """ + """ Retourne la liste des concepts qui sont utilisés à l'intérieur de self - ( comme valorisation d'un MCS) + ( comme valorisation d'un MCS) """ l=[] for child in self.mc_liste: @@ -378,13 +386,13 @@ class MCCOMPO(N_OBJECT.OBJECT): return l def get_sd_mcs_utilisees(self): - """ + """ Retourne la ou les SD utilisée par self sous forme d'un dictionnaire : - Si aucune sd n'est utilisée, le dictionnaire est vide. - Sinon, les clés du dictionnaire sont les mots-clés derrière lesquels on trouve des sd ; la valeur est la liste des sd attenante. Exemple :: - + { 'VALE_F': [ , ], 'MODELE': [] } @@ -399,7 +407,7 @@ class MCCOMPO(N_OBJECT.OBJECT): def get_mcs_with_co(self,co): """ - Cette methode retourne l'objet MCSIMP fils de self + Cette methode retourne l'objet MCSIMP fils de self qui a le concept co comme valeur. En principe, elle ne doit etre utilisee que pour les concepts instances de la classe CO @@ -417,3 +425,14 @@ class MCCOMPO(N_OBJECT.OBJECT): for child in self.mc_liste: l.extend(child.get_all_co()) return l + + +def intersection_vide(dict1, dict2): + """Verification qu'il n'y a pas de clé commune entre 'dict1' et 'dict2'.""" + sk1 = set(dict1.keys()) + sk2 = set(dict2.keys()) + inter = sk1.intersection(sk2) + ok = len(inter) == 0 + if not ok: + print 'ERREUR: Mot(s)-clef(s) vu(s) plusieurs fois :', tuple(inter) + return ok diff --git a/Noyau/N_MCSIMP.py b/Noyau/N_MCSIMP.py index ba769bbd..2ff4d1f9 100644 --- a/Noyau/N_MCSIMP.py +++ b/Noyau/N_MCSIMP.py @@ -1,36 +1,36 @@ -#@ MODIF N_MCSIMP Noyau DATE 07/09/2009 AUTEUR COURTOIS M.COURTOIS +#@ MODIF N_MCSIMP Noyau DATE 30/08/2011 AUTEUR COURTOIS M.COURTOIS # -*- coding: iso-8859-1 -*- # RESPONSABLE COURTOIS M.COURTOIS # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== -# COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG +# COPYRIGHT (C) 1991 - 2011 EDF R&D WWW.CODE-ASTER.ORG # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY -# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR -# (AT YOUR OPTION) ANY LATER VERSION. +# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR +# (AT YOUR OPTION) ANY LATER VERSION. +# +# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT +# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF +# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU +# GENERAL PUBLIC LICENSE FOR MORE DETAILS. +# +# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE +# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, +# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. # -# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT -# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF -# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU -# GENERAL PUBLIC LICENSE FOR MORE DETAILS. # -# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE -# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, -# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. -# -# # ====================================================================== -""" - Ce module contient la classe MCSIMP qui sert à controler la valeur - d'un mot-clé simple par rapport à sa définition portée par un objet +""" + Ce module contient la classe MCSIMP qui sert a controler la valeur + d'un mot-cle simple par rapport a sa definition portee par un objet de type ENTITE """ from copy import copy -from Noyau.N_ASSD import ASSD,assd +from Noyau.N_ASSD import ASSD from Noyau.N_CO import CO import N_OBJECT from N_CONVERT import ConversionFactory @@ -42,18 +42,13 @@ class MCSIMP(N_OBJECT.OBJECT): def __init__(self,val,definition,nom,parent): """ Attributs : - - - val : valeur du mot clé simple - + - val : valeur du mot cle simple - definition - - nom - - parent - Autres attributs : - - valeur : valeur du mot-clé simple en tenant compte de la valeur par défaut + - valeur : valeur du mot-cle simple en tenant compte de la valeur par defaut """ self.definition=definition @@ -67,15 +62,15 @@ class MCSIMP(N_OBJECT.OBJECT): self.niveau = self.parent.niveau self.etape = self.parent.etape else: - # Le mot cle simple a été créé sans parent + # Le mot cle simple a ete cree sans parent self.jdc = None self.niveau = None self.etape = None def GETVAL(self,val): - """ - Retourne la valeur effective du mot-clé en fonction - de la valeur donnée. Defaut si val == None + """ + Retourne la valeur effective du mot-cle en fonction + de la valeur donnee. Defaut si val == None """ if (val is None and hasattr(self.definition,'defaut')) : val = self.definition.defaut @@ -85,22 +80,32 @@ class MCSIMP(N_OBJECT.OBJECT): def get_valeur(self): """ - Retourne la "valeur" d'un mot-clé simple. - Cette valeur est utilisée lors de la création d'un contexte - d'évaluation d'expressions à l'aide d'un interpréteur Python + Retourne la "valeur" d'un mot-cle simple. + Cette valeur est utilisee lors de la creation d'un contexte + d'evaluation d'expressions a l'aide d'un interpreteur Python """ v = self.valeur - # Singleton : on retourne l'element - # Permet aussi d'ignorer l'erreur : concept=COMMANDE(), - # ou 'concept' est un tuple de longueur 1 a cause de la virgule. - if type(v) in (list, tuple) and len(v) == 1: + # Si singleton et max=1, on retourne la valeur. + # Si une valeur simple et max='**', on retourne un singleton. + # (si liste de longueur > 1 et max=1, on sera arrete plus tard) + # Pour accepter les numpy.array, on remplace : "type(v) not in (list, tuple)" + # par "not has_attr(v, '__iter__')". + if v is None: + pass + elif type(v) in (list, tuple) and len(v) == 1 and self.definition.max == 1: v = v[0] + elif not hasattr(v, '__iter__') and self.definition.max != 1: + v = (v, ) + # traitement particulier pour les complexes ('RI', r, i) + if 'C' in self.definition.type and self.definition.max != 1 \ + and v[0] in ('RI', 'MP'): + v = (v, ) return v def get_val(self): """ - Une autre méthode qui retourne une "autre" valeur du mot clé simple. - Elle est utilisée par la méthode get_mocle + Une autre methode qui retourne une "autre" valeur du mot cle simple. + Elle est utilisee par la methode get_mocle """ return self.valeur @@ -115,7 +120,7 @@ class MCSIMP(N_OBJECT.OBJECT): """ 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,...) + # possibles (reel,SD,...) if type(self.valeur) in (list, tuple): objet.valeur = copy(self.valeur) else: @@ -135,8 +140,8 @@ class MCSIMP(N_OBJECT.OBJECT): self.etape=parent.etape def get_sd_utilisees(self): - """ - Retourne une liste qui contient la ou les SD utilisée par self si c'est le cas + """ + Retourne une liste qui contient la ou les SD utilisee par self si c'est le cas ou alors une liste vide """ l=[] @@ -149,10 +154,10 @@ class MCSIMP(N_OBJECT.OBJECT): return l def get_sd_mcs_utilisees(self): - """ - Retourne la ou les SD utilisée par self sous forme d'un dictionnaire : - - Si aucune sd n'est utilisée, le dictionnaire est vide. - - Sinon, la clé du dictionnaire est le mot-clé simple ; la valeur est + """ + Retourne la ou les SD utilisee par self sous forme d'un dictionnaire : + - Si aucune sd n'est utilisee, le dictionnaire est vide. + - Sinon, la cle du dictionnaire est le mot-cle simple ; la valeur est la liste des sd attenante. Exemple :: @@ -179,7 +184,7 @@ class MCSIMP(N_OBJECT.OBJECT): def get_all_co(self): """ Cette methode retourne la liste de tous les concepts co - associés au mot cle simple + associes au mot cle simple """ lval=self.valeur if type(self.valeur) not in (list, tuple): diff --git a/Noyau/N_OPER.py b/Noyau/N_OPER.py index 7f2d1ffc..648d9b05 100644 --- a/Noyau/N_OPER.py +++ b/Noyau/N_OPER.py @@ -1,28 +1,28 @@ -#@ MODIF N_OPER Noyau DATE 07/09/2009 AUTEUR COURTOIS M.COURTOIS +#@ MODIF N_OPER Noyau DATE 30/08/2011 AUTEUR COURTOIS M.COURTOIS # -*- coding: iso-8859-1 -*- # RESPONSABLE COURTOIS M.COURTOIS # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== -# COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG +# COPYRIGHT (C) 1991 - 2011 EDF R&D WWW.CODE-ASTER.ORG # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY -# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR -# (AT YOUR OPTION) ANY LATER VERSION. +# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR +# (AT YOUR OPTION) ANY LATER VERSION. +# +# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT +# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF +# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU +# GENERAL PUBLIC LICENSE FOR MORE DETAILS. +# +# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE +# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, +# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. # -# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT -# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF -# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU -# GENERAL PUBLIC LICENSE FOR MORE DETAILS. # -# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE -# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, -# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. -# -# # ====================================================================== -""" +""" Ce module contient la classe de definition OPER qui permet de spécifier les caractéristiques d'un opérateur """ @@ -37,10 +37,10 @@ class OPER(N_ENTITE.ENTITE): """ Classe pour definir un opérateur - Cette classe a trois attributs de classe + Cette classe a trois attributs de classe - - class_instance qui indique la classe qui devra etre utilisée - pour créer l'objet qui servira à controler la conformité d'un + - class_instance qui indique la classe qui devra etre utilisée + pour créer l'objet qui servira à controler la conformité d'un opérateur avec sa définition - label qui indique la nature de l'objet de définition (ici, OPER) @@ -118,6 +118,7 @@ class OPER(N_ENTITE.ENTITE): self.niveau.enregistre(self) self.UIinfo=UIinfo self.affecter_parente() + self.check_definition(self.nom) def __call__(self,reuse=None,**args): """ @@ -130,10 +131,10 @@ class OPER(N_ENTITE.ENTITE): return etape.Build_sd(nomsd) def make_objet(self,mc_list='oui'): - """ + """ Cette méthode crée l'objet ETAPE dont la définition est self sans l'enregistrer ni créer sa sdprod. - Si l'argument mc_list vaut 'oui', elle déclenche en plus la construction + Si l'argument mc_list vaut 'oui', elle déclenche en plus la construction des objets MCxxx. """ etape= self.class_instance(oper=self,reuse=None,args={}) diff --git a/Noyau/N_OPS.py b/Noyau/N_OPS.py new file mode 100644 index 00000000..6d537097 --- /dev/null +++ b/Noyau/N_OPS.py @@ -0,0 +1,45 @@ +#@ MODIF N_OPS Noyau DATE 17/08/2011 AUTEUR COURTOIS M.COURTOIS +# -*- coding: iso-8859-1 -*- +# CONFIGURATION MANAGEMENT OF EDF VERSION +# ====================================================================== +# COPYRIGHT (C) 1991 - 2011 EDF R&D WWW.CODE-ASTER.ORG +# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY +# IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY +# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR +# (AT YOUR OPTION) ANY LATER VERSION. +# +# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT +# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF +# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU +# GENERAL PUBLIC LICENSE FOR MORE DETAILS. +# +# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE +# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, +# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. +# ====================================================================== + +from N_utils import import_object + +class OPS: + """Wrapper to ops functions. + This allows to import them only when they are needed.""" + + def __init__(self, uri): + """Initialization""" + self.uri = uri + + def __call__(self, *args, **kwargs): + """Import the real function and call it.""" + func = import_object(self.uri) + return func(*args, **kwargs) + + +# utilisé par exemple par des macros où tout est fait dans l'init. +class NOTHING(OPS): + """OPS which does nothing.""" + + def __call__(self, macro, *args, **kwargs): + macro.set_icmd(1) + return 0 + +EMPTY_OPS = NOTHING(None) diff --git a/Noyau/N_PROC.py b/Noyau/N_PROC.py index c19db8b4..ccef6948 100644 --- a/Noyau/N_PROC.py +++ b/Noyau/N_PROC.py @@ -1,28 +1,28 @@ -#@ MODIF N_PROC Noyau DATE 07/09/2009 AUTEUR COURTOIS M.COURTOIS +#@ MODIF N_PROC Noyau DATE 30/08/2011 AUTEUR COURTOIS M.COURTOIS # -*- coding: iso-8859-1 -*- # RESPONSABLE COURTOIS M.COURTOIS # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== -# COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG +# COPYRIGHT (C) 1991 - 2011 EDF R&D WWW.CODE-ASTER.ORG # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY -# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR -# (AT YOUR OPTION) ANY LATER VERSION. +# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR +# (AT YOUR OPTION) ANY LATER VERSION. +# +# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT +# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF +# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU +# GENERAL PUBLIC LICENSE FOR MORE DETAILS. +# +# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE +# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, +# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. # -# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT -# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF -# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU -# GENERAL PUBLIC LICENSE FOR MORE DETAILS. # -# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE -# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, -# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. -# -# # ====================================================================== -""" +""" Ce module contient la classe de definition PROC qui permet de spécifier les caractéristiques d'une procédure """ @@ -36,10 +36,10 @@ class PROC(N_ENTITE.ENTITE): """ Classe pour definir un opérateur - Cette classe a deux attributs de classe + Cette classe a deux attributs de classe - - class_instance qui indique la classe qui devra etre utilisée - pour créer l'objet qui servira à controler la conformité d'un + - class_instance qui indique la classe qui devra etre utilisée + pour créer l'objet qui servira à controler la conformité d'un opérateur avec sa définition - label qui indique la nature de l'objet de définition (ici, PROC) @@ -111,6 +111,7 @@ class PROC(N_ENTITE.ENTITE): self.niveau.enregistre(self) self.UIinfo=UIinfo self.affecter_parente() + self.check_definition(self.nom) def __call__(self,**args): """ diff --git a/Noyau/N_SIMP.py b/Noyau/N_SIMP.py index 6125a1ce..35a35712 100644 --- a/Noyau/N_SIMP.py +++ b/Noyau/N_SIMP.py @@ -37,9 +37,9 @@ class SIMP(N_ENTITE.ENTITE): Cette classe a deux attributs de classe - - class_instance qui indique la classe qui devra etre utilisée - pour créer l'objet qui servira à controler la conformité d'un - mot-clé simple avec sa définition + - class_instance qui indique la classe qui devra etre utilisee + pour creer l'objet qui servira a controler la conformite d'un + mot-cle simple avec sa définition - label qui indique la nature de l'objet de définition (ici, SIMP) @@ -49,14 +49,12 @@ class SIMP(N_ENTITE.ENTITE): def __init__(self,typ,fr="",ang="",statut='f',into=None,defaut=None, min=1,max=1,homo=1,position ='local', - val_min = '**',val_max='**',docu="",validators=None, - equiv=None,cache=0): + val_min = '**',val_max='**',docu="",validators=None): """ - Un mot-clé simple est caractérisé par les attributs suivants : + Un mot-cle simple est caracterise par les attributs suivants : - type : cet attribut est obligatoire et indique le type de valeur attendue - - fr : - ang : - statut : @@ -88,12 +86,10 @@ class SIMP(N_ENTITE.ENTITE): self.val_min=val_min self.val_max=val_max self.docu = docu - self.equiv=equiv - self.cache=cache def verif_cata(self): """ - Cette methode sert à valider les attributs de l'objet de définition + Cette methode sert a valider les attributs de l'objet de definition de la classe SIMP """ if type(self.min) != types.IntType : @@ -126,7 +122,3 @@ class SIMP(N_ENTITE.ENTITE): return self.class_instance(nom=nom,definition=self,val=val,parent=parent) - - - - diff --git a/Noyau/N__F.py b/Noyau/N__F.py index 6e1ba89d..78789894 100644 --- a/Noyau/N__F.py +++ b/Noyau/N__F.py @@ -1,24 +1,24 @@ -#@ MODIF N__F Noyau DATE 11/10/2010 AUTEUR COURTOIS M.COURTOIS +#@ MODIF N__F Noyau DATE 28/06/2011 AUTEUR COURTOIS M.COURTOIS # -*- coding: iso-8859-1 -*- # RESPONSABLE COURTOIS M.COURTOIS # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== -# COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG +# COPYRIGHT (C) 1991 - 2011 EDF R&D WWW.CODE-ASTER.ORG # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY -# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR -# (AT YOUR OPTION) ANY LATER VERSION. +# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR +# (AT YOUR OPTION) ANY LATER VERSION. +# +# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT +# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF +# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU +# GENERAL PUBLIC LICENSE FOR MORE DETAILS. +# +# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE +# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, +# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. # -# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT -# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF -# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU -# GENERAL PUBLIC LICENSE FOR MORE DETAILS. # -# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE -# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, -# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. -# -# # ====================================================================== @@ -26,13 +26,16 @@ import UserDict class _F(UserDict.UserDict): """ - Cette classe a un comportement semblable à un + Cette classe a un comportement semblable à un dictionnaire Python et permet de donner - la valeur d'un mot-clé facteur avec pour les sous + la valeur d'un mot-clé facteur avec pour les sous mots-clés la syntaxe motcle=valeur """ - def __init__(self,**args): + def __init__(self, *pos, **args): + if len(pos) != 0: + raise SyntaxError("Valeur invalide pour '_F('. "\ + "On attend cette syntaxe : _F(MOTCLE=valeur, ...)") self.data=args def supprime(self): diff --git a/Noyau/N_info.py b/Noyau/N_info.py new file mode 100644 index 00000000..59a66217 --- /dev/null +++ b/Noyau/N_info.py @@ -0,0 +1,269 @@ +#@ MODIF N_info Noyau DATE 17/08/2011 AUTEUR COURTOIS M.COURTOIS +# -*- coding: iso-8859-1 -*- +# CONFIGURATION MANAGEMENT OF EDF VERSION +# ====================================================================== +# COPYRIGHT (C) 1991 - 2011 EDF R&D WWW.CODE-ASTER.ORG +# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY +# IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY +# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR +# (AT YOUR OPTION) ANY LATER VERSION. +# +# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT +# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF +# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU +# GENERAL PUBLIC LICENSE FOR MORE DETAILS. +# +# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE +# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, +# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. +# ====================================================================== +# RESPONSABLE COURTOIS M.COURTOIS + +"""Module to manage information printing : debug, info, error. +Should replace 'print' and 'UTMESS' calls at least in the supervisor +modules. +Only used for debug right now. +""" + +import os +import os.path as osp +import re +import traceback +from functools import partial +from subprocess import Popen, PIPE + +from N_utils import Enum + +def default_print(text): + """Basic print function.""" + print text + +LEVEL = Enum( + 'DEBUG', + 'INFO', + 'WARN', + 'ERROR' +) + +class Category(object): + """Define a category of message for different parts of the code. + This allows to store different parameters for each category of message.""" + def __init__(self): + self._level = LEVEL.INFO + self._fmt = "%-8s" + self._header = { + LEVEL.DEBUG : "DEBUG", + LEVEL.INFO : None, + LEVEL.WARN : "WARNING", + LEVEL.ERROR : "ERROR", + } + + def set_level(self, level): + """Set the current level.""" + self._level = level + + def get_level(self): + """Return the current level.""" + return self._level + + def set_header(self, level, header): + """Set the header of ``level`` messages.""" + self._header[level] = header + + def get_header(self, level): + """Return the header at this ``level``.""" + header = self._header.get(level, "") + if header: + header = self._fmt % header + return header + + def active(self, level): + """Tell if a message should be print at this ``level``.""" + return self._level <= level + + +ALL = Category() +SUPERV = Category() +SUPERV.set_header(LEVEL.ERROR, None) +MISS = Category() + +REGEXP_ORIG = re.compile('File [\'\"]*(.*?)[\'\"]*, *line ([0-9]+), *in (.*)') + +# slighty different and very simplier than logger objects +# from the logging module. +class InfoLevel(object): + """Store informations level.""" + def __init__(self, level): + """Initialization""" + self._parts = [] + for part in self._parts: + part.level = level + self.reset_print_function() + self._msg_callback = [] + #self.extend_message(ALL, stack_header_callback) + self.extend_message(ALL, insert_header) + + def add(self, category): + """Add a category of message.""" + self._parts.append(category) + + def set_level(self, category, level): + """Set the current level for ``category``.""" + assert category in self._parts, "unknown category : %s" % category + assert LEVEL.exists(level), "unknown level : %s" % level + category.set_level(level) + if category == ALL: + for part in self._parts: + part.set_level(level) + + def set_debug(self): + """Set debug level for all categories.""" + self.set_level(ALL, LEVEL.DEBUG) + + def set_header(self, category, level, header): + """Set the header of ``level`` messages.""" + category.set_header(level, header) + + def register_print_function(self, print_function): + """Define the `print_function` to use.""" + self._print = print_function + + def reset_print_function(self): + """Register the default 'print function'.""" + self._print = default_print + + def extend_message(self, category, callback): + """Allow to extend the message calling an external function.""" + self._msg_callback.append((category, callback)) + + def _message(self, category, level, msg, args, kwargs): + """Print the message if the level is reached.""" + if category.active(level): + if kwargs.get('utmess'): + func = self._message_utmess + else: + func = self._message_print + func = self._message_print + apply(func, (category, level, msg, args, kwargs)) + + def _message_print(self, category, level, msg, args, kwargs): + """Print the message if the level is reached.""" + for cat, cbk in self._msg_callback: + if cat in (ALL, category): + msg, args = cbk(category, level, msg, args, kwargs) + if len(args) > 0: + try: + msg = msg % args + except Exception, err: + msg = repr((msg, args, err)) + self._print(msg) + + def _message_utmess(self, category, level, msg, args, kwargs): + """Print the message if the level is reached.""" + # how to use callbacks ? valk ? + from Utilitai.Utmess import MessageLog + code = { + LEVEL.DEBUG : 'I', + LEVEL.INFO : 'I', + LEVEL.WARN : 'A', + LEVEL.ERROR : 'F', + } + valk = kwargs.get('valk', ()) + vali = kwargs.get('vali', ()) + valr = kwargs.get('valr', ()) + msg = MessageLog.GetText(code[level], msg, valk, vali, valr) + for cat, cbk in self._msg_callback: + if cat in (ALL, category): + msg, args = cbk(category, level, msg, args, kwargs) + self._print(msg) + + def debug(self, category, msg, *args, **kwargs): + """Print a debug message.""" + self._message(category or ALL, LEVEL.DEBUG, msg, args, kwargs) + + def info(self, category, msg, *args, **kwargs): + """Print an information message.""" + self._message(category or ALL, LEVEL.INFO, msg, args, kwargs) + + def warn(self, category, msg, *args, **kwargs): + """Print a warning message.""" + self._message(category or ALL, LEVEL.WARN, msg, args, kwargs) + + def error(self, category, msg, *args, **kwargs): + """Print an error message.""" + self._message(category or ALL, LEVEL.ERROR, msg, args, kwargs) + + critical = error + + def add_memory_info(self, category): + """Shortcut to add memory informations.""" + self.extend_message(category, mem_msg_callback) + + def use_aster_print(self): + """Shortcut to use aster.affiche function to print the messages.""" + import aster + self.register_print_function(partial(aster.affiche, 'MESSAGE')) + + +# defined extensions +def insert_header(category, level, msg, args, kwargs): + """Insert the header.""" + header = category.get_header(level) + if header: + msg = header + msg + return msg, args + +def stack_header_callback(category, level, msg, args, kwargs): + """To insert the origin.""" + if level <= LEVEL.DEBUG: + stack_id = -5 + kwargs.get('stack_id', 0) + stack = traceback.format_stack(limit=10)[stack_id] + mat = REGEXP_ORIG.search(stack) + origin = '[%s:%s in %s] ' % (osp.basename(mat.group(1)), mat.group(2), mat.group(3)) + msg = origin + msg + return msg, args + + +# objet singleton +message = InfoLevel(LEVEL.INFO) +message.add(ALL) +message.add(SUPERV) +message.add(MISS) + +# callback to add memory information +_pid = os.getpid() + +RE_VMPEAK = re.compile('VmPeak:\s*([0-9]+)\s*([kMGBo]+)', re.M | re.I) + +def memory_used(pid): + """Return the current VmPeak value.""" + p = Popen(['cat', '/proc/%s/status' % pid], stdout=PIPE) + output = p.communicate()[0] + mat = RE_VMPEAK.search(output) + return int(mat.group(1)) / 1024. + +current_memory_used = partial(memory_used, _pid) + +def mem_msg_callback(category, level, msg, args, kwargs): + """Callback to add memory infos to message.""" + if level <= LEVEL.DEBUG: + msg = msg + " - VmPeak : %.2f Mo" + args = tuple(list(args) + [current_memory_used(), ]) + return msg, args + + +if __name__ == "__main__": + message.set_level(SUPERV, LEVEL.WARN) + message.set_level(MISS, LEVEL.DEBUG) + message.debug(None, "debug message") + message.info(ALL, "information message") + message.warn(None, "warning message") + message.error(ALL, "error message") + message.add_memory_info() + message.debug(MISS, "debug supervisor message") + message.info(SUPERV, "information supervisor message") + message.warn(SUPERV, "warning supervisor message") + message.error(SUPERV, "error supervisor message") + message.critical(MISS, "test the critical alias") + + diff --git a/Noyau/N_types.py b/Noyau/N_types.py index 8fd7305f..3a5c0358 100644 --- a/Noyau/N_types.py +++ b/Noyau/N_types.py @@ -1,4 +1,4 @@ -#@ MODIF N_types Noyau DATE 14/03/2011 AUTEUR COURTOIS M.COURTOIS +#@ MODIF N_types Noyau DATE 28/06/2011 AUTEUR COURTOIS M.COURTOIS # -*- coding: iso-8859-1 -*- # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== @@ -23,8 +23,6 @@ Ce module contient des fonctions utilitaires pour tester les types """ -from N_ASSD import ASSD - # use isinstance() instead of type() because objects returned from numpy arrays # inherit from python scalars but are numpy.float64 or numpy.int32... @@ -56,6 +54,7 @@ def is_enum(obj): return is_list(obj) or is_tuple(obj) def is_assd(obj): + from N_ASSD import ASSD return isinstance(obj, ASSD) diff --git a/Noyau/N_utils.py b/Noyau/N_utils.py index 50198669..4641ee64 100644 --- a/Noyau/N_utils.py +++ b/Noyau/N_utils.py @@ -1,24 +1,22 @@ -#@ MODIF N_utils Noyau DATE 11/05/2010 AUTEUR COURTOIS M.COURTOIS +#@ MODIF N_utils Noyau DATE 28/06/2011 AUTEUR COURTOIS M.COURTOIS # -*- coding: iso-8859-1 -*- # RESPONSABLE COURTOIS M.COURTOIS # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== -# COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG +# COPYRIGHT (C) 1991 - 2011 EDF R&D WWW.CODE-ASTER.ORG # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY -# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR -# (AT YOUR OPTION) ANY LATER VERSION. +# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR +# (AT YOUR OPTION) ANY LATER VERSION. # -# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT -# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF -# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU -# GENERAL PUBLIC LICENSE FOR MORE DETAILS. +# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT +# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF +# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU +# GENERAL PUBLIC LICENSE FOR MORE DETAILS. # -# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE -# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, -# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. -# -# +# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE +# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, +# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. # ====================================================================== @@ -36,11 +34,11 @@ from N_types import is_int, is_float, is_complex, is_str, is_enum, is_assd SEP='_' try: - # Si la version de Python possède la fonction _getframe + # Si la version de Python possede la fonction _getframe # on l'utilise. cur_frame=sys._getframe except: - # Sinon on l'émule + # Sinon on l'emule def cur_frame(offset=0): """ Retourne la frame d execution effective eventuellement en remontant de offset niveaux dans la pile d execution @@ -57,8 +55,8 @@ except: def callee_where(niveau=4): - """ - recupere la position de l appel + """ + recupere la position de l appel """ frame=cur_frame(niveau) if frame == None: return 0,"inconnu",0,{} @@ -71,7 +69,7 @@ def callee_where(niveau=4): def AsType(a): """ Retourne le type d'un concept (a) à partir - des caractéristiques de l'objet Python + des caracteristiques de l'objet Python """ if is_enum(a): return AsType(a[0]) if is_assd(a): return type(a) @@ -90,9 +88,9 @@ def prbanner(s): def repr_float(valeur): - """ - Cette fonction représente le réel valeur comme une chaine de caractères - sous forme mantisse exposant si nécessaire cad si le nombre contient plus de + """ + Cette fonction represente le reel valeur comme une chaine de caracteres + sous forme mantisse exposant si necessaire cad si le nombre contient plus de 5 caractères NB : valeur est un réel au format Python ou une chaine de caractères représentant un réel """ @@ -151,3 +149,49 @@ def repr_float(valeur): s=s+'E'+neg*'-'+repr(cpt) return s + +def import_object(uri): + """Load and return a python object (class, function...). + Its `uri` looks like "mainpkg.subpkg.module.object", this means + that "mainpkg.subpkg.module" is imported and "object" is + the object to return. + """ + path = uri.split('.') + modname = '.'.join(path[:-1]) + if len(modname) == 0: + raise ImportError(u"invalid uri: %s" % uri) + mod = object = '?' + objname = path[-1] + try: + __import__(modname) + mod = sys.modules[modname] + except ImportError, err: + raise ImportError(u"can not import module : %s (%s)" % (modname, str(err))) + try: + object = getattr(mod, objname) + except AttributeError, err: + raise AttributeError(u"object (%s) not found in module '%s'. " + "Module content is: %s" % (objname, modname, tuple(dir(mod)))) + return object + + +class Enum(object): + """ + This class emulates a C-like enum for python. It is initialized with a list + of strings to be used as the enum symbolic keys. The enum values are automatically + generated as sequencing integer starting at 0. + """ + def __init__(self, *keys): + """Constructor""" + self._dict_keys = {} + for inum, key in enumerate(keys): + setattr(self, key, 2**inum) + self._dict_keys[2**inum] = key + + def exists(self, value): + """Tell if value is in the enumeration""" + return self.get_id(value) is not None + + def get_id(self, value): + """Return the key associated to the given value""" + return self._dict_keys.get(value, None) diff --git a/Noyau/asojb.py b/Noyau/asojb.py index a5f2fc99..8b0176cb 100644 --- a/Noyau/asojb.py +++ b/Noyau/asojb.py @@ -1,9 +1,9 @@ -#@ MODIF asojb Noyau DATE 21/09/2009 AUTEUR COURTOIS M.COURTOIS +#@ MODIF asojb Noyau DATE 28/06/2011 AUTEUR COURTOIS M.COURTOIS # -*- coding: iso-8859-1 -*- # RESPONSABLE COURTOIS M.COURTOIS # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== -# COPYRIGHT (C) 1991 - 2007 EDF R&D WWW.CODE-ASTER.ORG +# COPYRIGHT (C) 1991 - 2011 EDF R&D WWW.CODE-ASTER.ORG # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR @@ -22,7 +22,7 @@ """ Description des OJB jeveux """ -from basetype import Type, MetaType +from basetype import Type from asnom import SDNom from ascheckers import CheckLog import traceback,sys diff --git a/Noyau/basetype.py b/Noyau/basetype.py index fb3b8391..601809df 100644 --- a/Noyau/basetype.py +++ b/Noyau/basetype.py @@ -1,22 +1,22 @@ -#@ MODIF basetype Noyau DATE 09/11/2010 AUTEUR COURTOIS M.COURTOIS +#@ MODIF basetype Noyau DATE 28/06/2011 AUTEUR COURTOIS M.COURTOIS # -*- coding: iso-8859-1 -*- # RESPONSABLE COURTOIS M.COURTOIS # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== -# COPYRIGHT (C) 1991 - 2007 EDF R&D WWW.CODE-ASTER.ORG -# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY -# IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY -# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR -# (AT YOUR OPTION) ANY LATER VERSION. -# -# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT -# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF -# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU -# GENERAL PUBLIC LICENSE FOR MORE DETAILS. -# -# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE -# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, -# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. +# COPYRIGHT (C) 1991 - 2011 EDF R&D WWW.CODE-ASTER.ORG +# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY +# IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY +# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR +# (AT YOUR OPTION) ANY LATER VERSION. +# +# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT +# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF +# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU +# GENERAL PUBLIC LICENSE FOR MORE DETAILS. +# +# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE +# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, +# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. # ====================================================================== """ @@ -141,32 +141,25 @@ class BaseType(object): for nam in self._subtypes: obj = getattr(self, nam) obj.supprime(delete) - if delete: - for nam in self._subtypes: - if hasattr(self, nam): - delattr(self, nam) - self._subtypes.remove(nam) + #XXX MC : avec ce code, j'ai l'impression qu'on supprime aussi + # des attributs de classe, ce qui pose problème pour une + # instanciation future... + # Dans une version précédente, on utilisait l'attribut + # sd_deleted pour ne faire qu'une fois, à voir. + # Supprimer les références remontantes devrait suffir. + #if delete: + #while len(self._subtypes): + #nam = self._subtypes.pop(0) + #try: + #delattr(self, nam) + #except AttributeError: + #pass def base( self ): if self._parent is None: return self return self._parent.base() - def change_type(self, new_type, nomj=None): - """Méthode appelée quand on change a posteriori le type - du concept (pour les 'CO'). - Si `nomj` est None, on prend `self.nom`. - """ - self.__class__ = new_type - nomj = nomj or self.nom - new_type.dup_attr(self) - - # Comment appeler AsBase.__init__ ? - # type(nomj)=str donc plus simple que dans AsBase.__init__... - assert isinstance(nomj, str), 'Valeur inattendue pour nomj : %s' % nomj - assert self.nomj is not self.__class__.nomj - self.nomj.nomj = nomj - class Type(BaseType): __metaclass__ = MetaType diff --git a/Noyau/context.py b/Noyau/context.py index 27c2528e..2573b505 100644 --- a/Noyau/context.py +++ b/Noyau/context.py @@ -1,30 +1,36 @@ -#@ MODIF context Noyau DATE 07/09/2009 AUTEUR COURTOIS M.COURTOIS +#@ MODIF context Noyau DATE 28/06/2011 AUTEUR COURTOIS M.COURTOIS # -*- coding: iso-8859-1 -*- # RESPONSABLE COURTOIS M.COURTOIS # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== -# COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG +# COPYRIGHT (C) 1991 - 2011 EDF R&D WWW.CODE-ASTER.ORG # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY -# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR -# (AT YOUR OPTION) ANY LATER VERSION. +# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR +# (AT YOUR OPTION) ANY LATER VERSION. +# +# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT +# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF +# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU +# GENERAL PUBLIC LICENSE FOR MORE DETAILS. +# +# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE +# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, +# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. # -# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT -# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF -# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU -# GENERAL PUBLIC LICENSE FOR MORE DETAILS. # -# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE -# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, -# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. -# -# # ====================================================================== - _root=None _cata=None debug=0 +from Noyau.N_info import message, SUPERV + +# Le "current step" est l'étape courante. +# Une macro se déclare étape courante dans sa méthode Build avant de construire +# ses étapes filles ou dans BuildExec avant de les exécuter. +# Les étapes simples le font aussi : dans Execute et BuildExec. +# (Build ne fait rien pour une étape) def set_current_step(step): """ @@ -33,6 +39,7 @@ def set_current_step(step): global _root if _root : raise "Impossible d'affecter _root. Il devrait valoir None" _root=step + message.debug(SUPERV, "current_step = %s", step.nom, stack_id=-1) def get_current_step(): """ -- 2.39.2