diff options
| author | Chris McDonough <chrism@plope.com> | 2010-12-16 15:03:15 -0500 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2010-12-16 15:03:15 -0500 |
| commit | 24bf2a83c5172e6974c997495e8f1c7922394617 (patch) | |
| tree | b27072f09db57924ec22179538e9cf42204098be | |
| parent | a61f345b414bb4529c2a5927a73192ce874ab001 (diff) | |
| download | pyramid-24bf2a83c5172e6974c997495e8f1c7922394617.tar.gz pyramid-24bf2a83c5172e6974c997495e8f1c7922394617.tar.bz2 pyramid-24bf2a83c5172e6974c997495e8f1c7922394617.zip | |
Features
--------
- Added ``debug_routematch`` configuration setting that logs matched routes
(including the matchdict and predicates).
Documentation
-------------
- Added "Debugging Route Matching" section to the urldispatch narrative
documentation chapter.
- Added reference to ``BFG_DEBUG_ROUTEMATCH`` envvar and ``debug_routematch``
config file setting to the Environment narrative docs chapter.
25 files changed, 143 insertions, 59 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 5f9cb3d05..9752df196 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,17 +1,26 @@ Next release ============ +Bug Fixes +--------- + +- Make it possible to succesfully run all tests via ``nosetests`` command + directly (rather than indirectly via ``python setup.py nosetests``). + Features -------- -- Added ``debug_matched`` configuration setting that logs matched routes +- Added ``debug_routematch`` configuration setting that logs matched routes (including the matchdict and predicates). -Bug Fixes ---------- +Documentation +------------- -- Make it possible to succesfully run all tests via ``nosetests`` command - directly (rather than indirectly via ``python setup.py nosetests``). +- Added "Debugging Route Matching" section to the urldispatch narrative + documentation chapter. + +- Added reference to ``BFG_DEBUG_ROUTEMATCH`` envvar and ``debug_routematch`` + config file setting to the Environment narrative docs chapter. 1.0a6 (2010-12-15) ================== diff --git a/docs/narr/MyProject/development.ini b/docs/narr/MyProject/development.ini index 7a48b5bc5..48fc81b8c 100644 --- a/docs/narr/MyProject/development.ini +++ b/docs/narr/MyProject/development.ini @@ -3,7 +3,7 @@ use = egg:MyProject reload_templates = true debug_authorization = false debug_notfound = false -debug_matched = false +debug_routematch = false debug_templates = true default_locale_name = en diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index 44e75542c..08fa7af44 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -97,6 +97,21 @@ when this value is true. See also :ref:`debug_notfound_section`. | | | +---------------------------------+-----------------------------+ +Debugging Route Matching +------------------------ + +Print debugging messages related to :term:`url dispatch` route matching when +this value is true. See also :ref:`debug_routematch_section`. + ++---------------------------------+-----------------------------+ +| Environment Variable Name | Config File Setting Name | ++=================================+=============================+ +| ``BFG_DEBUG_ROUTEMATCH`` | ``debug_routematch`` | +| | | +| | | +| | | ++---------------------------------+-----------------------------+ + Debugging All ------------- diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index c84a5ca06..f0ace76ba 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1268,6 +1268,37 @@ not very ambitious. .. note:: See :ref:`security_chapter` for more information about :app:`Pyramid` security and ACLs. +.. _debug_routematch_section: + +Debugging Route Matching +------------------------ + +It's useful to be able to take a peek under the hood when requests that enter +your application arent matching your routes as you expect them to. To debug +route matching, use the ``BFG_DEBUG_ROUTEMATCH`` environment variable or the +``debug_routematch`` configuration file setting (set either to ``true``). +Details of the route matching decision for a particular request to the +:app:`Pyramid` application will be printed to the ``stderr`` of the console +which you started the application from. For example: + +.. code-block:: text + :linenos: + + [chrism@thinko pylonsbasic]$ BFG_DEBUG_ROUTEMATCH=true \ + bin/paster serve development.ini + Starting server in PID 13586. + serving on 0.0.0.0:6543 view at http://127.0.0.1:6543 + 2010-12-16 14:45:19,956 no route matched for url \ + http://localhost:6543/wontmatch + 2010-12-16 14:45:20,010 no route matched for url \ + http://localhost:6543/favicon.ico + 2010-12-16 14:41:52,084 route matched for url \ + http://localhost:6543/static/logo.png; \ + route_name: 'static/', .... + +See :ref:`environment_chapter` for more information about how, and where to +set these values. + References ---------- diff --git a/docs/tutorials/wiki/src/authorization/development.ini b/docs/tutorials/wiki/src/authorization/development.ini index d09da86eb..a102b721b 100644 --- a/docs/tutorials/wiki/src/authorization/development.ini +++ b/docs/tutorials/wiki/src/authorization/development.ini @@ -3,7 +3,7 @@ use = egg:tutorial reload_templates = true debug_authorization = false debug_notfound = false -debug_matched = false +debug_routematch = false zodb_uri = file://%(here)s/Data.fs?connection_cache_size=20000 [pipeline:main] diff --git a/docs/tutorials/wiki/src/basiclayout/development.ini b/docs/tutorials/wiki/src/basiclayout/development.ini index 4fb6f25f8..fdae922e9 100644 --- a/docs/tutorials/wiki/src/basiclayout/development.ini +++ b/docs/tutorials/wiki/src/basiclayout/development.ini @@ -3,7 +3,7 @@ use = egg:tutorial reload_templates = true debug_authorization = false debug_notfound = false -debug_matched = false +debug_routematch = false zodb_uri = file://%(here)s/Data.fs?connection_cache_size=20000 [pipeline:main] diff --git a/docs/tutorials/wiki/src/models/development.ini b/docs/tutorials/wiki/src/models/development.ini index 4fb6f25f8..fdae922e9 100644 --- a/docs/tutorials/wiki/src/models/development.ini +++ b/docs/tutorials/wiki/src/models/development.ini @@ -3,7 +3,7 @@ use = egg:tutorial reload_templates = true debug_authorization = false debug_notfound = false -debug_matched = false +debug_routematch = false zodb_uri = file://%(here)s/Data.fs?connection_cache_size=20000 [pipeline:main] diff --git a/docs/tutorials/wiki/src/viewdecorators/development.ini b/docs/tutorials/wiki/src/viewdecorators/development.ini index d09da86eb..a102b721b 100644 --- a/docs/tutorials/wiki/src/viewdecorators/development.ini +++ b/docs/tutorials/wiki/src/viewdecorators/development.ini @@ -3,7 +3,7 @@ use = egg:tutorial reload_templates = true debug_authorization = false debug_notfound = false -debug_matched = false +debug_routematch = false zodb_uri = file://%(here)s/Data.fs?connection_cache_size=20000 [pipeline:main] diff --git a/docs/tutorials/wiki/src/views/development.ini b/docs/tutorials/wiki/src/views/development.ini index d09da86eb..a102b721b 100644 --- a/docs/tutorials/wiki/src/views/development.ini +++ b/docs/tutorials/wiki/src/views/development.ini @@ -3,7 +3,7 @@ use = egg:tutorial reload_templates = true debug_authorization = false debug_notfound = false -debug_matched = false +debug_routematch = false zodb_uri = file://%(here)s/Data.fs?connection_cache_size=20000 [pipeline:main] diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini index 10595b4f5..b0cfd12a7 100644 --- a/docs/tutorials/wiki2/src/authorization/development.ini +++ b/docs/tutorials/wiki2/src/authorization/development.ini @@ -3,7 +3,7 @@ use = egg:tutorial reload_templates = true debug_authorization = false debug_notfound = false -debug_matched = false +debug_routematch = false debug_templates = true default_locale_name = en sqlalchemy.url = sqlite:///%(here)s/tutorial.db diff --git a/docs/tutorials/wiki2/src/basiclayout/development.ini b/docs/tutorials/wiki2/src/basiclayout/development.ini index 10595b4f5..b0cfd12a7 100644 --- a/docs/tutorials/wiki2/src/basiclayout/development.ini +++ b/docs/tutorials/wiki2/src/basiclayout/development.ini @@ -3,7 +3,7 @@ use = egg:tutorial reload_templates = true debug_authorization = false debug_notfound = false -debug_matched = false +debug_routematch = false debug_templates = true default_locale_name = en sqlalchemy.url = sqlite:///%(here)s/tutorial.db diff --git a/docs/tutorials/wiki2/src/models/development.ini b/docs/tutorials/wiki2/src/models/development.ini index 10595b4f5..b0cfd12a7 100644 --- a/docs/tutorials/wiki2/src/models/development.ini +++ b/docs/tutorials/wiki2/src/models/development.ini @@ -3,7 +3,7 @@ use = egg:tutorial reload_templates = true debug_authorization = false debug_notfound = false -debug_matched = false +debug_routematch = false debug_templates = true default_locale_name = en sqlalchemy.url = sqlite:///%(here)s/tutorial.db diff --git a/docs/tutorials/wiki2/src/views/development.ini b/docs/tutorials/wiki2/src/views/development.ini index 10595b4f5..b0cfd12a7 100644 --- a/docs/tutorials/wiki2/src/views/development.ini +++ b/docs/tutorials/wiki2/src/views/development.ini @@ -3,7 +3,7 @@ use = egg:tutorial reload_templates = true debug_authorization = false debug_notfound = false -debug_matched = false +debug_routematch = false debug_templates = true default_locale_name = en sqlalchemy.url = sqlite:///%(here)s/tutorial.db diff --git a/pyramid/paster_templates/alchemy/development.ini_tmpl b/pyramid/paster_templates/alchemy/development.ini_tmpl index 6a713bac2..bf672ef1d 100644 --- a/pyramid/paster_templates/alchemy/development.ini_tmpl +++ b/pyramid/paster_templates/alchemy/development.ini_tmpl @@ -3,7 +3,7 @@ use = egg:{{package}} reload_templates = true debug_authorization = false debug_notfound = false -debug_matched = false +debug_routematch = false debug_templates = true default_locale_name = en sqlalchemy.url = sqlite:///%(here)s/{{project}}.db diff --git a/pyramid/paster_templates/pylons_basic/development.ini_tmpl b/pyramid/paster_templates/pylons_basic/development.ini_tmpl index a6f6f77a5..186c78862 100644 --- a/pyramid/paster_templates/pylons_basic/development.ini_tmpl +++ b/pyramid/paster_templates/pylons_basic/development.ini_tmpl @@ -4,7 +4,7 @@ reload_templates = true mako.directories = {{package}}:templates debug_authorization = false debug_notfound = false -debug_matched = false +debug_routematch = false debug_templates = true default_locale_name = en session.type = file diff --git a/pyramid/paster_templates/pylons_minimal/development.ini_tmpl b/pyramid/paster_templates/pylons_minimal/development.ini_tmpl index c66756738..b8844b2fc 100644 --- a/pyramid/paster_templates/pylons_minimal/development.ini_tmpl +++ b/pyramid/paster_templates/pylons_minimal/development.ini_tmpl @@ -4,7 +4,7 @@ reload_templates = true mako.directories = {{package}}:templates debug_authorization = false debug_notfound = false -debug_matched = false +debug_routematch = false debug_templates = true default_locale_name = en session.type = file diff --git a/pyramid/paster_templates/pylons_sqla/development.ini_tmpl b/pyramid/paster_templates/pylons_sqla/development.ini_tmpl index 07768ef93..30ffef35f 100644 --- a/pyramid/paster_templates/pylons_sqla/development.ini_tmpl +++ b/pyramid/paster_templates/pylons_sqla/development.ini_tmpl @@ -3,7 +3,7 @@ use = egg:{{project}} reload_templates = true debug_authorization = false debug_notfound = false -debug_matched = false +debug_routematch = false debug_templates = true default_locale_name = en mako.directories = {{package}}:templates diff --git a/pyramid/paster_templates/routesalchemy/development.ini_tmpl b/pyramid/paster_templates/routesalchemy/development.ini_tmpl index 19cedb323..b79dfccfe 100644 --- a/pyramid/paster_templates/routesalchemy/development.ini_tmpl +++ b/pyramid/paster_templates/routesalchemy/development.ini_tmpl @@ -3,7 +3,7 @@ use = egg:{{project}} reload_templates = true debug_authorization = false debug_notfound = false -debug_matched = false +debug_routematch = false debug_templates = true default_locale_name = en sqlalchemy.url = sqlite:///%(here)s/{{project}}.db diff --git a/pyramid/paster_templates/starter/development.ini_tmpl b/pyramid/paster_templates/starter/development.ini_tmpl index 0daa76e74..574062b30 100644 --- a/pyramid/paster_templates/starter/development.ini_tmpl +++ b/pyramid/paster_templates/starter/development.ini_tmpl @@ -3,7 +3,7 @@ use = egg:{{project}} reload_templates = true debug_authorization = false debug_notfound = false -debug_matched = false +debug_routematch = false debug_templates = true default_locale_name = en diff --git a/pyramid/paster_templates/starter_zcml/development.ini_tmpl b/pyramid/paster_templates/starter_zcml/development.ini_tmpl index 0daa76e74..574062b30 100644 --- a/pyramid/paster_templates/starter_zcml/development.ini_tmpl +++ b/pyramid/paster_templates/starter_zcml/development.ini_tmpl @@ -3,7 +3,7 @@ use = egg:{{project}} reload_templates = true debug_authorization = false debug_notfound = false -debug_matched = false +debug_routematch = false debug_templates = true default_locale_name = en diff --git a/pyramid/paster_templates/zodb/development.ini_tmpl b/pyramid/paster_templates/zodb/development.ini_tmpl index 5a95a3186..110d514e6 100644 --- a/pyramid/paster_templates/zodb/development.ini_tmpl +++ b/pyramid/paster_templates/zodb/development.ini_tmpl @@ -3,7 +3,7 @@ use = egg:{{project}} reload_templates = true debug_authorization = false debug_notfound = false -debug_matched = false +debug_routematch = false debug_templates = true default_locale_name = en zodb_uri = file://%(here)s/Data.fs?connection_cache_size=20000 diff --git a/pyramid/router.py b/pyramid/router.py index 9777459f0..1b22a6a05 100644 --- a/pyramid/router.py +++ b/pyramid/router.py @@ -30,7 +30,7 @@ class Router(object): implements(IRouter) debug_notfound = False - debug_matched = False + debug_routematch = False threadlocal_manager = manager @@ -46,7 +46,7 @@ class Router(object): if settings is not None: self.debug_notfound = settings['debug_notfound'] - self.debug_matched = settings['debug_matched'] + self.debug_routematch = settings['debug_routematch'] def __call__(self, environ, start_response): """ @@ -84,7 +84,12 @@ class Router(object): if self.routes_mapper is not None: info = self.routes_mapper(request) match, route = info['match'], info['route'] - if route is not None: + if route is None: + if self.debug_routematch: + msg = ('no route matched for url %s' % + request.url) + logger and logger.debug(msg) + else: # TODO: kill off bfg.routes.* environ keys when # traverser requires request arg, and cant cope # with environ anymore (they are docs-deprecated as @@ -94,14 +99,18 @@ class Router(object): attrs['matchdict'] = match attrs['matched_route'] = route - if self.debug_matched: + if self.debug_routematch: msg = ( - 'debug_matched of url %s; path_info: %r, ' - 'route_name: %r, pattern: %r, ' + 'route matched for url %s; ' + 'route_name: %r, ' + 'path_info: %r, ' + 'pattern: %r, ' 'matchdict: %r, ' 'predicates: %r' % ( - request.url, request.path_info, - route.name, route.pattern, match, + request.url, + route.name, + request.path_info, + route.pattern, match, route.predicates) ) logger and logger.debug(msg) diff --git a/pyramid/settings.py b/pyramid/settings.py index bd7e2c227..1e49f7dd8 100644 --- a/pyramid/settings.py +++ b/pyramid/settings.py @@ -29,9 +29,9 @@ class Settings(dict): config_debug_notfound = self.get('debug_notfound', '') eff_debug_notfound = asbool(eget('BFG_DEBUG_NOTFOUND', config_debug_notfound)) - config_debug_matched = self.get('debug_matched', '') - eff_debug_matched = asbool(eget('BFG_DEBUG_MATCHED', - config_debug_matched)) + config_debug_routematch = self.get('debug_routematch', '') + eff_debug_routematch = asbool(eget('BFG_DEBUG_ROUTEMATCH', + config_debug_routematch)) config_debug_templates = self.get('debug_templates', '') eff_debug_templates = asbool(eget('BFG_DEBUG_TEMPLATES', config_debug_templates)) @@ -49,7 +49,7 @@ class Settings(dict): update = { 'debug_authorization': eff_debug_all or eff_debug_auth, 'debug_notfound': eff_debug_all or eff_debug_notfound, - 'debug_matched': eff_debug_all or eff_debug_matched, + 'debug_routematch': eff_debug_all or eff_debug_routematch, 'debug_templates': eff_debug_all or eff_debug_templates, 'reload_templates': eff_reload_all or eff_reload_templates, 'reload_resources':eff_reload_all or eff_reload_resources, diff --git a/pyramid/tests/test_router.py b/pyramid/tests/test_router.py index 299bd89cb..65a1b82a4 100644 --- a/pyramid/tests/test_router.py +++ b/pyramid/tests/test_router.py @@ -36,7 +36,7 @@ class TestRouter(unittest.TestCase): def _registerSettings(self, **kw): settings = {'debug_authorization':False, 'debug_notfound':False, - 'debug_matched':False} + 'debug_routematch':False} settings.update(kw) self.registry.settings = settings @@ -496,7 +496,7 @@ class TestRouter(unittest.TestCase): def test_call_route_matches_and_has_factory(self): from pyramid.interfaces import IViewClassifier logger = self._registerLogger() - self._registerSettings(debug_matched=True) + self._registerSettings(debug_routematch=True) self._registerRouteRequest('foo') root = object() def factory(request): @@ -529,13 +529,33 @@ class TestRouter(unittest.TestCase): self.assertEqual(len(logger.messages), 1) self.assertEqual(logger.messages[0], - "debug_matched of url http://localhost:8080" + "route matched for url http://localhost:8080" "/archives/action1/article1; " + "route_name: 'foo', " "path_info: '/archives/action1/article1', " - "route_name: 'foo', pattern: 'archives/:action/:article', " + "pattern: 'archives/:action/:article', " "matchdict: {'action': u'action1', 'article': u'article1'}, " "predicates: ()") + def test_call_route_match_miss_debug_routematch(self): + from pyramid.exceptions import NotFound + logger = self._registerLogger() + self._registerSettings(debug_routematch=True) + self._registerRouteRequest('foo') + self._connectRoute('foo', 'archives/:action/:article') + context = DummyContext() + self._registerTraverserFactory(context) + environ = self._makeEnviron(PATH_INFO='/wontmatch') + self._registerRootFactory(context) + router = self._makeOne() + start_response = DummyStartResponse() + self.assertRaises(NotFound, router, environ, start_response) + + self.assertEqual(len(logger.messages), 1) + self.assertEqual( + logger.messages[0], + 'no route matched for url http://localhost:8080/wontmatch') + def test_call_route_matches_doesnt_overwrite_subscriber_iface(self): from pyramid.interfaces import INewRequest from pyramid.interfaces import IViewClassifier diff --git a/pyramid/tests/test_settings.py b/pyramid/tests/test_settings.py index 9df7026a9..26f6b0363 100644 --- a/pyramid/tests/test_settings.py +++ b/pyramid/tests/test_settings.py @@ -24,7 +24,7 @@ class TestSettings(unittest.TestCase): settings = self._makeOne() self.assertEqual(settings['debug_authorization'], False) self.assertEqual(settings['debug_notfound'], False) - self.assertEqual(settings['debug_matched'], False) + self.assertEqual(settings['debug_routematch'], False) self.assertEqual(settings['reload_templates'], False) self.assertEqual(settings['reload_resources'], False) self.assertEqual(settings['configure_zcml'], '') @@ -110,20 +110,20 @@ class TestSettings(unittest.TestCase): {'BFG_DEBUG_NOTFOUND':'1'}) self.assertEqual(result['debug_notfound'], True) - def test_debug_matched(self): + def test_debug_routematch(self): result = self._makeOne({}) - self.assertEqual(result['debug_matched'], False) - result = self._makeOne({'debug_matched':'false'}) - self.assertEqual(result['debug_matched'], False) - result = self._makeOne({'debug_matched':'t'}) - self.assertEqual(result['debug_matched'], True) - result = self._makeOne({'debug_matched':'1'}) - self.assertEqual(result['debug_matched'], True) - result = self._makeOne({}, {'BFG_DEBUG_MATCHED':'1'}) - self.assertEqual(result['debug_matched'], True) - result = self._makeOne({'debug_matched':'false'}, - {'BFG_DEBUG_MATCHED':'1'}) - self.assertEqual(result['debug_matched'], True) + self.assertEqual(result['debug_routematch'], False) + result = self._makeOne({'debug_routematch':'false'}) + self.assertEqual(result['debug_routematch'], False) + result = self._makeOne({'debug_routematch':'t'}) + self.assertEqual(result['debug_routematch'], True) + result = self._makeOne({'debug_routematch':'1'}) + self.assertEqual(result['debug_routematch'], True) + result = self._makeOne({}, {'BFG_DEBUG_ROUTEMATCH':'1'}) + self.assertEqual(result['debug_routematch'], True) + result = self._makeOne({'debug_routematch':'false'}, + {'BFG_DEBUG_ROUTEMATCH':'1'}) + self.assertEqual(result['debug_routematch'], True) def test_debug_templates(self): result = self._makeOne({}) @@ -143,33 +143,33 @@ class TestSettings(unittest.TestCase): def test_debug_all(self): result = self._makeOne({}) self.assertEqual(result['debug_notfound'], False) - self.assertEqual(result['debug_matched'], False) + self.assertEqual(result['debug_routematch'], False) self.assertEqual(result['debug_authorization'], False) self.assertEqual(result['debug_templates'], False) result = self._makeOne({'debug_all':'false'}) self.assertEqual(result['debug_notfound'], False) - self.assertEqual(result['debug_matched'], False) + self.assertEqual(result['debug_routematch'], False) self.assertEqual(result['debug_authorization'], False) self.assertEqual(result['debug_templates'], False) result = self._makeOne({'debug_all':'t'}) self.assertEqual(result['debug_notfound'], True) - self.assertEqual(result['debug_matched'], True) + self.assertEqual(result['debug_routematch'], True) self.assertEqual(result['debug_authorization'], True) self.assertEqual(result['debug_templates'], True) result = self._makeOne({'debug_all':'1'}) self.assertEqual(result['debug_notfound'], True) - self.assertEqual(result['debug_matched'], True) + self.assertEqual(result['debug_routematch'], True) self.assertEqual(result['debug_authorization'], True) self.assertEqual(result['debug_templates'], True) result = self._makeOne({}, {'BFG_DEBUG_ALL':'1'}) self.assertEqual(result['debug_notfound'], True) - self.assertEqual(result['debug_matched'], True) + self.assertEqual(result['debug_routematch'], True) self.assertEqual(result['debug_authorization'], True) self.assertEqual(result['debug_templates'], True) result = self._makeOne({'debug_all':'false'}, {'BFG_DEBUG_ALL':'1'}) self.assertEqual(result['debug_notfound'], True) - self.assertEqual(result['debug_matched'], True) + self.assertEqual(result['debug_routematch'], True) self.assertEqual(result['debug_authorization'], True) self.assertEqual(result['debug_templates'], True) |
