]> SALOME platform Git repositories - tools/eficas.git/commitdiff
Salome HOME
Antoine Yessayan a modifié la boîte à outils permettant d'instrumenter du Python.
authoreficas <>
Thu, 6 Mar 2003 14:36:12 +0000 (14:36 +0000)
committereficas <>
Thu, 6 Mar 2003 14:36:12 +0000 (14:36 +0000)
developpeur.py
En particulier, les outils ne sont actifs que si les développeurs sont
déclarés dans ce fichier ;

modification.py
propose une fonction permettant de tracer lors de l'execution d'Eficas
une intervention effectuée par l'un des développeurs ;

execute.py
permet d'organiser l'instruction exec in contexte.

Utilites/__init__.py
Utilites/appels.py
Utilites/developpeur.py [new file with mode: 0644]
Utilites/execute.py [new file with mode: 0644]
Utilites/funcname.py [new file with mode: 0644]
Utilites/ici.py
Utilites/message.py
Utilites/modification.py [new file with mode: 0644]
Utilites/pause.py
Utilites/scrute.py

index 19d51f8fd41eb6ad62e6767d71b8a4cb6427fb6c..d109f6c84ed715c0cc82773cdafcdec0cc48357b 100644 (file)
@@ -1,5 +1,5 @@
 """
-    $Id: __init__.py,v 1.2 2003/02/04 10:40:57 eficas Exp $
+    $Id: __init__.py,v 1.3 2003/02/06 15:11:22 eficas Exp $
 
     Le package UTILITES contient les fonctions permettant
     d'instrumenter un script :
 
 
 ##__all__ = [ "ici" , "message" , "scrute" , "pause" , "appels" ]
-from pause import *
+
+try :
+       from developpeur import *
+except :
+       pass
 from ici import *
+from execute import *
+from pause import *
 from scrute import *
 from message import *
 from appels import *
+from modification import *
 
 
 
 if __name__ == "__main__" :
-    print dir()
-    print "import du package effectué !"
+    MODIFICATION( "toto" )
+    developpeur.write( dir()+'\n' )
+    developpeur.write( "import du package effectué !" +'\n' )
index efc9a6d95a4d0c3fd522c4739546943c69dc7d5e..d4638a4afad97f1367a38201920556111c5ec400 100644 (file)
@@ -4,52 +4,115 @@ Module appels
     le module appels ...
 """
 
-import sys
-sortie=sys.stderr
-sortie.write( "import de "+__name__+" : $Id$" )
-sortie.write( "\n" )
+try :
+       from developpeur import DEVELOPPEUR
+except :
+       DEVELOPPEUR=None
 
+def NULL( *l_args, **d_args  ) : pass
 
-def APPELS() :
+if DEVELOPPEUR :
 
-    """
-    Fonction APPELS
-    ---------------
-    La fonction APPELS ...
-    ..
+    import developpeur
+    developpeur.sortie.write( "import de "+__name__+" : $Id$" )
+    developpeur.sortie.write( "\n" )
 
+    import sys
+    import re
+    import ici
+    import funcname
+    
+    
+    def Alonge( chaine , longueur ) :
+        return chaine+' ' # provisoirement on ne complete pas la chaine
+        k=len(chaine)
+        while( k<longueur ) :
+            chaine = chaine + ' '
+            k+=1
+        return chaine
+    
+    def APPELS( dec="" ) :
+    
+        """
+        Fonction APPELS
+        ---------------
+        La fonction APPELS ...
+        ..
+    
+    
+        Usage :
+            from appels import APPELS
+            APPELS()
+        """
+    
+    ### try :
+    ###     1/0
+    ### except :
+    ###     import traceback
+    ###     trace=traceback.extract_stack()
+    ###     print trace
+    
+        nombre_de_blancs=None
+    
+        import traceback
+        trace=traceback.extract_stack()
+    
+        trace.reverse()
+    
+        decalage=dec
+        sys.stderr.flush()
+        sys.stdout.flush()
+    
+        developpeur.sortie.write( 3*'\n' )
+        developpeur.sortie.write( decalage )
+        developpeur.sortie.write( "LISTE des appels" )
+        developpeur.sortie.write( '\n' )
+        developpeur.sortie.flush()
+        if len(trace)>2 :
+            decalage += '\t'
+    
+            # Recherche du plus long nom de fichier pour la mise en forme
+            lmax=0
+            for e in trace[2:-1] :
+                fic,numero,fonc,inst = e
+                position=fic+":"+str(numero)+":"
+           if len(position)>lmax : lmax=len(position)
+            lmax += 1 # Pour eloigner les informations du nom du fichier
+    
+            for e in trace[1:-1] :
+                fic,numero,fonc,inst = e
+                position = chaine=fic+":"+str(numero)+":"
+                position = Alonge( chaine=position , longueur=lmax )
+                developpeur.sortie.write( decalage+position)
+                developpeur.sortie.flush()
+                fname=funcname.FUNCNAME(fic,numero)
+                developpeur.sortie.write( str(fname) )
+                developpeur.sortie.write( ' : ' )
+                developpeur.sortie.write( inst )
+                developpeur.sortie.write( '\n' )
+                developpeur.sortie.flush()
+                decalage += ""
+    
+        fic,numero,fonc,inst = trace[-1]
+        position = chaine=fic+":"+str(numero)+":"
+        position = Alonge( chaine=position , longueur=lmax )
+        developpeur.sortie.write( decalage+position)
+        developpeur.sortie.flush()
+        fname="__main__"
+        developpeur.sortie.write( str(fname) )
+        developpeur.sortie.write( ' : ' )
+        developpeur.sortie.write( inst )
+        developpeur.sortie.write( 3*'\n' )
+        developpeur.sortie.flush()
+    
+    
+        return
 
-    Usage :
-        from appels import APPELS
-        APPELS()
-    """
+else :
+       APPELS = NULL
 
-    print  "Passage dans APPELS"
-### try :
-###     1/0
-### except :
-###     import traceback
-###     trace=traceback.extract_stack()
-###     print trace
-
-    import traceback
-    trace=traceback.extract_stack()
-
-    trace.reverse()
-
-    decalage=""
-    if len(trace)>2 :
-        for e in trace[2:-1] :
-            fic,numero,fonc,inst = e
-            print decalage+fic+":"+str(numero)+": "+fonc,inst
-            decalage += "\t"
-
-    fic,numero,fonc,inst = trace[-1]
-    print decalage+fic+":"+str(numero)+": "+"__main__",inst
-
-
-    return
 
 
 if __name__ == "__main__" :
-       APPELS()
+    TOTO=NULL
+    TOTO(  dec="" )
diff --git a/Utilites/developpeur.py b/Utilites/developpeur.py
new file mode 100644 (file)
index 0000000..6fc7bf4
--- /dev/null
@@ -0,0 +1,36 @@
+"""
+    Ce module permet de définir la variable DEVELOPPEUR indiquant
+    que l'utilisateur courant fait partie de la liste des développeurs.
+    Ce qui lui donne un accès aux versions actives des fonctions
+    ICI, MESSAGE, SCRUTE, ... définies dans le module Utilites
+    à condition qu'ils utilisent le module sur une station cli*.
+
+    Pour ajouter un nouveau développeur, il faut modifier le dictionaire
+    d_dev ci-dessous
+"""
+
+
+DEVELOPPEUR=None
+
+import os
+def hostname() :
+       return os.uname()[1]
+group_eficas=108
+group_salome=107
+
+
+# Test pour identifier un utilisateur développeur d'Eficas
+groups = os.getgroups()
+test_devel = hostname()[0:3]=="cli" and ( group_eficas in groups or group_salome in groups )
+if test_devel :
+    d_dev = { 10618 : "antoine" , 10621 : "Pascale" , 20132 : "chris" , 10214 : "salome" }
+    if os.getuid() in d_dev.keys() :
+        DEVELOPPEUR=d_dev[ os.getuid() ]
+        import sys
+        sortie=sys.stderr
+        sortie.write( "import de "+__name__+" : $Id$" )
+        sortie.write( "\n" )
+
+
+if __name__ == "__main__" :
+    print DEVELOPPEUR
diff --git a/Utilites/execute.py b/Utilites/execute.py
new file mode 100644 (file)
index 0000000..8e18e4d
--- /dev/null
@@ -0,0 +1,71 @@
+"""
+Module exec
+-----------
+    le module exec ...
+"""
+
+try :
+       from developpeur import DEVELOPPEUR
+except :
+       DEVELOPPEUR=None
+
+if DEVELOPPEUR :
+
+    import message
+    import scrute
+    import types
+    import developpeur
+    developpeur.sortie.write( "import de "+__name__+" : $Id$" )
+    developpeur.sortie.write( "\n" )
+    developpeur.sortie.flush()
+
+
+    class EXEC :
+
+        def __init__ ( self, texte, contexte=None, verbeux=1 ) :
+
+            assert( type(texte) == types.StringType )
+            if contexte == None :
+                contexte = globals()
+
+            if verbeux :
+                message.MESSAGE( "execution de "+texte )
+            try :
+                exec texte in contexte
+            except Exception,e :
+                if verbeux :
+                    import traceback
+                    traceback.print_exc()
+                    developpeur.sortie.write( "\n\n\n" )
+                    message.MESSAGE( "Exception interceptee" )
+                    scrute.SCRUTE( texte )
+                    scrute.SCRUTE( contexte )
+                    scrute.SCRUTE( e.__class__.__name__ )
+                    scrute.SCRUTE( str(e) )
+                    developpeur.sortie.write( "\n\n\n" )
+                    developpeur.sortie.flush()
+                raise 
+
+
+else :
+    class EXEC : pass
+
+
+
+
+if __name__ == "__main__" :
+    class Ex(Exception) : pass
+    def toto() :
+        print "toto"
+        raise Ex( "y a bel et bien un erreur" )
+
+    def tutu() :
+        s = "toto()"
+        EXEC( s , verbeux=1)
+
+    try :
+        tutu()
+    except Exception,ee :
+        scrute.SCRUTE(str(ee))
+        scrute.SCRUTE(ee.__class__)
+        pass
diff --git a/Utilites/funcname.py b/Utilites/funcname.py
new file mode 100644 (file)
index 0000000..bd27291
--- /dev/null
@@ -0,0 +1,100 @@
+import re,types
+import sys
+
+sortie=sys.stderr
+sortie.write( "import de "+__name__+" : $Id$" )
+sortie.write( "\n" )
+
+def get_nombre_de_blancs( str ) :
+    nombre_de_blancs=0
+    if str :
+        nombre_de_blancs=len(re.sub( "[^ ].*$" , "" , str ))
+    return nombre_de_blancs
+
+
+
+def get_classname( filename, lineno ) :
+    """
+        Cette méthode sert à trouver dans quelle classe (le cas échéant)
+        se trouve l'instruction numéro lineno dans le fichier filename.
+    """
+    classname = ""
+    current_func = ""
+    assert(type(filename)==types.StringType)
+    ####print "RECHERCHE de la classe de "+filename+" ligne : ",lineno
+    if lineno>0 :
+        try :
+               f=open( filename , 'r' )
+       except Exception,e :
+               print ">>>>",str(e)
+               sys.stdout.flush()
+               sys.exit(17)
+
+        s = f.read()
+        f.close()
+        l_lines = s.split( '\n' )
+        k=1
+        inst = l_lines[lineno]
+        nb_blancs= get_nombre_de_blancs( inst )
+
+        for line in l_lines :
+            if k == lineno :
+                break
+            elif re.search( "^ *def ", line ) != None :
+                if get_nombre_de_blancs( line ) < nb_blancs :
+                    current_func=re.sub( "^ *def  *" , "" , line )
+                    current_func=re.sub( " *\(.*$" , "" , current_func )
+            elif re.search( "^class ", line ) != None :
+                classname = re.sub( "^class  *" , "" , line )
+                classname = re.sub( " *[(:].*$" , "" , classname )
+               current_func = ""
+            elif current_func != "" and re.search( "^[^ \t]", line ) != None :
+               current_func = ""
+               classname = ""
+            k = k+1
+    if current_func == "" : current_func="__main__"
+    return classname ,current_func
+
+
+
+
+class FUNCNAME :
+
+    """
+        Conversion des 3 informations nom de méthode, nom de fichier
+        numéro de ligne en un nom complet de méthode
+    """
+
+    def __init__ ( self , *args ) :
+
+       # le premier argument est optionnel (c'est un nom de fonction 
+        # qu'on peut reconstituer avec le nom du fichier et le numéro de ligne.
+        k=0
+        self.name = None
+        if len(args)>2 :
+            if args[k] != "" : self.name = args[k]
+            k = k+1
+
+        assert(args[k]!=None)
+        assert(args[k]!="")
+        self.filename = args[k]        # recuperation du nom du fichier source
+
+        k = k+1
+        assert(args[k]>0)
+        self.lineno = args[k]  # recupération du numero de ligne
+
+        self.classname,funcname = get_classname( self.filename, self.lineno )
+        if self.name == None : self.name = funcname
+        ###assert(funcname==self.name or self.name=="main" or self.name=="<lambda>" ), "attendue '"+self.name+"' - trouvee '"+funcname+"'"
+
+    def __str__ ( self ) :
+        if self.classname != "" :
+            name=self.classname+"."+self.name
+        else :
+            name=self.name
+        return name
+
+
+if __name__ == "__main__" :
+       print  'FUNCNAME("","funcname.py", 68)='+str(FUNCNAME("","funcname.py", 63) )
+       print  'FUNCNAME("funcname.py", 68)='+str(FUNCNAME("funcname.py", 63) )
index fdfa8c9c4af25f3a101452ecaca5f5b06f87126d..cd79c6aca3a617cbadf9e12e99c90ae9c1aa59bc 100644 (file)
@@ -5,52 +5,67 @@ Module ici
     le fichier courant et le numéro de la ligne courante.
 """
 
-import sys
-sortie=sys.stderr
-sortie.write( "import de "+__name__+" : $Id$" )
-sortie.write( "\n" )
+try :
+       from developpeur import DEVELOPPEUR
+except :
+       DEVELOPPEUR=None
 
-def ICI(offset=1) :
+def NULL( *l_args, **d_args  ) : pass
 
-    """
-    Fonction ICI
-    ------------
-    La fonction ICI affiche sur la stderr, le nom du fichier qui l'appelle,
-    le numéro de la ligne ou elle est appelée et retourne ces deux informations.
+if DEVELOPPEUR :
 
-    Usage :
-        from ici import ICI
-        ICI()
-        filename,lineno=ICI()
-    """
+    import developpeur
+    developpeur.sortie.write( "import de "+__name__+" : $Id$" )
+    developpeur.sortie.write( "\n" )
 
-    sortie=sys.stderr
+    import sys
 
-    sys.stdout.flush()
-    sys.stderr.flush()
-    try :
-        1/0
-    except :
+    def ICI(offset=1) :
+    
+        """
+        Fonction ICI
+        ------------
+        La fonction ICI affiche sur la stderr, le nom du fichier qui l'appelle,
+        le numéro de la ligne ou elle est appelée et retourne ces deux informations.
+    
+        Usage :
+            from ici import ICI
+            ICI()
+            filename,lineno=ICI()
 
-        ###f=sys.exc_info()[2].tb_frame.f_back
-        ###lineno=f.f_lineno
-        ###code=f.f_code
-        ###filename=code.co_filename
+        N.B. : la fonction ICI n'est opérante que pour les développeurs
+        """
+    
+        sys.stdout.flush()
+        sys.stderr.flush()
+        try :
+            1/0
+        except :
+            ###f=sys.exc_info()[2].tb_frame.f_back
+            ###lineno=f.f_lineno
+            ###code=f.f_code
+            ###filename=code.co_filename
+    
+            import traceback
+            trace=traceback.extract_stack()
+    
+            indice = len(trace)-(2+offset)
+            if indice<0 : indice=0
+    
+    
+            assert( indice<len(trace) ),"valeur de offset INVALIDE : "+str(offset)+" taille de la table "+len(trace)
+            file_name, lineno, func_name, dummytxt = trace[ indice ]
+    
+            assert( (indice>0) or (func_name=="?") )
+            if func_name=="?" : func_name = "main"
+    
+        if offset >= 0 :
+                import funcname
+                developpeur.sortie.write( file_name+':'+str(lineno)+': ('+str(funcname.FUNCNAME(func_name,file_name,lineno))+') : ' )
+                developpeur.sortie.flush()
+    
+        return file_name,lineno
 
-        import traceback
-        trace=traceback.extract_stack()
 
-        indice = len(trace)-(2+offset)
-        if indice<0 : indice=0
-
-
-        assert( indice<len(trace) ),"valeur de offset INVALIDE : "+str(offset)+" taille de la table "+len(trace)
-        file, lineno, funcname, dummytxt = trace[ indice ]
-
-        assert( (indice>0) or (funcname=="?") )
-        if funcname=="?" : funcname = "main"
-
-        sortie.write( file+':'+str(lineno)+': ('+funcname+') : ' )
-        sortie.flush()
-
-    return file,lineno
+else :
+       ICI = NULL
index 90b41c3a4fd1a32dc9432d1bc52ce5cb995a0e52..fa94124ae0628b6c2bc5b60de58bdf6de3ff8390 100644 (file)
@@ -3,70 +3,88 @@ Module message
 --------------
     le module message propose la fonction MESSAGE pour afficher
     sur la stderr, le texte passé en argument.
+    N.B. : la fonction MESSAGE n'est opérante que pour les développeurs
+           (la variable DEVELOPPEUR doit être définie)
 """
 
-import sys
-sortie=sys.stderr
-sortie.write( "import de "+__name__+" : $Id$" )
-sortie.write( "\n" )
+try :
+       from developpeur import DEVELOPPEUR
+except :
+       DEVELOPPEUR=None
 
-def MESSAGE( text , offset=1 ) :
+def NULL( *l_args, **d_args  ) : pass
 
-    """
-    Fonction MESSAGE
-    ----------------
-    La fonction MESSAGE affiche sur la stderr, le texte passé en argument.
-    Elle précise également le nom du fichier et le numéro de la ligne où
-    elle a été appelée.
+if DEVELOPPEUR :
 
-    Usage :
+    import developpeur
+    developpeur.sortie.write( "import de "+__name__+" : $Id$" )
+    developpeur.sortie.write( "\n" )
+
+    import sys
+    import ici
+
+    def MESSAGE( text , offset=1 ) :
+
+        """
+        Fonction MESSAGE
+        ----------------
+        La fonction MESSAGE affiche sur la stderr, le texte passé en argument.
+        Elle précise également le nom du fichier et le numéro de la ligne où
+        elle a été appelée.
+
+        Usage :
         from message import MESSAGE
 
         MESSAGE("debut du traitement")
         MESSAGE( "Exception interceptée "+str(e) )
-    """
+        """
+
+        ici.ICI( offset )
+        developpeur.sortie.write( str(text)+'\n' )
+        developpeur.sortie.flush()
+        return
 
-    sortie=sys.stderr
 
-    import ici
-    ici.ICI( offset )
-    sortie.write( str(text)+'\n' )
-    sortie.flush()
-    return
 
+    def DEBUT() :
 
+        """
+        Fonction DEBUT
+        --------------
+        La fonction DEBUT affiche sur la stderr, le texte signalant le début
+        d'un traitement
 
-def DEBUT() :
+        Usage :
+            from message import *
+            DEBUT()
+            N.B. : la fonction DEBUT n'est opérante que pour les développeurs
+        """
 
-    """
-    Fonction DEBUT
-    --------------
-    La fonction DEBUT affiche sur la stderr, le texte signalant le début
-    d'un traitement
+        developpeur.sortie.write( '\n\n' )
+        MESSAGE("DEBUT du traitement [",offset=2)
+        return
 
-    Usage :
-        from message import *
-        DEBUT()
-    """
 
-    MESSAGE("DEBUT du traitement",offset=2)
-    return
 
+    def FIN() :
 
+        """
+        Fonction FIN
+        ------------
+        La fonction FIN affiche sur la stderr, le texte signalant la fin
+        d'un traitement
 
-def FIN() :
+        Usage :
+            from message import *
+            FIN()
 
-    """
-    Fonction FIN
-    ------------
-    La fonction FIN affiche sur la stderr, le texte signalant la fin
-    d'un traitement
+            N.B. : la fonction FIN n'est opérante que pour les développeurs
+        """
 
-    Usage :
-        from message import *
-        FIN()
-    """
+        MESSAGE("] FIN du traitement",offset=2)
+        return
 
-    print
-    MESSAGE("FIN du traitement",offset=2)
-    return
+else :
+    MESSAGE= NULL
+    DEBUT = NULL
+    FIN = NULL
diff --git a/Utilites/modification.py b/Utilites/modification.py
new file mode 100644 (file)
index 0000000..f5f8e6b
--- /dev/null
@@ -0,0 +1,46 @@
+"""
+Module intervention
+-------------------
+    Permet aux développeurs de signer leur intervention à
+    destination des autres développeurs.
+"""
+
+try :
+       from developpeur import DEVELOPPEUR
+except :
+       DEVELOPPEUR=None
+
+def NULL( *l_args, **d_args  ) : pass
+
+
+if DEVELOPPEUR :
+
+    import developpeur
+    developpeur.sortie.write( "import de "+__name__+" : $Id$" )
+    developpeur.sortie.write( "\n" )
+    import ici
+
+    def MODIFICATION( text , offset=1 ) :
+    
+        """
+        Fonction MODIFICATION
+        ---------------------
+    
+        Usage :
+            from utilites import MODIFICATION
+    
+            utilites.MODIFICATION("auteur,date et intention")
+        """
+    
+        ici.ICI( offset )
+        developpeur.sortie.write( "MODIFICATION "+str(text)+'\n' )
+        developpeur.sortie.flush()
+        return
+
+
+else :
+    MODIFICATION = NULL
+        
+
+if __name__ == "__main__" :
+    MODIFICATION( "baratin inutile" )
index 40d23a8e93102fbe9cb34df3de635c7f312b454f..d7dcafa86116d1b4c29221bc32584d418a58ae32 100644 (file)
@@ -4,42 +4,54 @@ Module pause
     le module pause propose la fonction PAUSE pour effectuer
     une attente.
 """
+try :
+       from developpeur import DEVELOPPEUR
+except :
+       DEVELOPPEUR=None
 
-import sys
-sortie=sys.stderr
-sortie.write( "import de "+__name__+" : $Id$" )
-sortie.write( "\n" )
+def NULL( *l_args, **d_args  ) : pass
 
-def PAUSE( secondes ) :
+if DEVELOPPEUR :
 
-    """
+    import developpeur
+    developpeur.sortie.write( "import de "+__name__+" : $Id$" )
+    developpeur.sortie.write( "\n" )
 
-    Fonction PAUSE
-    ----------------
-    La fonction PAUSE permet d'interrompre le traitement pendant un délai
-    passé en argument. La localisation de l'appel est tracée sur la stderr
+    import sys
+    import ici
+    
+    def PAUSE( secondes ) :
+    
+        """
+    
+        Fonction PAUSE
+        ----------------
+        La fonction PAUSE permet d'interrompre le traitement pendant un délai
+        passé en argument. La localisation de l'appel est tracée sur la stderr
+    
+        Usage :
+            from pause import PAUSE
+    
+            PAUSE(secondes=5)
+        """
+    
+        if secondes > 0 :
+            developpeur.sortie.write( "\n\n\n" )
+            ici.ICI()
+                
+            developpeur.sortie.write( "pause de "+str(secondes)+" secondes" )
+            developpeur.sortie.write( "\n\n\n" )
+            developpeur.sortie.flush()
+    
+            import time
+            time.sleep( secondes )
+    
+        developpeur.sortie.flush()
+    
+        return
 
-    Usage :
-        from pause import PAUSE
-
-        PAUSE(secondes=5)
-    """
-
-    if secondes > 0 :
-        sortie.write( "\n\n\n" )
-        import ici
-        ici.ICI()
-            
-        sortie.write( "pause de "+str(secondes)+" secondes" )
-        sortie.write( "\n\n\n" )
-        sortie.flush()
-
-        import time
-        time.sleep( secondes )
-
-    sortie.flush()
-
-    return
+else :
+    PAUSE = NULL
 
 
 if __name__ == "__main__" :
index 151155ea81e71bb1648cb672141f249917770b6c..90ade3563b6e2822861e11937e14b5ea52fbcc6c 100644 (file)
 """
 Module scrute
 -------------
-    le module scrute propose la fonction SCRUTE qui affiche sur
+    Le module scrute propose la fonction SCRUTE qui affiche sur
     la stderr, la valeur de l'objet (passé en argument)
     précédée le nom de l'objet.
+    Il propose également la fonction EXAMINE qui détaille sur
+    la stderr le contenu d'un objet
+    
+    N.B. : les fonctions SCRUTE e EXAMINE ne sont opérantes que pour les développeurs
+           (la variable DEVELOPPEUR doit être définie)
 """
 
-import sys
-sortie=sys.stderr
-sortie.write( "import de "+__name__+" : $Id$" )
-sortie.write( "\n" )
+try :
+       from developpeur import DEVELOPPEUR
+except :
+       DEVELOPPEUR=None
 
+def NULL( *l_args, **d_args  ) : pass
 
-def SCRUTE( valeur ) :
+if DEVELOPPEUR :
 
-    """
-    Fonction SCRUTE
-    ---------------
-    La fonction SCRUTE affiche sur la stderr, la valeur (passée en argument)
-    d'une variable précédée de son nom.
-    L'affichage précise également le nom du fichier et le numéro
-    de la ligne où la fonction SCRUTE a été appelée.
+    import developpeur
+    developpeur.sortie.write( "import de "+__name__+" : $Id$" )
+    developpeur.sortie.write( "\n" )
+    import re
+    import linecache
+    import ici
+    import sys
+
+    def SCRUTE( valeur ) :
+
+        """
+        Fonction SCRUTE
+        ---------------
+        La fonction SCRUTE affiche sur la stderr, la valeur (passée en argument)
+        d'une variable précédée de son nom.
+        L'affichage précise également le nom du fichier et le numéro
+        de la ligne où la fonction SCRUTE a été appelée.
 
-    N.B. : le type de la variable doit posséder de préférence une méthode __str__
+        N.B. : le type de la variable doit posséder de préférence une méthode __str__
 
-    Usage :
+        Usage :
         from scrute import SCRUTE
         r=1.0
         SCRUTE(r)
         SCRUTE(r+1)
         SCRUTE(f(r))
-    Erreur :
+        Erreur :
         SCRUTE(r) ; SCRUTE(f(r)) # ==> ERREUR
-    """
+        """
 
-    import re
-    import linecache
-    import ici
 
-    filename,lineno=ici.ICI()
+        filename,lineno=ici.ICI()
 
-    line = linecache.getline( filename, lineno )
+        line = linecache.getline( filename, lineno )
 
-    ll=re.sub( "\s*#.*$" , '' ,line)
-    l_occurrences=[]
-    l_occurrences=re.findall( "SCRUTE" , ll )
-    assert(len(l_occurrences)>0),__name__+" : pas de SCRUTE trouvé !"
-    assert(len(l_occurrences)<=1),\
+        ll=re.sub( "\s*#.*$" , '' ,line)
+
+        l_occurrences=[]
+        l_occurrences=re.findall( "SCRUTE" , ll )
+        assert(len(l_occurrences)>0),__name__+" : pas de SCRUTE trouvé !"
+        assert(len(l_occurrences)<=1),\
         __name__+" : "+str(len(l_occurrences))+" SCRUTE sur la même ligne ; c'est LIMITE à 1 !"
 
-    ll=re.sub( "\s*;.*$" , '' ,line)
-    regex='^.*SCRUTE[^(]*\('
-    l=re.sub( regex , '' ,ll)
-    regex='\)[^)]*$'
-    nom_objet=re.sub( regex , '' ,l)
-
-    try :
-        sortie.write( nom_objet+'=' )
-        sortie.write( str(valeur) )
-        sortie.write( " ("+str(type(valeur))+")" )
-    except : pass
-    sortie.write( '\n' )
-    sortie.flush()
-
-    return
+        ll=re.sub( "\s*;.*$" , '' ,line)
+        regex='^.*SCRUTE[^(]*\('
+        l=re.sub( regex , '' ,ll)
+        regex='\)[^)]*$'
+        nom_objet=re.sub( regex , '' ,l)
+
+        try :
+            developpeur.sortie.write( nom_objet+'=' )
+            s=str(valeur)
+            developpeur.sortie.write( s )
+            developpeur.sortie.write( " ("+str(type(valeur))+")" )
+        except : pass
+        developpeur.sortie.write( '\n' )
+        developpeur.sortie.flush()
+
+        return
+
+    def makeClassName( ob ) :
+        import types
+        if type(ob) == types.InstanceType :
+            return str(ob.__class__)
+        else :
+            return str(type(ob))
+        
+
+    def EXAMINE( ob ) :
+        """
+        Affiche sur la developpeur.sortie le contenu d'un objet
+
+        Usage :
+            class KLASS : pass
+            import Utilites
+            object=KLASS()
+            Utilites.EXAMINE(object)
+        """
+
+        appel_EXAMINE=1
+        f = sys._getframe( appel_EXAMINE )
+        context=f.f_locals
+
+        filename,lineno=ici.ICI()
+        line = linecache.getline( filename, lineno )
+        nom=re.sub( "^.*EXAMINE *\(", "" , line )
+        nom=re.sub( " *[,\)].*$", "" , nom )
+        nom=re.sub( "\n", "" , nom )
+        developpeur.sortie.write( "Examen de "+nom+" de type "+makeClassName(ob)+"\n" )
+
+        for att in dir(ob) :
+            st=nom+'.'+att
+            developpeur.sortie.write( '\t'+st+' = ' )
+            developpeur.sortie.flush()
+            commande="import developpeur;developpeur.sortie.write( str("+st+")+'\\n' )"
+            try :
+                exec commande in context
+            except :
+                commande="import sys; sys.stderr.write( str("+st+")+'\\n' )"
+                exec commande in context
+            
+        return
+
+
+else :
+
+    SCRUTE = NULL
+    EXAMINE = NULL