Merge "make_app() now uses the debugger param in DebugMiddleware()"

This commit is contained in:
Jenkins 2015-04-29 20:25:29 +00:00 committed by Gerrit Code Review
commit d907987e70
5 changed files with 76 additions and 12 deletions

View File

@ -29,11 +29,24 @@ browser for easy debugging:
To further aid in debugging, the middleware includes the ability to repeat the
offending request, automatically inserting a breakpoint, and dropping your
console into the Python debugger, ``pdb``:
console into the Python debugger, ``pdb.post_mortem``:
.. figure:: debug-middleware-2.png
:alt: Pecan debug middleware request debugger.
You can also use any debugger with a suitable ``post_mortem`` entry point.
For example, to use the `PuDB Debugger <http://pypi.python.org/pypi/pudb>`_,
set ``debugger`` like so::
import pudb
app = {
...
'debug': True,
'debugger': pudb.post_mortem,
...
}
.. seealso::
Refer to the `pdb documentation

View File

@ -4,19 +4,16 @@ from .core import (
)
from .decorators import expose
from .hooks import RequestViewerHook
from .middleware.debug import DebugMiddleware
from .middleware.errordocument import ErrorDocumentMiddleware
from .middleware.recursive import RecursiveMiddleware
from .middleware.static import StaticFileMiddleware
from .configuration import set_config, Config
from .configuration import _runtime_conf as conf
from . import middleware
try:
from logging.config import dictConfig as load_logging_config
except ImportError:
from logutils.dictconfig import dictConfig as load_logging_config # noqa
import six
import warnings
@ -40,6 +37,8 @@ def make_app(root, **kw):
debug mode is set.
:param debug: A flag to enable debug mode. This enables the debug
middleware and serving static files.
:param debugger: A callable to start debugging, defaulting to the Python
debugger entry point ``pdb.post_mortem``.
:param wrap_app: A function or middleware class to wrap the Pecan app.
This must either be a wsgi middleware class or a
function that returns a wsgi application. This wrapper
@ -90,19 +89,28 @@ def make_app(root, **kw):
# Configuration for serving custom error messages
errors = kw.get('errors', getattr(conf.app, 'errors', {}))
if errors:
app = ErrorDocumentMiddleware(app, errors)
app = middleware.errordocument.ErrorDocumentMiddleware(app, errors)
# Included for internal redirect support
app = RecursiveMiddleware(app)
app = middleware.recursive.RecursiveMiddleware(app)
# When in debug mode, load our exception dumping middleware
static_root = kw.get('static_root', None)
if debug:
app = DebugMiddleware(app)
debugger = kw.get('debugger', None)
debugger_kwargs = {}
if six.callable(debugger):
debugger_kwargs['debugger'] = debugger
elif debugger:
warnings.warn(
"`app.debugger` is not callable, ignoring",
RuntimeWarning
)
app = middleware.debug.DebugMiddleware(app, **debugger_kwargs)
# Support for serving static files (for development convenience)
if static_root:
app = StaticFileMiddleware(app, static_root)
app = middleware.static.StaticFileMiddleware(app, static_root)
elif static_root:
warnings.warn(

View File

@ -0,0 +1,4 @@
from . import debug
from . import errordocument
from . import recursive
from . import static

View File

@ -253,7 +253,10 @@ class DebugMiddleware(object):
To further aid in debugging, the middleware includes the ability to repeat
the offending request, automatically inserting a breakpoint, and dropping
your console into the Python debugger, ``pdb``.
your console into the Python debugger, ``pdb.post_mortem``.
You can also use any debugger with a suitable ``post_mortem`` entry point
such as the `PuDB Debugger <http://pypi.python.org/pypi/pudb>`_,
For more information, refer to the `documentation for pdb
<http://docs.python.org/library/pdb.html>`_ available on the Python
@ -261,7 +264,7 @@ class DebugMiddleware(object):
:param app: the application to wrap.
:param debugger: a callable to start debugging, defaulting to the Python
debugger, ``pdb``.
debugger entry point ``pdb.post_mortem``.
"""
def __init__(self, app, debugger=pdb.post_mortem):

View File

@ -5,6 +5,7 @@ import warnings
import webob
from webob.exc import HTTPNotFound
import mock
from webtest import TestApp
import six
from six import b as b_
@ -1616,6 +1617,41 @@ class TestNonCanonical(PecanTestCase):
assert len(wrapped_apps) == 1
class TestDebugging(PecanTestCase):
def test_debugger_setup(self):
class RootController(object):
pass
def debugger():
pass
app_conf = dict(
debug=True,
debugger=debugger
)
with mock.patch('pecan.middleware.debug.DebugMiddleware') \
as patched_debug_middleware:
app = make_app(RootController(), **app_conf)
args, kwargs = patched_debug_middleware.call_args
assert kwargs.get('debugger') == debugger
def test_invalid_debugger_setup(self):
class RootController(object):
pass
debugger = 'not_a_valid_entry_point'
app_conf = dict(
debug=True,
debugger=debugger
)
with mock.patch('pecan.middleware.debug.DebugMiddleware') \
as patched_debug_middleware:
app = make_app(RootController(), **app_conf)
args, kwargs = patched_debug_middleware.call_args
assert kwargs.get('debugger') is None
class TestLogging(PecanTestCase):
def test_logging_setup(self):