]> SALOME platform Git repositories - tools/eficas.git/commitdiff
Salome HOME
This commit was manufactured by cvs2git to create tag 'V_12a1'. V_12a1
authorcvs2git <renaud.nedelec@opencascade.com>
Thu, 14 Jun 2007 16:19:32 +0000 (16:19 +0000)
committercvs2git <renaud.nedelec@opencascade.com>
Thu, 14 Jun 2007 16:19:32 +0000 (16:19 +0000)
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

Sdbase/__init__.py [new file with mode: 0644]
Sdbase/ascheckers.py [new file with mode: 0644]
Sdbase/asnom.py [new file with mode: 0644]
Sdbase/asojb.py [new file with mode: 0644]
Sdbase/basetype.py [new file with mode: 0644]

diff --git a/Sdbase/__init__.py b/Sdbase/__init__.py
new file mode 100644 (file)
index 0000000..9c2d49d
--- /dev/null
@@ -0,0 +1,3 @@
+
+import asojb
+from asojb import AsBase
diff --git a/Sdbase/ascheckers.py b/Sdbase/ascheckers.py
new file mode 100644 (file)
index 0000000..fc6a9b4
--- /dev/null
@@ -0,0 +1,70 @@
+#@ 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) )
diff --git a/Sdbase/asnom.py b/Sdbase/asnom.py
new file mode 100644 (file)
index 0000000..89a541b
--- /dev/null
@@ -0,0 +1,133 @@
+#@ 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
+
+
diff --git a/Sdbase/asojb.py b/Sdbase/asojb.py
new file mode 100644 (file)
index 0000000..9e3c9e7
--- /dev/null
@@ -0,0 +1,304 @@
+#@ 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
diff --git a/Sdbase/basetype.py b/Sdbase/basetype.py
new file mode 100644 (file)
index 0000000..050ec23
--- /dev/null
@@ -0,0 +1,156 @@
+#@ 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
+