CHANGES.txt
@@ -1,18 +1,27 @@ Next release ============ Features -------- - Added ``debug_matched`` configuration setting that logs matched routes (including the matchdict and predicates). 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_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. 1.0a6 (2010-12-15) ================== docs/narr/MyProject/development.ini
@@ -3,7 +3,7 @@ reload_templates = true debug_authorization = false debug_notfound = false debug_matched = false debug_routematch = false debug_templates = true default_locale_name = en docs/narr/environment.rst
@@ -97,6 +97,21 @@ | | | +---------------------------------+-----------------------------+ 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 ------------- docs/narr/urldispatch.rst
@@ -1268,6 +1268,37 @@ .. 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 ---------- docs/tutorials/wiki/src/authorization/development.ini
@@ -3,7 +3,7 @@ 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] docs/tutorials/wiki/src/basiclayout/development.ini
@@ -3,7 +3,7 @@ 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] docs/tutorials/wiki/src/models/development.ini
@@ -3,7 +3,7 @@ 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] docs/tutorials/wiki/src/viewdecorators/development.ini
@@ -3,7 +3,7 @@ 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] docs/tutorials/wiki/src/views/development.ini
@@ -3,7 +3,7 @@ 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] docs/tutorials/wiki2/src/authorization/development.ini
@@ -3,7 +3,7 @@ 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 docs/tutorials/wiki2/src/basiclayout/development.ini
@@ -3,7 +3,7 @@ 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 docs/tutorials/wiki2/src/models/development.ini
@@ -3,7 +3,7 @@ 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 docs/tutorials/wiki2/src/views/development.ini
@@ -3,7 +3,7 @@ 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 pyramid/paster_templates/alchemy/development.ini_tmpl
@@ -3,7 +3,7 @@ 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 pyramid/paster_templates/pylons_basic/development.ini_tmpl
@@ -4,7 +4,7 @@ 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 pyramid/paster_templates/pylons_minimal/development.ini_tmpl
@@ -4,7 +4,7 @@ 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 pyramid/paster_templates/pylons_sqla/development.ini_tmpl
@@ -3,7 +3,7 @@ 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 pyramid/paster_templates/routesalchemy/development.ini_tmpl
@@ -3,7 +3,7 @@ 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 pyramid/paster_templates/starter/development.ini_tmpl
@@ -3,7 +3,7 @@ reload_templates = true debug_authorization = false debug_notfound = false debug_matched = false debug_routematch = false debug_templates = true default_locale_name = en pyramid/paster_templates/starter_zcml/development.ini_tmpl
@@ -3,7 +3,7 @@ reload_templates = true debug_authorization = false debug_notfound = false debug_matched = false debug_routematch = false debug_templates = true default_locale_name = en pyramid/paster_templates/zodb/development.ini_tmpl
@@ -3,7 +3,7 @@ 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 pyramid/router.py
@@ -30,7 +30,7 @@ implements(IRouter) debug_notfound = False debug_matched = False debug_routematch = False threadlocal_manager = manager @@ -46,7 +46,7 @@ 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 @@ 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 @@ 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) pyramid/settings.py
@@ -29,9 +29,9 @@ 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 @@ 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, pyramid/tests/test_router.py
@@ -36,7 +36,7 @@ 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 @@ 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 @@ 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 pyramid/tests/test_settings.py
@@ -24,7 +24,7 @@ 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 @@ {'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 @@ 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)