-#@ MODIF basetype Noyau DATE 16/05/2007 AUTEUR COURTOIS M.COURTOIS
-# -*- 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.
-# ======================================================================
+# coding=utf-8
+# Copyright (C) 2007-2013 EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
"""
+
Description des types de base aster
-----------------------------------
-version 2 - réécrite pour essayer de simplifier
-le problème des instances/types et instances/instances.
+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.
+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.
+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
+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.
+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
+
+ """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.
+ 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:
+ 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.
+ 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.
+ 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
+ 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 = type.__new__(mcs, name, bases, classdict)
new_cls._subtypes = []
for b in bases:
- if hasattr(b,'_subtypes'):
+ 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é.
+ # et donne l'occasion aux attributs de se renommer à partir
+ # du nom utilisé.
for k, v in classdict.items():
- if not isinstance( v, BaseType ):
+ if not isinstance(v, BaseType):
continue
- v.reparent( new_cls, k )
- new_cls._subtypes.append( k )
+ v.reparent(new_cls, k)
+ new_cls._subtypes.append(k)
return new_cls
def dup_attr(cls, 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 )
+ 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
+ """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 )
+ cls.dup_attr(inst)
type(inst).__init__(inst, *args, **kwargs)
return inst
def mymethod(cls):
- pass
+ pass
class BaseType(object):
self._name = None
self._parent = None
- def reparent( self, parent, new_name ):
+ 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 ):
+ obj = getattr(self, nam)
+ obj.reparent(self, nam)
+
+ def supprime(self, delete=False):
+ """Permet de casser les boucles de références pour que les ASSD
+ puissent être détruites.
+ Si `delete` vaut True, on supprime l'objet lui-même et pas
+ seulement les références remontantes."""
+ self._parent = None
+ self._name = None
+ for nam in self._subtypes:
+ obj = getattr(self, nam)
+ obj.supprime(delete)
+ # 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...
+ # 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
-