X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=Noyau%2FN_utils.py;h=5e1ba24a9004291cbfb991d1434e77c7d81fbebb;hb=8b202e4a0e933f400731a984944bf84aa9a06f48;hp=44cc0966e52cd29c299507010d8261456111395a;hpb=860a50d7df32b5c86f9ab536178d030ea882cae5;p=tools%2Feficas.git diff --git a/Noyau/N_utils.py b/Noyau/N_utils.py index 44cc0966..5e1ba24a 100644 --- a/Noyau/N_utils.py +++ b/Noyau/N_utils.py @@ -1,147 +1,222 @@ -# -*- coding: utf-8 -*- -#@ MODIF N_utils Noyau DATE 27/03/2002 AUTEUR DURAND C.DURAND -# CONFIGURATION MANAGEMENT OF EDF VERSION -# ====================================================================== -# COPYRIGHT (C) 1991 - 2002 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. +# coding=utf-8 +# Copyright (C) 2007-2021 EDF R&D # -# 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 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. # -# 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 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 + + """ Ce module contient des fonctions utilitaires """ # Modules Python -import sys,types -import string +from __future__ import absolute_import +from __future__ import print_function +from __future__ import division +try : + from builtins import str + from builtins import object +except : + pass +import sys # Modules EFICAS -from N_Exception import AsException - -SEP='_' - -try: - # Si la version de Python possède la fonction _getframe - # on l'utilise. - cur_frame=sys._getframe -except: - # Sinon on l'émule - def cur_frame(offset=0): - """ Retourne la frame d execution effective eventuellement en remontant - de offset niveaux dans la pile d execution - Si il y a moins de offset niveaux retourne None - """ - try:1/0 - except: - frame=sys.exc_info()[2].tb_frame.f_back - while offset > 0: - if frame == None:return None - frame=frame.f_back - offset=offset-1 - return frame - - -def callee_where(niveau=4): - """ - recupere la position de l appel - """ - frame=cur_frame(niveau) - if frame == None: return 0,"inconnu",0,{} - try: - return frame.f_lineno,frame.f_code.co_filename,frame.f_code.co_firstlineno,frame.f_locals - except: - return 0,"inconnu",0,{} +from .N_Exception import AsException +from .N_types import isInt, isFloat, isComplex, isStr, isSequence, isASSD +from .strfunc import getEncoding + +SEP = '_' + +try : + cur_frame = sys._getframe +except : + print ('pb avec la version de python pour cur_frame = sys._getframe') + +def calleeWhere(niveau=4): + """ + recupere la position de l appel + """ + frame = sys._getframe(niveau) + if frame == None: + return 0, "inconnu", 0, {} + try: + # Python 2.7 compile function does not accept unicode filename, so we encode it + # with the current locale encoding in order to have a correct traceback. + # Here, we convert it back to unicode. + import six + filename = six.text_type(frame.f_code.co_filename, getEncoding()) + return frame.fLineNo, filename, frame.f_code.co_firstlineno, frame.f_locals + except: + return 0, "inconnu", 0, {} + def AsType(a): - """ - Retourne le type d'un concept (a) à partir - des caractéristiques de l'objet Python - """ - if type(a) in (types.TupleType,types.ListType):return AsType(a[0]) - if type(a) == types.InstanceType:return a.__class__ - if type(a) == types.FloatType:return "R" - if type(a) == types.IntType:return "I" - if type(a) == types.StringType:return "TXM" - if a == None : return None - print 'a=',a,type(a) - raise AsException("type inconnu") + """ + Retourne le type d'un concept (a) à partir + des caractéristiques de l'objet Python + """ + if isSequence(a): + return AsType(a[0]) + if isASSD(a): + return type(a) + if isFloat(a): + return "R" + if isInt(a): + return "I" + if isStr(a): + return "TXM" + if a == None: + return None + raise AsException("type inconnu: %r %s" % (a, type(a))) + def prbanner(s): - print "*"*(len(s)+10) - print "*"*5 + s + "*"*5 - print "*"*(len(s)+10) + print(("*" * (len(s) + 10))) + print(("*" * 5 + s + "*" * 5)) + print(("*" * (len(s) + 10))) + 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 - 5 caractères - NB : valeur est un réel au format Python ou une chaine de caractères représentant un réel - """ - if type(valeur) == types.StringType : valeur = eval(valeur) - if valeur == 0. : return '0.0' - if abs(valeur) > 1. : - if abs(valeur) < 10000. : return repr(valeur) - else : - if abs(valeur) > 0.01 : return repr(valeur) - t=repr(valeur) - if string.find(t,'e') != -1 or string.find(t,'E') != -1 : - # le réel est déjà sous forme mantisse exposant ! - # --> on remplace e par E - t=string.replace(t,'e','E') - # --> on doit encore vérifier que la mantisse contient bien un '.' - if string.find(t,'.')!= -1: - return t + """ + 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 + 5 caractères + NB : valeur est un réel au format Python ou une chaine de caractères représentant un réel + """ + if type(valeur) == str: + valeur = eval(valeur) + if valeur == 0.: + return '0.0' + if abs(valeur) > 1.: + if abs(valeur) < 10000.: + return repr(valeur) else: - # -->il faut rajouter le point avant le E - t=string.replace(t,'E','.E') - return t - s='' - neg = 0 - if t[0]=='-': - s=s+t[0] - t=t[1:] - cpt = 0 - if string.atof(t[0]) == 0.: - # réel plus petit que 1 - neg = 1 - t=t[2:] - cpt=1 - while string.atof(t[0]) == 0. : - cpt = cpt+1 - t=t[1:] - s=s+t[0]+'.' - for c in t[1:]: - s=s+c - else: - # réel plus grand que 1 - s=s+t[0]+'.' - if string.atof(t[1:]) == 0.: - l=string.split(t[1:],'.') - cpt = len(l[0]) + if abs(valeur) > 0.01: + return repr(valeur) + t = repr(valeur) + if t.find('e') != -1 or t.find('E') != -1: + # le réel est déjà sous forme mantisse exposant ! + # --> on remplace e par E + t = t.replace('e', 'E') + # --> on doit encore vérifier que la mantisse contient bien un '.' + if t.find('.') != -1: + return t + else: + # -->il faut rajouter le point avant le E + t = t.replace('E', '.E') + return t + s = '' + neg = 0 + if t[0] == '-': + s = s + t[0] + t = t[1:] + cpt = 0 + if t[0].atof() == 0.: + # réel plus petit que 1 + neg = 1 + t = t[2:] + cpt = 1 + while t[0].atof() == 0.: + cpt = cpt + 1 + t = t[1:] + s = s + t[0] + '.' + for c in t[1:]: + s = s + c else: - r=0 - pt=0 - for c in t[1:]: - r=r+1 - if c != '.' : - if pt != 1 : cpt = cpt + 1 - s=s+c + # réel plus grand que 1 + s = s + t[0] + '.' + if t[1:].atof() == 0.: + l = t[1:].split('.') + cpt = len(l[0]) else: - pt = 1 - if r+1 == len(t) or string.atof(t[r+1:]) == 0.:break - s=s+'E'+neg*'-'+repr(cpt) - return s + r = 0 + pt = 0 + for c in t[1:]: + r = r + 1 + if c != '.': + if pt != 1: + cpt = cpt + 1 + s = s + c + else: + pt = 1 + if r + 1 == len(t) or t[r + 1:].atof() == 0.: + break + s = s + 'E' + neg * '-' + repr(cpt) + return s + + +def importObject(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 as err: + raise ImportError( + "can not import module : %s (%s)" % (modname, str(err))) + try: + object = getattr(mod, objname) + except AttributeError as err: + raise AttributeError("object (%s) not found in module '%s'. " + "Module content is: %s" % (objname, modname, tuple(dir(mod)))) + return object + + +class Singleton(object): + + """Singleton implementation in python.""" + # add _singleton_id attribute to the class to be independant of import + # path used + __inst = {} + + def __new__(cls, *args, **kargs): + cls_id = getattr(cls, '_singleton_id', cls) + if Singleton.__inst.get(cls_id) is None: + Singleton.__inst[cls_id] = object.__new__(cls) + return Singleton.__inst[cls_id] + + +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.getId(value) is not None + def getId(self, value): + """Return the key associated to the given value""" + return self._dict_keys.get(value, None)