Accueil » Tutoriels Zope » Débug de zope avec ipython

Débug de zope avec ipython

Document Actions

Par gawel le 05/03/2005 18:11

Comment débuger zope avec ipython

Catégories : Zope

IPython c'est quoi ?


IPython n'est ni plus ni moin qu'un interpréteur python amélioré. Vous pouvez le trouver ici
Pourquoi utiliser IPython ? C'est très simple, il dispose de nombreuses fonctionalités qui mériterais un HowTo a lui seul.
En voici quelques une non exhaustives:
  • auto completion
  • aide en ligne en tapant un ? après n'importe quel object/méthode python
  • édition de fichier en tapant ?? après n'importe quel object/métode python

Créer son propre IPython embed

Il est possible de customiser IPython pour ses propres besoins.
Ici nous allons tout simplement ajouter des fonctionalités pour aider au débug de zope.
Voici un exemple de code:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

__version__ = '''zdb.py 1.0'''
__author__ = '''Gael Pasgrimaud <gael@gawel.org>'''

import sys

from IPython.Shell import IPShell
from IPython.iplib import InteractiveShell

class ZopeDebug(InteractiveShell):

    
''' Surclasse de l'interpréteur IPython '''

    
def _init_zope(self):
        
# ceci sert a récupérer l'app zope dans le bon espace de nom
        
# en effet, IPython place les variables trouver dans __main__
        
# dans son espace de nom interne (internal_ns)
        
if self.internal_ns.has_key('app'):
            
import Zope
            
self.user_ns['app'] = self.internal_ns['app']
            
self.user_ns['debug'] = Zope.debug
            
from AccessControl.SecurityManagement import newSecurityManager
            
self.user_ns['newSecurityManager'] = newSecurityManager

    
def magic_setuser(self,parameter_s=''):
        
# une fonction pour récupere une variable user dans son espace de nom
        
if not parameter_s:
            
print >> sys.stderr, 'Entrez un nom d\'utilisateur valid'
        
ns = self.user_ns
        
if hasattr(ns['app'],'portal'):
            
# si on a un objet portal (Plone) on récup wrap le user dans son context
            
ns['plone'] = ns['app'].plone.portal_url.getPortalObject()
            
ns['user'] = ns['app'].acl_users.getUser(parameter_s).__of__(ns['app'].plone.acl_users)
        
else:
            
# sinon on prends un user a la racine
            
ns['user'] = ns['app'].acl_users.getUserById(parameter_s)
        
# on initialise le context
        
ns['newSecurityManager'](None,ns['user'])

    
def post_config_initialization(self):
        
''' surcharge de post configiguration ipython '''
        
InteractiveShell.post_config_initialization(self)
        
# on ne veux pas de bannière
        
self.BANNER = ''
        
# on initialise notre espace de nom
        
self._init_zope()

# on creer un shell
ipshell = IPShell([],shell_class=ZopeDebug)

if __name__ != '__main__':
    
# nous sommes déjà dans un interpréteur
    
# on import __main__ pour se retrouver dans son espace de nom
    
import __main__
    
# on lance notre shell
ipshell.mainloop(sys_exit=1)

Et Zope la dedans ?

Jusqu'as présent nous avons un joli IPython customiser mais il ne nous sert a rien en dehors du context de zope.Pour récuperer son instance dans notre interpréteur, rien de plus simple. Il suffit de lancer le mode debug de zope.Attention de bien lancer zope depuis le répertoire ou se trouve zdb.py ou d'avoir zdb.py dans votre PYTHONPATH pour pouvoir l'importer.

gawel@tabatha:~/python/home/zope/Zope-2.7.4-0/bin/zopectl debug

Starting debugger (the name "app" is bound to the top-level Zope object)

>>> import zdb
In [1]: # on sait jouer avec app
In [2]: app.objectIds()
Out[2]: 
['acl_users',
 
'Control_Panel',
 
'temp_folder',
 
'session_data_manager',
 
'browser_id_manager',
 
'error_log',
 
'standard_html_header',
 
'standard_html_footer',
 
'standard_template.pt',
 
'index_html',
 
'standard_error_message',
 
'virtual_hosting',
 
'plone']
In [3]: # on sait récupérer un user
In [4]: %setuser gawel
In [5]: user.getId()
Out[5]: 'gawel'
In [6]: # on sait utiliser l'auto completion avec app
In [7]: app.object
app.objectIds              app.objectItems            app.objectMap              app.objectValues__roles__  
app.objectIds__roles__     app.objectItems__roles__   app.objectMap_d            app.objectValues_d         
app.objectIds_d            app.objectItems_d          app.objectValues           
In [7]: app.objectVal
app.objectValues           app.objectValues__roles__  app.objectValues_d         
In [7]: app.objectValues
------> app.objectValues()
Out[7]: 
[<UserFolder instance at 4179f800>,
 
<ApplicationManager instance at 417b7650>,
 
<SimpleTemporaryContainer instance at 417b7c20>,
 
<SessionDataManager instance at 417b72c0>,
 
<BrowserIdManager instance at 417b7530>,
 
<SiteErrorLog at /error_log>,
 
<DTMLMethod instance at 417b78f0>,
 
<DTMLMethod instance at 417b7860>,
 
<ZopePageTemplate at /standard_template.pt>,
 
<DTMLMethod instance at 417b7890>,
 
<DTMLMethod instance at 4179f6b0>,
 
<VirtualHostMonster instance at 4179f650>,
 
<PloneSite instance at 4179f710>]
In [8]:

Débuger une external method

Voici un petit exemple pratique. On a une external method simple que l'on désir débuger.En voici le code:

# -*- coding: utf-8 -*-
import os, sys

def ext_meth(self):
    
''' une external method qui renvois os.name '''
    
return os.name

if __name__ == '__main__':
    
# si on est dans le namespace de __main__
    
# on récupère app et on exécute notre méthode
    
global app
    
print ext_meth(app)

Ensuite on sait la débuger/modifer dans IPython a l'aide de la commande IPython %ed qui lance votre éditeur favoris et éxécute le code à la sortie

In [8]: ed ext_meth.py

Editing... done. Executing edited code...

posix

In [9]: # on change os.name par sys.patform dans notre fichier

In [10]: ed ext_meth.py

Editing... done. Executing edited code...

---------------------------------------------------------------------------

exceptions.AttributeError                            Traceback (most recent call last)



/home/gawel/python/<console> 



/usr/lib/python2.3/site-packages/IPython/Magic.py in magic_ed(self, parameter_s)

   
1469     def magic_ed(self,parameter_s = ''):

   
1470         """Alias to %edit."""

-> 1471         return self.magic_edit(parameter_s)

   
1472 

   
1473     def magic_edit(self,parameter_s = '',last_call=['','']):



/usr/lib/python2.3/site-packages/IPython/Magic.py in magic_edit(self, parameter_s, last_call)

   
1701             except IOError:

   
1702                 warn('File not found. Did you forget to save?')

-> 1703                 return

   
1704         if use_temp:

   
1705             contents = open(filename).read()



/home/gawel/python/ext_meth.py 

      
8 if __name__ == '__main__':

      
9     # si on est dans le namespace de __main__

     
10     # on récupère app et on exécute notre méthode

     
11     global app

---> 12     print ext_meth(app)



/home/gawel/python/ext_meth.py in ext_meth(self)

      
4 def ext_meth(self):

      
5     ''' une external method qui renvois os.name '''

----> 6     return sys.patform

      
7 

      
8 if __name__ == '__main__':



AttributeError: 'module' object has no attribute 'patform'

In [11]: # oups, par sys.platform !

In [12]: ed ext_meth.py

Editing... done. Executing edited code...

linux2

In [11]: 

Mot de la fin

Voila vous savez utiliser IPython pour débuger zope. J'ai fais se tutoriel car je suis tombé amoureux de IPython. J'ai mon propre shell avec de nombreuses fonctionalités en plus qui me simplifie énormement la vie. J'en suis arrivé a m'en servir plus que bash :) J'espère que cela vous auras convaincu.

Référence

Ceci est largement inspiré de la section DebuggingZopeWithPythonDebugger2 de zopewiki.org que je vous conseil de lire aussi.

Merci

Posté par ogrisel le 22/03/2005 23:00
Ca faisait un moment que je voulais m'écrire un code de custom pour lancer ipython dans le mode debug de zope. Merci pour ce bout de code,came fera gagner du temps !

Fantastic!!

Posté par rompelstilchen le 08/12/2006 12:43
Merci gawel pour ce tuto, par contre est-ce que les modifications sont appliquees dans la zodb, parceque quand je quitte (Ctrl+D) :
In [19]: %Quit
Unable to save IPython command history to file: '/root/.ipython/history'
*** ERROR *** persistent data saving failed.

Problème import Zope

Posté par fcarlier le 14/09/2007 10:12
Je viens de tester sous Zope 2.9.7 et 2.10.4

Il apparait un probleme dans l'import de zdb.py sur 'import Zope'
Voici le message :
DeprecationWarning: The Zope package has been renamed to Zope2. Import of a package named 'Zope' is deprecated and will be disabled starting in Zope 2.11.
import Zope

In [1]: app.ObjectIds()
---------------------------------------------------------------------------
exceptions.AttributeError Traceback (most recent call last)
Aidez l'AfPy

Rechercher
Dernières news AFPY
Les 6 dernières news
PyCon FR - 17-18 mai - Paris
07/05/2008 07:05
AFPyro d'Avril
24/04/2008 00:00