Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

Changeset 1336

Show
Ignore:
Timestamp:
09/05/06 17:54:42
Author:
fumanchu
Message:

Moved request.namespaces back to the class level (each instance gets a copy). Renamed "tool_up" to "configure". Also, request.handler should not set response.body anymore: it should return it to the caller instead (this allows custom namespaces to wrap the handler and munge output). Full demo in test_config.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/cherrypy/_cpconfig.py

    r1311 r1336  
    6565    log:        Configures the logging for each application. 
    6666                These can only be declared in the global or / config. 
    67     request:    Adds attributes to each Request during the tool_up phase
    68     response:   Adds attributes to each Response during the tool_up phase
     67    request:    Adds attributes to each Request
     68    response:   Adds attributes to each Response
    6969    server:     Controls the default HTTP server via cherrypy.server. 
    7070                These can only be declared in the global config. 
  • trunk/cherrypy/_cprequest.py

    r1329 r1336  
    9999     
    100100    def __call__(self): 
    101         cherrypy.response.body = self.callable(*self.args, **self.kwargs) 
     101        return self.callable(*self.args, **self.kwargs) 
    102102 
    103103 
     
    228228        pi = request.path_info 
    229229         
    230         # Must use config here because tool_up probably hasn't run yet. 
     230        # Must use config here because configure probably hasn't run yet. 
    231231        if request.config.get("request.redirect_on_missing_slash", 
    232232                              request.redirect_on_missing_slash): 
     
    243243        pi = request.path_info 
    244244         
    245         # Must use config here because tool_up hasn't run yet. 
     245        # Must use config here because configure hasn't run yet. 
    246246        if request.config.get("request.redirect_on_extra_slash", 
    247247                              request.redirect_on_extra_slash): 
     
    294294 
    295295 
     296# Config namespace handlers 
     297def tools_namespace(k, v): 
     298    """Attach tools specified in config.""" 
     299    toolname, arg = k.split(".", 1) 
     300    bucket = cherrypy.request.toolmap.setdefault(toolname, {}) 
     301    bucket[arg] = v 
     302 
     303def hooks_namespace(k, v): 
     304    """Attach bare hooks declared in config.""" 
     305    # Use split again to allow multiple hooks for a single 
     306    # hookpoint per path (e.g. "hooks.before_handler.1"). 
     307    # Little-known fact you only get from reading source ;) 
     308    hookpoint = k.split(".", 1)[0] 
     309    if isinstance(v, basestring): 
     310        v = cherrypy.lib.attributes(v) 
     311    if not isinstance(v, Hook): 
     312        v = Hook(v) 
     313    cherrypy.request.hooks[hookpoint].append(v) 
     314 
     315def request_namespace(k, v): 
     316    """Attach request attributes declared in config.""" 
     317    setattr(cherrypy.request, k, v) 
     318 
     319def response_namespace(k, v): 
     320    """Attach response attributes declared in config.""" 
     321    setattr(cherrypy.response, k, v) 
     322 
     323def error_page_namespace(k, v): 
     324    """Attach error pages declared in config.""" 
     325    cherrypy.request.error_page[int(k)] = v 
     326 
     327 
    296328class Request(object): 
    297329    """An HTTP request.""" 
     
    346378    throw_errors = False 
    347379     
     380    namespaces = {"tools": tools_namespace, 
     381                  "hooks": hooks_namespace, 
     382                  "request": request_namespace, 
     383                  "response": response_namespace, 
     384                  "error_page": error_page_namespace, 
     385                  } 
    348386     
    349387    def __init__(self, local_host, remote_host, scheme="http", 
     
    366404        self.error_page = self.error_page.copy() 
    367405         
    368         self.namespaces = {"tools": self._set_tool, 
    369                            "hooks": self._set_hook, 
    370                            "request": self.__setattr__, 
    371                            "response": lambda k, v: setattr(cherrypy.response, k, v), 
    372                            "error_page": lambda k, v: self.error_page.__setitem__(int(k), v), 
    373                            } 
     406        # Put a *copy* of the class namespaces into self. 
     407        self.namespaces = self.namespaces.copy() 
    374408     
    375409    def close(self): 
     
    500534                    self.hooks = HookMap(self.hookpoints) 
    501535                    self.get_resource(path_info) 
    502                     self.tool_up() 
     536                    self.configure() 
    503537                     
    504538                    self.hooks.run('on_start_resource') 
     
    521555                    self.hooks.run('before_handler') 
    522556                    if self.handler: 
    523                         self.handler() 
     557                        cherrypy.response.body = self.handler() 
    524558                    self.hooks.run('before_finalize') 
    525559                    cherrypy.response.finalize() 
     
    587621        while trail: 
    588622            nodeconf = self.app.config.get(trail, {}) 
     623             
    589624            d = nodeconf.get("request.dispatch") 
    590625            if d: 
     
    603638        dispatch(path) 
    604639     
    605     def _set_tool(self, k, v): 
    606         """Attach tools specified in config.""" 
    607         toolname, arg = k.split(".", 1) 
    608         bucket = self.toolmap.setdefault(toolname, {}) 
    609         bucket[arg] = v 
    610      
    611     def _set_hook(self, k, v): 
    612         """Attach bare hooks declared in config.""" 
    613         # Use split again to allow multiple hooks for a single 
    614         # hookpoint per path (e.g. "hooks.before_handler.1"). 
    615         # Little-known fact you only get from reading source ;) 
    616         hookpoint = k.split(".", 1)[0] 
    617         if isinstance(v, basestring): 
    618             v = cherrypy.lib.attributes(v) 
    619         if not isinstance(v, Hook): 
    620             v = Hook(v) 
    621         self.hooks[hookpoint].append(v) 
    622      
    623     def tool_up(self): 
     640    def configure(self): 
    624641        """Process self.config, populate self.toolmap and set up each tool.""" 
    625         # Get all 'tools.*' config entries as a {toolname: {k: v}} dict. 
    626642        self.toolmap = tm = {} 
     643         
     644        # Process config namespaces (including tools.*) 
    627645        reqconf = self.config 
    628646        for k in reqconf: 
  • trunk/cherrypy/test/test_config.py

    r1326 r1336  
    4545        index.exposed = True 
    4646     
     47     
     48    def raw_namespace(key, value): 
     49        if key == 'input.map': 
     50            params = cherrypy.request.params 
     51            for name, coercer in value.iteritems(): 
     52                try: 
     53                    params[name] = coercer(params[name]) 
     54                except KeyError: 
     55                    pass 
     56        elif key == 'output': 
     57            handler = cherrypy.request.handler 
     58            def wrapper(): 
     59                return value(handler()) 
     60            cherrypy.request.handler = wrapper 
     61    cherrypy.engine.request_class.namespaces['raw'] = raw_namespace 
     62     
     63    class Raw: 
     64         
     65        _cp_config = {'raw.output': repr} 
     66         
     67        def incr(self, num): 
     68            return num + 1 
     69        incr.exposed = True 
     70        incr._cp_config = {'raw.input.map': {'num': int}} 
     71     
    4772    ioconf = StringIO.StringIO(""" 
    4873[/] 
     
    5277    root = Root() 
    5378    root.foo = Foo() 
     79    root.raw = Raw() 
    5480    cherrypy.tree.mount(root, config=ioconf) 
    5581    cherrypy.tree.mount(Another(), "/another") 
     
    106132            self.getPage("/foo/bar?key=" + key) 
    107133            self.assertBody(`expected`) 
     134     
     135    def testCustomNamespaces(self): 
     136        self.getPage("/raw/incr?num=12") 
     137        self.assertBody("13") 
    108138 
    109139 

Hosted by WebFaction

Log in as guest/cpguest to create tickets