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

Changeset 1145

Show
Ignore:
Timestamp:
06/13/06 01:04:32
Author:
fumanchu
Message:

Heavily cleaned the namespace for Tool objects:

  1. Privatized "name", "point", "merged_args" and "setup".
  2. Renamed Tool.enable to Tool.call.
  3. Set the docstring of each Tool instance to the docstring of the tool's callable. Combined with the above, this means calltips should pick up the calltip of the callable.
  4. Tools now copy the param names of self.callable to self.attributes. This allows users to "import tools" and then get config entry auto-completion in aware editors.
Files:

Legend:

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

    r1143 r1145  
    305305                bucket[".".join(atoms)] = v 
    306306         
    307         # Run tool.setup(conf) for each tool in the new toolmap. 
     307        # Run tool._setup(conf) for each tool in the new toolmap. 
    308308        for toolname, conf in self.toolmap.iteritems(): 
    309309            if conf.get("on", False): 
    310310                tool = getattr(cherrypy.tools, toolname) 
    311                 tool.setup() 
     311                tool._setup() 
    312312     
    313313    def _get_browser_url(self): 
  • trunk/cherrypy/_cptools.py

    r1143 r1145  
    99     
    1010    Function decorators: 
    11         If the tool exposes an "enable" callable, that is assumed to be a 
    12         compile-time decorator for use in configuring individual CherryPy 
    13         page handlers (methods on the CherryPy tree). It should "turn on" 
    14         the tool in the decorated function's _cp_config attribute. 
     11        All tools, when called, may be used as decorators which configure 
     12        individual CherryPy page handlers (methods on the CherryPy tree). 
     13        That is, "@tools.anytool()" should "turn on" the tool via the 
     14        decorated function's _cp_config attribute. 
    1515     
    1616    CherryPy hooks: "hooks" are points in the CherryPy request-handling 
    1717        process which may hand off control to registered callbacks. The 
    18         Request object possesses a "hooks" attribute (a HookMap) 
    19         for manipulating this. If a tool exposes a "setup" callable, 
    20         it will be called once per Request (if the feature is enabled 
     18        Request object possesses a "hooks" attribute (a HookMap) for 
     19        manipulating this. If a tool exposes a "_setup" callable, it 
     20        will be called once per Request (if the feature is "turned on" 
    2121        via config). 
    2222 
     
    2828 
    2929 
     30def setargs(obj, func): 
     31    """Copy func parameter names to obj attributes.""" 
     32    try: 
     33        import inspect 
     34        for arg in inspect.getargspec(func)[0]: 
     35            setattr(obj, arg, None) 
     36    except (ImportError, AttributeError): 
     37        pass 
     38 
     39 
    3040class Tool(object): 
    3141    """A registered function for use with CherryPy request-processing hooks. 
     
    3545     
    3646    def __init__(self, point, callable, name=None): 
    37         self.point = point 
     47        self._point = point 
    3848        self.callable = callable 
    39         self.name = name 
    40         # TODO: add an attribute to self for each arg 
    41         # in inspect.getargspec(callable) 
    42      
    43     def __call__(self, *args, **kwargs): 
    44         return self.callable(*args, **kwargs) 
    45      
    46     def merged_args(self, d=None): 
    47         conf = cherrypy.request.toolmap.get(self.name, {}).copy() 
     49        self._name = name 
     50        self.__doc__ = self.callable.__doc__ 
     51        setargs(self, callable) 
     52     
     53    def _merged_args(self, d=None): 
     54        conf = cherrypy.request.toolmap.get(self._name, {}).copy() 
    4855        conf.update(d or {}) 
    4956        if "on" in conf: 
     
    5158        return conf 
    5259     
    53     def enable(self, **kwargs): 
     60    def __call__(self, **kwargs): 
    5461        """Compile-time decorator (turn on the tool in config). 
    5562         
    5663        For example: 
    5764         
    58             @tools.base_url.enable() 
     65            @tools.base_url() 
    5966            def whats_my_base(self): 
    6067                return cherrypy.request.base 
     
    6471            if not hasattr(f, "_cp_config"): 
    6572                f._cp_config = {} 
    66             f._cp_config["tools." + self.name + ".on"] = True 
     73            f._cp_config["tools." + self._name + ".on"] = True 
    6774            for k, v in kwargs.iteritems(): 
    68                 f._cp_config["tools." + self.name + "." + k] = v 
     75                f._cp_config["tools." + self._name + "." + k] = v 
    6976            return f 
    7077        return wrapper 
    7178     
    72     def setup(self): 
     79    def _setup(self): 
    7380        """Hook this tool into cherrypy.request. 
    7481         
     
    7683        method when the tool is "turned on" in config. 
    7784        """ 
    78         conf = self.merged_args() 
    79         cherrypy.request.hooks.attach(self.point, self.callable, conf) 
     85        conf = self._merged_args() 
     86        cherrypy.request.hooks.attach(self._point, self.callable, conf) 
    8087 
    8188 
     
    99106        """ 
    100107        def wrapper(*a, **kw): 
    101             handled = self.callable(*args, **self.merged_args(kwargs)) 
     108            handled = self.callable(*args, **self._merged_args(kwargs)) 
    102109            if not handled: 
    103110                raise cherrypy.NotFound() 
     
    106113        return wrapper 
    107114     
    108     def setup(self): 
     115    def _setup(self): 
    109116        """Hook this tool into cherrypy.request. 
    110117         
     
    113120        """ 
    114121        def wrapper(): 
    115             if self.callable(**self.merged_args()): 
     122            if self.callable(**self._merged_args()): 
    116123                cherrypy.request.handler = None 
    117124        # Don't pass conf (or our wrapper will get wrapped!) 
    118         cherrypy.request.hooks.attach(self.point, wrapper) 
     125        cherrypy.request.hooks.attach(self._point, wrapper) 
    119126 
    120127 
     
    125132        Tool.__init__(self, None, callable, name) 
    126133     
    127     def setup(self): 
     134    def _setup(self): 
    128135        """Hook this tool into cherrypy.request. 
    129136         
     
    132139        """ 
    133140        def wrapper(): 
    134             self.callable(**self.merged_args()) 
     141            self.callable(**self._merged_args()) 
    135142        cherrypy.request.error_response = wrapper 
    136143 
     
    144151 
    145152class StaticDirTool(MainTool): 
    146     def setup(self): 
     153    def _setup(self): 
    147154        """Hook this tool into cherrypy.request using the given conf.""" 
    148         conf = self.merged_args() 
     155        conf = self._merged_args() 
    149156        def wrapper(): 
    150157            if self.callable(**conf): 
    151158                cherrypy.request.handler = None 
    152159        # Don't pass conf (or our wrapper will get wrapped!) 
    153         cherrypy.request.hooks.attach(self.point, wrapper) 
     160        cherrypy.request.hooks.attach(self._point, wrapper) 
    154161 
    155162 
    156163class SessionTool(Tool): 
     164    """Session Tool for CherryPy.""" 
     165     
    157166    def __init__(self): 
    158         self.point = "before_finalize" 
     167        self._point = "before_finalize" 
    159168        self.callable = _sessions.save 
    160         self.name = None 
    161      
    162     def setup(self): 
     169        self._name = None 
     170     
     171    def _setup(self): 
    163172        """Hook this tool into cherrypy.request using the given conf. 
    164173         
     
    167176        """ 
    168177        def init(): 
    169             conf = cherrypy.request.toolmap.get(self.name, {}) 
     178            conf = cherrypy.request.toolmap.get(self._name, {}) 
    170179             
    171180            s = cherrypy.request._session = _sessions.Session() 
     
    215224    """ 
    216225     
    217     def setup(self): 
     226    def _setup(self): 
    218227        """Hook this tool into cherrypy.request using the given conf.""" 
    219228        request = cherrypy.request 
     
    246255    """ 
    247256     
    248     def setup(self): 
     257    def _setup(self): 
    249258        # Keep request body intact so the wsgi app can have its way with it. 
    250259        cherrypy.request.process_request_body = False 
    251         MainTool.setup(self) 
     260        MainTool._setup(self) 
     261 
     262 
     263class CachingTool: 
     264    """Caching Tool for CherryPy.""" 
     265     
     266    def __init__(self): 
     267        self._setup = _caching._setup 
     268        self.__call__ = _caching.enable 
    252269 
    253270 
     
    256273     
    257274    def __setattr__(self, name, value): 
    258         # If the Tool.name is None, supply it from the attribute name. 
     275        # If the Tool._name is None, supply it from the attribute name. 
    259276        if isinstance(value, Tool): 
    260             if value.name is None: 
    261                 value.name = name 
     277            if value._name is None: 
     278                value._name = name 
    262279        object.__setattr__(self, name, value) 
    263280 
     
    282299default_toolbox.xmlrpc = XMLRPCTool() 
    283300default_toolbox.wsgiapp = WSGIAppTool(_wsgiapp.run) 
    284 default_toolbox.caching = _caching 
     301default_toolbox.caching = CachingTool() 
    285302 
    286303 
  • trunk/cherrypy/lib/caching.py

    r1144 r1145  
    160160    return wrapper 
    161161 
    162 def setup(): 
     162def _setup(): 
    163163    """Hook caching into cherrypy.request using the given conf.""" 
    164164    conf = cherrypy.request.toolmap.get("caching", {}) 
  • trunk/cherrypy/lib/static.py

    r1141 r1145  
    143143 
    144144def staticdir(section, dir, root="", match="", content_types=None, index=""): 
     145    """Serve a static resource from the given (root +) dir.""" 
    145146    if match and not re.search(match, cherrypy.request.path_info): 
    146147        return False 
     
    178179 
    179180def staticfile(filename, root=None, match="", content_types=None): 
     181    """Serve a static resource from the given (root +) filename.""" 
    180182    if match and not re.search(match, cherrypy.request.path_info): 
    181183        return False 
  • trunk/cherrypy/test/test_core.py

    r1143 r1145  
    162162         
    163163        # We support Python 2.3, but the @-deco syntax would look like this: 
    164         # @tools.login_redir.enable() 
     164        # @tools.login_redir() 
    165165        def secure(self): 
    166166            return "Welcome!" 
    167         secure = tools.login_redir.enable()(secure) 
    168         # Since enable returns the same function you pass in, 
     167        secure = tools.login_redir()(secure) 
     168        # Since calling the tool returns the same function you pass in, 
    169169        # you could skip binding the return value, and just write: 
    170         # tools.login_redir.enable()(secure) 
     170        # tools.login_redir()(secure) 
    171171         
    172172        def login(self): 
  • trunk/cherrypy/test/test_response_headers.py

    r1143 r1145  
    1212        index.exposed = True 
    1313        h = [("Content-Language", "en-GB"), ('Content-Type', 'text/plain')] 
    14         tools.response_headers.enable(headers=h)(index) 
     14        tools.response_headers(headers=h)(index) 
    1515         
    1616        def other(self): 
  • trunk/cherrypy/test/test_tools.py

    r1143 r1145  
    2828     
    2929    class NumTool(_cptools.Tool): 
    30         def setup(self): 
     30        def _setup(self): 
    3131            def makemap(): 
    32                 m = self.merged_args().get("map", {}) 
     32                m = self._merged_args().get("map", {}) 
    3333                cherrypy.request.numerify_map = m.items() 
    3434            cherrypy.request.hooks.attach('on_start_resource', makemap) 
    35             cherrypy.request.hooks.attach(self.point, self.callable) 
     35            cherrypy.request.hooks.attach(self._point, self.callable) 
    3636    tools.numerify = NumTool('before_finalize', numerify) 
    3737     
     
    4242            self.counter = 0 
    4343            self.ended = {} 
    44             self.name = "nadsat" 
     44            self._name = "nadsat" 
    4545         
    4646        def nadsat(self): 
     
    5757            self.ended[cherrypy.request.counter] = True 
    5858         
    59         def setup(self): 
     59        def _setup(self): 
    6060            cherrypy.request.counter = self.counter = self.counter + 1 
    6161            self.ended[cherrypy.request.counter] = False 
     
    111111            yield "confidential" 
    112112         
    113         # METHOD TWO: decorator using Tool.enable 
     113        # METHOD TWO: decorator using Tool() 
    114114        # We support Python 2.3, but the @-deco syntax would look like this: 
    115         # @tools.check_access.enable() 
     115        # @tools.check_access() 
    116116        def restricted(self): 
    117117            return "Welcome!" 
    118         restricted = tools.check_access.enable()(restricted) 
     118        restricted = tools.check_access()(restricted) 
    119119         
    120120        def err_in_onstart(self): 
     
    186186        self.assertBody("True") 
    187187         
    188         # Test the "enable" technique (compile-time decorator). 
     188        # Test the "__call__" technique (compile-time decorator). 
    189189        self.getPage("/demo/restricted") 
    190190        self.assertErrorPage(401) 

Hosted by WebFaction

Log in as guest/cpguest to create tickets