This howTo includes tips and tricks on debugging ERP5 (and is in dire need of an update!)
Table of Contents
ERP5 uses psyco when available (usually on all 32bits machines), but psyco
disable pdb, so if you want to use pdb, you'll have to disable psyco manually.
If you have a recent ERP5Type product, you can modify Products/ERP5Type/PsycoWrapper.py
to use the dummy psyco module (you should understand by looking at this code).
If you use older version, you have to create a dummy psyco.py in your PYTHONPATH, containing, for example:
def bind(*args, **kw):
Make sure this psyco module will be the first in your python path, for example
by putting it in $INSTANCE_HOME/lib/python/psyco.py
Below shell code will automagically create needed file:
mkdir -p $INSTANCE_HOME/lib/python
echo -e "def bind(*args, **kawrgs):\n pass" > $INSTANCE_HOME/lib/python/psyco.py
The simplest solution is to use:
import pdb; pdb.set_trace()
Somewhere in python code. To have console attached start zope in foreground mode:
For python scripts, you are not allowed to use pdb directly. One solution is
create one external method with the previous code. Other solution is use zdb.
zdb is a Zope Product that allows use set_trace inside PythonScripts directly at
from Products.zdb import set_trace; set_trace()
To have console attached start zope in foreground mode:
You might know already, that it is possible to debug zope using zopectl debug
facility. There are some ERP5-specific issues related.
After invoking zopectl debug you need to wrap site with a REQUEST using:
from Testing.makerequest import makerequest
portal = makerequest(app.erp5)
Where erp5 is name of your site.
You might also like to have some privileges while debugging, to achieve it use following code:
user = app.erp5.acl_users.getUserById('username')
user = user.__of__(app.erp5.acl_users)
from AccessControl.SecurityManagement import newSecurityManager
Substitute app.erp5.acl_users with your user folder and username with username to which you'd like to login.
If you want to use PDBDebugMode, and are using iHotfix, you have to apply this
patch to Products/iHotfix:
diff -u iHotfix.orig/__init__.py iHotfix/__init__.py
--- iHotfix.orig/__init__.py 2008-09-23 12:06:02.707936781 -0400
+++ iHotfix/__init__.py 2008-09-23 12:06:34.418025744 -0400
@@ -72,7 +72,7 @@
_the_lock = allocate_lock()
-def new_publish(zope_request, module_name, after_list, debug=0):
+def new_publish(zope_request, module_name, after_list, debug=0, **kw):
# Build the Context instance, a wrapper around the Zope request
context = Context(zope_request)
# Store it
@@ -85,7 +85,7 @@
- x = Publish.zope_publish(zope_request, module_name, after_list, debug)
+ x = Publish.zope_publish(zope_request, module_name, after_list, debug, **kw)
# Remove the context object.
# When conflicts occur the "publish" method is called again,
While using zopectl debug you'll observe that activities aren't invoked - you
can invoke them using this:
To synchronise your debug session with current Zope state you need to use such snippet:
To change the content of a python script ('Python_script' in the above example) :
(Pdb) open('/tmp/x.py', 'w').write(context.Python_script.document_src())
Edit the file /tmp/x.py and edit the Python script:
You can add this to your .pdbrc :
alias edit import os; open('/tmp/x.py', 'w').write(%1.document_src());
os.system('%s /tmp/x.py' % os.environ.get('EDITOR', 'vim'));
and then use the macro like that:
(Pdb) edit context.Python_script
alias whoami from AccessControl import getSecurityManager; getSecurityManager().getUser()
It is quite common practice to copy problematic Data.fs file to test machine.
But SQL connection strings are hardcoded, so it is possible, that after running
this Data.fs it will connect to original database - that would be disaster - or,
it won't be possible to run this Data.fs as MySQL database won't be available.
There is solution. Run zopectl debug, use above snippets to fetch portal, then
edit erp5_sql_connection, erp5_sql_deferred_connection and erp5_sql_transactionless_connection.
# portal is fetched already
>>> portal.erp5_sql_connection.connection_string = 'new connection string'
>>> portal.erp5_sql_deferred_connection.connection_string = 'new connection string'
>>> portal.erp5_sql_transactionless_connection.connection_string = 'new connection string'
Now after starting Zope ERP5 will use new connection string.
Note: /!\ Same might apply to configuring portal activities' load balancing system offline.
To script above change you might use pipes, eg:
bash$ echo -e "portal.erp5_sql_connection.connection_string =
'new connection string'\nportal.erp5_sql_deferred_connection.connection_string =
'new connection string'\nportal.erp5_sql_transactionless_connection.connection_string =
'new connection'\nget_transaction().commit()\n" | zopectl debug