Sprout from BR_V1_12a1 2007-06-14 16:19:31 UTC Pascale Noyret <pascale.noyret@edf.fr> 'modif mathieu courtois'
Cherrypick from BR_V1_12a1 2007-04-26 07:56:11 UTC Christian Caremoli 'CCAR: Creation de la version Eficas 1.12 avec mise a niveau Aster 9.0.16':
Sdbase/__init__.py
Sdbase/ascheckers.py
Sdbase/asnom.py
Sdbase/asojb.py
Sdbase/basetype.py
--- /dev/null
+
+import asojb
+from asojb import AsBase
--- /dev/null
+#@ MODIF ascheckers SD DATE 13/02/2007 AUTEUR PELLET J.PELLET
+# -*- coding: iso-8859-1 -*-
+# 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.
+# ======================================================================
+
+class Parmi(object):
+ """Classe qui exprime une contrainte multiple pour un attribut"""
+ def __init__(self, *args):
+ self.values = list(args)
+
+ def add_value(self, value ):
+ if value not in self.values:
+ self.values.append( value )
+
+ def __call__(self, obj, name, value, log ):
+ if value not in self.values:
+ log.err( obj, "l'attribut %s=%r n'est pas dans %r" % (name, value, self.values) )
+
+ def __repr__(self):
+ l = [ "Parmi(", ]
+ g = [ repr(v) for v in self.values ]
+ l.append( ", ".join(g) )
+ l.append( ")" )
+ return "".join( l )
+
+class CheckLog(object):
+ """Un validateur qui enregistre toutes
+ les erreurs trouvées"""
+ def __init__(self):
+ self.msg = []
+ self.names = {}
+ self.optional = False
+
+ def log(self, level, obj, msg ):
+ self.msg.append( (level, obj.nomj(), msg) )
+
+ def err(self, obj, msg ):
+ self.log( 0, obj, msg )
+
+ def warn(self, obj, msg ):
+ self.log( 1, obj, msg )
+
+ def visit(self, obj ):
+ self.names[obj.nomj()] = 1
+
+ def __str__(self):
+ d = { 0: "E", 1:"W" }
+ return "\n".join( [ "%s:%s: %s" % (d[l],n,m)
+ for l,n,m in self.msg ])
+
+class CheckFail(CheckLog):
+ """Un validateur qui lève une exception
+ dès la première erreur"""
+ def err(self, obj, msg ):
+ raise AssertionError("%s: %s" % (obj.nomj(), msg) )
--- /dev/null
+#@ MODIF asnom SD DATE 13/02/2007 AUTEUR PELLET J.PELLET
+# -*- coding: iso-8859-1 -*-
+# 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.
+# ======================================================================
+
+"""
+Description des types de base aster
+
+version 2 - réécrite pour essayer de simplifier
+le problème des instances/types et instances/instances
+
+le type de base ASBase permet de représenter une structure
+de donnée. Une instance de ASBase comme attribut d'une classe
+dérivée de ASBase représente une sous-structure nommée.
+
+une instance de ASBase 'libre' représente une instance de la
+structure de donnée complète.
+
+c'est ce comportement qui est capturé dans la classe StructType
+"""
+
+from basetype import Type
+
+class SDNom(Type):
+ """Objet représentant une sous-partie de nom
+ d'objet jeveux"""
+ nomj = None
+ debut = None
+ fin = None
+ just = None
+ justtype = None
+
+ def __init__(self, nomj=None, debut=None, fin=None, just='l', **kwargs ):
+ """
+ Configure un objet nom
+ nomj : la partie du nom fixée (par ex .TITR) ou '' si non précisée
+ debut, fin : la partie du K24 concernée
+ just : la justification a droite ou a gauche ('l' ou 'r')
+ kwargs : inutilisé, juste par simplicité
+
+ Note:
+ On utilise cet objet comme attribut d'instance ou de classe.
+ En attribut de classe pour les noms de structure, cela permet
+ de définir la position du nom d'objet dans le nom jeveux, l'attribut
+ nom est alors la valeur du suffixe pour une sous-structure ou None pour
+ une structure principale.
+ """
+ super( SDNom, self ).__init__( nomj=nomj, debut=debut, fin=fin, just=just, **kwargs )
+ self.update( (nomj, debut, fin, just) )
+
+ def __call__(self):
+ if self._parent is None or self._parent._parent is None:
+ debut = self.debut or 0
+ prefix = ' '*debut
+ else:
+ # normalement
+ # assert self._parent.nomj is self
+ nomparent = self._parent._parent.nomj
+ prefix = nomparent()
+ debut = self.debut or nomparent.fin or len(prefix)
+ fin = self.fin or 24
+ nomj = self.nomj or ''
+ nomj = self.just( nomj, fin-debut )
+ prefix = prefix.ljust(24)
+ res = prefix[:debut]+nomj+prefix[fin:]
+ return res[:24]
+
+ def fcata(self):
+ return self.just(self.nomj,self.fin-self.debut).replace(' ','?')
+
+ def __repr__(self):
+ return "<SDNom(%r,%s,%s)>" % (self.nomj,self.debut,self.fin)
+
+ # On utilise pickle pour les copies, et pickle ne sait pas gérer la
+ # sauvegarde de str.ljust ou str.rjust (c'est une méthode non liée)
+
+ def __getstate__(self):
+ return (self.nomj, self.debut, self.fin, self.justtype )
+
+ def __setstate__( self, (nomj,debut,fin,just) ):
+ self.nomj = nomj
+ self.debut = debut
+ self.fin = fin
+ if just=='l' or just is None:
+ self.just = str.ljust
+ elif just=='r':
+ self.just = str.rjust
+ else:
+ raise ValueError("Justification '%s' invalide" % just )
+ self.justtype = just
+
+
+ def update( self, (nomj,debut,fin,just) ):
+ if nomj is not None:
+ self.nomj = nomj
+ if self.debut is None:
+ self.debut = debut
+ if self.fin is None:
+ self.fin = fin
+ if self.justtype is None and just is not None:
+ if just=='l':
+ self.just = str.ljust
+ elif just=='r':
+ self.just = str.rjust
+ else:
+ raise ValueError("Justification '%s' invalide" % just )
+ self.justtype = just
+
+ def reparent( self, parent, new_name ):
+ self._parent = parent
+ self._name = new_name
+ for nam in self._subtypes:
+ obj = getattr( self, nam )
+ obj.reparent( self, nam )
+ if self.nomj is None and self._parent._name is not None:
+ self.nomj = "." + self._parent._name
+
+
--- /dev/null
+#@ MODIF asojb SD DATE 13/02/2007 AUTEUR PELLET J.PELLET
+# -*- coding: iso-8859-1 -*-
+# 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.
+# ======================================================================
+
+"""
+ Description des OJB jeveux
+"""
+from basetype import Type, MetaType
+from asnom import SDNom
+from ascheckers import CheckLog
+
+# pour utilisation dans eficas
+try:
+ import aster
+except:
+ pass
+
+# -----------------------------------------------------------------------------
+class AsBase(Type):
+ nomj = SDNom()
+ optional = False
+
+ def __init__(self, nomj=None, *args, **kwargs ):
+ super(AsBase,self).__init__( nomj, *args, **kwargs )
+ assert self.nomj is not self.__class__.nomj
+ if isinstance( nomj, str ):
+ self.nomj.nomj = nomj
+ elif isinstance( nomj, SDNom ):
+ self.nomj.update( nomj.__getstate__() )
+
+ def set_name(self, nomj):
+ """Positionne le nomj de self
+ """
+ assert isinstance( self.nomj.nomj, str ), "uniquement pour les concepts"
+ self.nomj.nomj = nomj
+
+ def check(self, checker=None):
+ if checker is None:
+ checker = CheckLog()
+
+ # vérifie les enfants :
+ optional = checker.optional
+ checker.optional = checker.optional or self.optional
+ for name in self._subtypes:
+ v = getattr(self, name)
+ if isinstance( v, (OJB,AsBase) ):
+ v.check(checker)
+ for name in dir(self):
+ if name.startswith( 'check_' ):
+ v = getattr(self, name)
+ if callable(v):
+ v( checker )
+
+ checker.optional = optional
+ return checker
+
+ def members( self ):
+ pass
+
+ def dump(self, indent=""):
+ import pydoc
+ l = []
+ checkers = []
+ nomj = self.nomj()
+ if self.optional:
+ f = "(f)"
+ else:
+ f = "(o)"
+ l.append( f+" "+nomj )
+ #l.append( '-'*(len(nomj)+3) )
+ for name in self._subtypes:
+ obj = getattr(self, name)
+ if isinstance(obj,(AsBase,OJB)):
+ l.append( obj.dump(indent) )
+ for name in dir(self):
+ if name.startswith( 'check_' ):
+ obj = getattr(self, name)
+ if callable(obj) and name.startswith("check_"):
+ checkers.append( obj )
+
+ indent = " "*len(nomj)
+ for checker in checkers:
+ doc = pydoc.text.document( checker )
+ for line in doc.splitlines():
+ l.append( indent + line )
+ return "\n".join( l )
+
+ def __repr__(self):
+ return "<%s(%x,%r)>" % (self.__class__.__name__, id(self), self.nomj() )
+
+
+# -----------------------------------------------------------------------------
+class JeveuxAttr(object):
+ """Un attribut jeveux"""
+ def __init__(self, name):
+ self.name = name
+
+ def __get__(self, obj, klass):
+ raise NotImplementedError
+
+ def check(self, attrname, obj, log ):
+ checker = getattr(obj, "_"+attrname, None )
+ if checker is None:
+ return True
+ val = self.__get__( obj, obj.__class__ )
+ if callable( checker ):
+ return checker( obj, attrname, val, log )
+ else:
+ test = val == checker
+ if not test:
+ log.err( obj, "Attribut incorrect %s %r!=%r" % (self.name, val, checker ) )
+ return test
+
+# -----------------------------------------------------------------------------
+class JeveuxExists(JeveuxAttr):
+ def __init__(self):
+ pass
+
+ def __get__(self, obj, klass):
+ if obj is None:
+ return self
+ nomj = obj.nomj()
+ if len(nomj)!=24:
+ raise AssertionError(repr(nomj))
+ return aster.jeveux_exists( nomj.ljust(24) )
+
+# -----------------------------------------------------------------------------
+class JeveuxIntAttr(JeveuxAttr):
+ def __get__(self, obj, klass):
+ if obj is None:
+ return self
+ return aster.jeveux_getattr( obj.nomj(), self.name )[0]
+
+# -----------------------------------------------------------------------------
+class JeveuxStrAttr(JeveuxAttr):
+ def __get__(self, obj, klass):
+ if obj is None:
+ return self
+ return aster.jeveux_getattr( obj.nomj(), self.name )[1].strip()
+
+# -----------------------------------------------------------------------------
+class OJB(AsBase):
+ _clas = None
+ _genr = None
+ _type = None
+ _ltyp = None
+ _xous = None
+ _docu = None
+ _exists = True
+
+ clas = JeveuxStrAttr("CLAS")
+ genr = JeveuxStrAttr("GENR")
+ type = JeveuxStrAttr("TYPE")
+ ltyp = JeveuxIntAttr("LTYP")
+ xous = JeveuxStrAttr("XOUS")
+ docu = JeveuxStrAttr("DOCU")
+ exists = JeveuxExists()
+ #optional = False
+ nomj = SDNom()
+
+ def __init__(self, nomj=None, **attrs):
+ super(OJB,self).__init__( nomj, **attrs )
+ self.foreachattr( self.setattribute, attrs )
+ self.optional = attrs.get('optional', False)
+
+ def setattribute( self, name, prop, attrs ):
+ _name = "_"+name
+ if name in attrs:
+ setattr( self, _name, attrs[name] )
+
+ def get(self):
+ nomj = self.nomj()
+ if aster.jeveux_exists( nomj ):
+ obj_simple = aster.jeveux_getattr( nomj, 'XOUS')[1].strip() == 'S'
+ if obj_simple :
+ return aster.getvectjev( nomj )
+ else :
+ return aster.getcolljev( nomj )
+ else:
+ return None
+
+ def get_stripped(self):
+ """Fonction utilitaire, renvoie une liste de chaines 'strippées'"""
+ data = self.get()
+ if data is not None:
+ return [ x.strip() for x in self.get() ]
+ else:
+ return []
+
+ def foreachattr(self, callable, *args, **kwargs):
+ klass = self.__class__
+ for k in dir(klass):
+ v = getattr( klass, k )
+ if isinstance(v, JeveuxAttr):
+ callable( k, v, *args, **kwargs )
+
+ def check(self, checker=None):
+ if checker is None:
+ checker = CheckLog()
+ # l'objet a déjà été vérifié, on ne fait rien
+ if self.nomj() in checker.names.keys():
+ return checker
+ checker.visit( self )
+ if self.exists:
+ self.foreachattr( lambda k,v,obj,c: v.check(k, obj, c),
+ self, checker )
+ else:
+ if not self.optional and not checker.optional :
+ checker.err( self, "n'existe pas (%r)" %self._parent )
+ return checker
+
+ def tous_compris(self, checker, vmin=None, vmax=None):
+ # Vérifie que toutes les valeurs du vecteur sont comprises entre vmin et vmax
+ # Les bornes vmin et vmax sont autorisées
+ assert vmin or vmax, 'Il faut fournir au moins une des valeurs vmin ou vmax'
+ vect = self.get()
+ if not vect : return
+ ier = 0
+ for v in vect :
+ if vmin and v < vmin : ier = 1
+ if vmax and v > vmax : ier = 1
+ if ier == 1 : checker.err( self, "L'objet doit contenir des valeurs dans l'intervalle : %s %s " % (vmin,vmax))
+
+ def dump(self, indent=""):
+ if self.optional:
+ f = "(f)"
+ else:
+ f = "(o)"
+ return f +" "+ self.nomj() +" "+ str(self.exists)
+
+# -----------------------------------------------------------------------------
+def Facultatif( ojb ):
+ ojb.optional = True
+ return ojb
+
+# -----------------------------------------------------------------------------
+class OJBVect(OJB):
+ lonmax = JeveuxIntAttr("LONMAX")
+ lonuti = JeveuxIntAttr("LONUTI")
+
+# -----------------------------------------------------------------------------
+class OJBCollec(OJB):
+ stockage = JeveuxStrAttr("STOCKAGE")
+ nutioc = JeveuxIntAttr( "NUTIOC" )
+ acces = JeveuxStrAttr( "ACCES" )
+ modelong = JeveuxStrAttr( "MODELONG" )
+ nmaxoc = JeveuxIntAttr( "NMAXOC" )
+
+# -----------------------------------------------------------------------------
+class AsVI(OJBVect):
+ _type = "I"
+
+# -----------------------------------------------------------------------------
+class AsVR(OJBVect):
+ _type = "R"
+
+# -----------------------------------------------------------------------------
+class AsVC(OJBVect):
+ _type = "C"
+
+# -----------------------------------------------------------------------------
+class AsVK8(OJBVect):
+ _type = "K"
+ _ltyp = 8
+
+# -----------------------------------------------------------------------------
+class AsVK16(OJBVect):
+ _type = "K"
+ _ltyp = 16
+
+# -----------------------------------------------------------------------------
+class AsVK24(OJBVect):
+ _type = "K"
+ _ltyp = 24
+
+# -----------------------------------------------------------------------------
+class AsVK32(OJBVect):
+ _type = "K"
+ _ltyp = 32
+
+# -----------------------------------------------------------------------------
+class AsVK80(OJBVect):
+ _type = "K"
+ _ltyp = 80
+
+# Pour compatibilite
+AsColl = OJBCollec
+AsObject = OJB
--- /dev/null
+#@ MODIF basetype SD DATE 13/02/2007 AUTEUR PELLET J.PELLET
+# -*- coding: iso-8859-1 -*-
+# 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.
+# ======================================================================
+
+"""
+Description des types de base aster
+-----------------------------------
+
+version 2 - réécrite pour essayer de simplifier
+le problème des instances/types et instances/instances.
+
+Le type de base `Type` permet de représenter une structure
+de donnée. Une instance de `Type` comme attribut d'une classe
+dérivée de `Type` représente une sous-structure nommée.
+
+Une instance de `Type` 'libre' représente une instance de la
+structure de donnée complète.
+
+C'est ce comportement qui est capturé dans la classe BaseType
+
+La classe `Type` hérite de BaseType et y associe la métaclasse MetaType.
+
+"""
+from copy import copy,deepcopy
+import cPickle
+
+__docformat__ = "restructuredtext"
+
+
+
+
+class MetaType(type):
+ """Métaclasse d'un type représentant une structure de données.
+ Les méthodes spéciales __new__ et __call__ sont réimplémentées
+ """
+ def __new__( mcs, name, bases, classdict ):
+ """Création d'une nouvelle 'classe' dérivant de Type.
+
+ Cette méthode permet de calculer certains attributs automatiquement:
+
+ - L'attribut _subtypes qui contient la liste des sous-structures
+ de type 'Type' attributs (directs ou hérités) de cette classe.
+
+ Pour chaque attribut de classe héritant de Type, on recrée une nouvelle
+ instance des attributs hérités pour pouvoir maintenir une structure de
+ parentée entre l'attribut de classe et sa nouvelle classe.
+
+ L'effet obtenu est que tous les attributs de classe ou des classes parentes
+ de cette classe sont des attributs associés à la classe feuille. Ces attributs
+ ont eux-meme un attribut parent qui pointe sur la classe qui les contient.
+ """
+ new_cls = type.__new__( mcs, name, bases, classdict )
+ new_cls._subtypes = []
+ for b in bases:
+ if hasattr(b,'_subtypes'):
+ new_cls._subtypes += b._subtypes
+ # affecte la classe comme parent des attributs de classe
+ # et donne l'occasion aux attributs de se renommer à partir
+ # du nom utilisé.
+ for k, v in classdict.items():
+ if not isinstance( v, BaseType ):
+ continue
+ v.reparent( new_cls, k )
+ new_cls._subtypes.append( k )
+ return new_cls
+
+ def dup_attr(cls, inst):
+ """Duplique les attributs de la classe `cls` pour qu'ils deviennent
+ des attributs de l'instance `inst`.
+ """
+ # reinstantiate and reparent subtypes
+ for nam in cls._subtypes:
+ obj = getattr( cls, nam )
+ # permet de dupliquer completement l'instance
+ cpy = cPickle.dumps(obj)
+ newobj = cPickle.loads( cpy )
+ newobj.reparent( inst, None )
+ setattr( inst, nam, newobj )
+
+ def __call__(cls, *args, **kwargs):
+ """Instanciation d'un Type structuré.
+ Lors de l'instanciation on effectue un travail similaire à la
+ création de classe: Les attributs sont re-parentés à l'instance
+ et réinstanciés pour obtenir une instanciation de toute la structure
+ et de ses sous-structures.
+
+ Les attributs de classe deviennent des attributs d'instance.
+ """
+ inst = cls.__new__(cls, *args, **kwargs)
+ # reinstantiate and reparent subtypes
+ cls.dup_attr( inst )
+ type(inst).__init__(inst, *args, **kwargs)
+ return inst
+
+ def mymethod(cls):
+ pass
+
+
+class BaseType(object):
+ # Le parent de la structure pour les sous-structures
+ _parent = None
+ _name = None
+
+ def __init__(self, *args, **kwargs):
+ self._initargs = args
+ self._initkwargs = kwargs
+ self._name = None
+ self._parent = None
+
+ def reparent( self, parent, new_name ):
+ self._parent = parent
+ self._name = new_name
+ for nam in self._subtypes:
+ obj = getattr( self, nam )
+ obj.reparent( self, nam )
+
+ 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
+