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

Introduction
============

Zope 3 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.
