Using the Zope Debugger
=======================

Introduction
------------
  
Zope3 includes a mechanism to debug an object publishing request,
similar to the `Zope 2 debug mechanism`_

.. _Zope 2 debug mechanism: http://www.zope.org/Members/mcdonc/HowTos/UsingTheZopeDebugger


Setting up the environment
--------------------------

Setup your PYTHONPATH environment variable to include src. ie (unix
bash syntax):

  cd Zope3
  export PYTHONPATH=$PWD/src:$PYTHONPATH
    
To start interacting with the debugger you need to initialize the zope
application:

  $ python2.4
  >>> from zope.app.debug import Debugger
  >>> debugger = Debugger()

Note that you can pass a database file name and a site ZCML file to
the debugger:

  >>> Debugger('path/to/zodb/', 'path/to/site.zcml')
          
But you can generally let the debugger figure out where they are.
XXX In the future, the debugger should have it's own ZConfig file.


Alternatively, you can also use the ``zopectl`` script to initiate the
debugger.  It will start up the Zope 3 instance without the servers
and drop into a regular Python prompt, with the Debugger instance
bound to the ``debugger`` variable:

  $ bin/zopectl debug
  >>> debugger
  <zope.app.debug.debug.Debugger object at 0x660350>

For people with Zope 2 experience, the debugger is also available
under the name ``app``:

  >>> app
  <zope.app.debug.debug.Debugger object at 0x660350>


Using the Debugger
------------------

There are several methods you can call on the application object for
testing purposes.

Publish
~~~~~~~

The ``publish`` method executes a request as the publisher would and
prints the response headers and body:

  >>> debugger.publish(path='/folder/content_object')

Run
~~~

The ``run`` method executes a request with the publisher's normal
error handling disabled and without outputting anything.  This is
useful for use with Python's post-mortem.

  >>> debugger.run(path='/folder/content_object')
  # an exception is raised
  >>> import pdb; pdb.pm()
  # enters the python post-mortem debugger

Debug
~~~~~      

The 'debug' method starts up the publisher in the python debugger,
with an extra convenience break point, setup just before the published
object call:

  >>> debugger.debug(path='/folder/content_object')
  * Type c<cr> to jump to published object call.
  pdb> 

Arguments: All of the debugger object's debug methods take optional
arguments, the more common/useful ones...

* path - the url path to debug

* basic - user:password used for HTTP basic auth (it will be base64
  encoded by the debug method).


Accessing objects (without the debugger)
----------------------------------------

You can use the application object to open a database connection to
access your objects.  If the application object is called, it opens a
database connection and fetches the root object:

  root = debugger.root()

For example, to list the objects in the root folder:

  print list(root)

Also note that, after initializing the application, by creating the
root object, you can access any global services setup during
initialization.
