Issue #896 resolved

no request logging, other breakage with root=None

Anonymous created an issue

When using a [ CustomDispatcher], it is recommended to pass root=None to cherrypy.tree.mount. However, this causes some breakage. Consider the following example:



import os.path import cherrypy

d = cherrypy.dispatch.RoutesDispatcher() conf = { 'global': { 'log.screen': True, }, '/': { 'request.dispatch': d, }, '/static': { 'tools.staticdir.on': True, 'tools.staticdir.dir': os.path.abspath('static'), }, } cherrypy.quickstart(root=None, config=conf) }}}

A request for /static/foo' results in a 404, regardless of whether that file exists, and results in no logging to the console (despitelog.screen` being enabled).

Passing any object instance to cherrypy.quickstart for the root parameter, rather than None, resolves the issue, resulting in both request logging and static file retrieval working as expected.

This has been observed with !CherryPy 3.1.1.

Reported by

Comments (6)

  1. visteya

    The observed problem is caused by this code in cherrypy.quickstart() :

        if root is not None:
            tree.mount(root, script_name, config)

    in Tree.mount() , we find this important bit of code:

            if config:

    So the net result of the example is that the config dict is ignored, resulting in the misbehavior observed by the reporter.

    Note that if you explicitly call tree.mount() , rather than expecting quickstart() to do it for you, everything works fine:

    cherrypy.tree.mount(root=None, config=conf)

    The following patch will fix this problem:

    --- cherrypy/	(revision 2149)
    +++ cherrypy/	(working copy)
    @@ -237,8 +237,7 @@
         if config:
    -    if root is not None:
    -        tree.mount(root, script_name, config)
    +    tree.mount(root, script_name, config)
         if hasattr(engine, "signal_handler"):
  2. visteya

    The patch is not really a good solution, and I'm not in favor of applying it. A better solution is to correct the design flaw that creates this problem, which is that two separate concepts, the object-tree dispatcher, and the config dict, were commingled, instead of having separate APIs.

    <lakin> I guess the weird part is that quickstart/mount both have a root parameter, when not all dispatchers require one.

    <visteya> RoutesDispatcher does actually look at Application.root, but just to see if app.root has a _cp_config attribute.

    <visteya> the entire tree.mount concept is specific to the object tree dispatcher

    <visteya> the only reason you need to call tree.mount() for the other dispatchers is because the config dict merging happens to be hidden inside tree.mount()

    <visteya> i'd favor giving independent concepts (dispatch tree, and config dict) independent APIs. i.e. take the config arg away from tree.mount(), and have a different API to give the config dict to the Application object.

  3. Log in to comment