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

Changeset 1281

Show
Ignore:
Timestamp:
08/26/06 03:26:19
Author:
fumanchu
Message:

API and docstring cleanups:

  1. Removed WrongConfigValue?, decorate, decorate_all, and ExposeItems.
  2. Moved cherrypy.logtime to cherrypy.log.time.
  3. Reduced cherrypy.config.globalconf back to just cherrypy.config.
  4. Moved _cpconfig.default_conf to config.defaults.

.

Files:

Legend:

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

    r1280 r1281  
    88 
    99from cherrypy._cperror import HTTPError, HTTPRedirect, InternalRedirect, NotFound 
    10 from cherrypy._cperror import WrongConfigValue, TimeoutError 
     10from cherrypy._cperror import TimeoutError 
    1111 
    1212from cherrypy import _cptools 
     
    9898 
    9999 
    100 def logtime(): 
    101     import datetime 
    102     now = datetime.datetime.now() 
    103     import rfc822 
    104     month = rfc822._monthnames[now.month - 1].capitalize() 
    105     return '%02d/%s/%04d:%02d:%02d:%02d' % ( 
    106         now.day, month, now.year, now.hour, now.minute, now.second) 
    107  
    108  
    109100_error_log = _logging.getLogger("cherrypy.error") 
    110101_error_log.setLevel(_logging.DEBUG) 
     
    134125        except AttributeError: 
    135126            elog = _error_log 
    136         elog.log(severity, ' '.join((logtime(), context, msg))) 
     127        elog.log(severity, ' '.join((self.time(), context, msg))) 
    137128     
    138129    def __call__(self, *args, **kwargs): 
     
    140131     
    141132    def access(self): 
    142         """Default method for logging access""" 
    143         tmpl = '%(h)s %(l)s %(u)s [%(t)s] "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"' 
     133        """Write to the access log.""" 
     134        tmpl = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"' 
    144135        s = tmpl % {'h': request.remote.name or request.remote.ip, 
    145136                    'l': '-', 
    146137                    'u': getattr(request, "login", None) or "-", 
    147                     't': logtime(), 
     138                    't': self.time(), 
    148139                    'r': request.request_line, 
    149140                    's': response.status.split(" ", 1)[0], 
     
    156147        except: 
    157148            self.error(traceback=True) 
     149     
     150    def time(self): 
     151        """Return now() in Apache Common Log Format (no timezone).""" 
     152        import datetime, rfc822 
     153        now = datetime.datetime.now() 
     154        month = rfc822._monthnames[now.month - 1].capitalize() 
     155        return ('[%02d/%s/%04d:%02d:%02d:%02d]' % 
     156                (now.day, month, now.year, now.hour, now.minute, now.second)) 
    158157 
    159158 
     
    162161 
    163162#                       Helper functions for CP apps                       # 
    164  
    165  
    166 def decorate(func, decorator): 
    167     """ 
    168     Return the decorated func. This will automatically copy all 
    169     non-standard attributes (like exposed) to the newly decorated function. 
    170     """ 
    171     newfunc = decorator(func) 
    172     for key in dir(func): 
    173         if not hasattr(newfunc, key): 
    174             setattr(newfunc, key, getattr(func, key)) 
    175     return newfunc 
    176  
    177 def decorate_all(obj, decorator): 
    178     """ 
    179     Recursively decorate all exposed functions of obj and all of its children, 
    180     grandchildren, etc. If you used to use aspects, you might want to look 
    181     into these. This function modifies obj; there is no return value. 
    182     """ 
    183     obj_type = type(obj) 
    184     for key in dir(obj): 
    185         if hasattr(obj_type, key): # only deal with user-defined attributes 
    186             continue 
    187         value = getattr(obj, key) 
    188         if callable(value) and getattr(value, "exposed", False): 
    189             setattr(obj, key, decorate(value, decorator)) 
    190         decorate_all(value, decorator) 
    191  
    192  
    193 class ExposeItems: 
    194     """ 
    195     Utility class that exposes a getitem-aware object. It does not provide 
    196     index() or default() methods, and it does not expose the individual item 
    197     objects - just the list or dict that contains them. User-specific index() 
    198     and default() methods can be implemented by inheriting from this class. 
    199      
    200     Use case: 
    201      
    202     from cherrypy import ExposeItems 
    203     ... 
    204     root.foo = ExposeItems(mylist) 
    205     root.bar = ExposeItems(mydict) 
    206     """ 
    207     exposed = True 
    208     def __init__(self, items): 
    209         self.items = items 
    210     def __getattr__(self, key): 
    211         return self.items[key] 
    212163 
    213164 
  • trunk/cherrypy/_cpconfig.py

    r1278 r1281  
    1212 
    1313    Global: configuration entries which apply everywhere are stored in 
    14     cherrypy.config.globalconf. Use the top-level function 'config.update' 
    15     to modify it. 
     14    cherrypy.config. 
    1615     
    1716    Application: entries which apply to each mounted application are stored 
     
    7473The only key that does not exist in a namespace is the "environment" entry. 
    7574This special entry 'imports' other config entries from a template stored in 
    76 cherrypy.config.environments[environment]. It only applies to globalconf, 
    77 and only when you use "update" to modify globalconf
     75cherrypy._cpconfig.environments[environment]. It only applies to the global 
     76config, and only when you use cherrypy.config.update
    7877""" 
    7978 
     
    121120 
    122121 
    123 default_conf = { 
    124     'tools.log_tracebacks.on': True, 
    125     'tools.log_headers.on': True, 
    126     } 
    127  
    128  
    129 class Config(object): 
    130      
    131     globalconf = default_conf.copy() 
     122class Config(dict): 
     123    """The 'global' configuration data for the entire CherryPy process.""" 
     124     
     125    defaults = { 
     126        'tools.log_tracebacks.on': True, 
     127        'tools.log_headers.on': True, 
     128        } 
     129     
     130    def __init__(self): 
     131        self.reset() 
    132132     
    133133    def reset(self): 
    134         """Reset self.globalconf to default values.""" 
    135         self.globalconf.clear() 
    136         self.update(default_conf
     134        """Reset self to default values.""" 
     135        self.clear() 
     136        dict.update(self, self.defaults
    137137     
    138138    def update(self, conf): 
    139         """Update self.globalconf from a dict, file or filename.""" 
     139        """Update self from a dict, file or filename.""" 
    140140        if isinstance(conf, basestring): 
     141            # Filename 
    141142            if conf not in cherrypy.engine.reload_files: 
    142143                cherrypy.engine.reload_files.append(conf) 
    143144            conf = _Parser().dict_from_file(conf) 
    144145        elif hasattr(conf, 'read'): 
     146            # Open file object 
    145147            conf = _Parser().dict_from_file(conf) 
    146148         
     
    157159            conf['tools.staticdir.section'] = "global" 
    158160         
    159         self.globalconf.update(conf) 
    160          
    161         _configure_builtin_logging(self.globalconf, cherrypy._error_log) 
    162         _configure_builtin_logging(self.globalconf, cherrypy._access_log, "log.access_file") 
    163          
    164         # Override properties specified in config. 
    165         gconf = self.globalconf 
    166         for k in gconf: 
    167             atoms = k.split(".", 1) 
    168             namespace = atoms[0] 
    169             if namespace == "server": 
    170                 setattr(cherrypy.server, atoms[1], gconf[k]) 
    171             elif namespace == "engine": 
    172                 setattr(cherrypy.engine, atoms[1], gconf[k]) 
    173             elif namespace == "log": 
    174                 setattr(cherrypy.log, atoms[1], gconf[k]) 
    175             elif namespace == "error_page": 
    176                 cherrypy.error_page[int(atoms[1])] = gconf[k] 
     161        # Must use this idiom in order to hit our custom __setitem__. 
     162        for k, v in conf.iteritems(): 
     163            self[k] = v 
     164         
     165        _configure_builtin_logging(self, cherrypy._error_log) 
     166        _configure_builtin_logging(self, cherrypy._access_log, "log.access_file") 
     167     
     168    def __setitem__(self, k, v): 
     169        dict.__setitem__(self, k, v) 
     170         
     171        # Override object properties if specified in config. 
     172        atoms = k.split(".", 1) 
     173        namespace = atoms[0] 
     174        if namespace == "server": 
     175            setattr(cherrypy.server, atoms[1], v) 
     176        elif namespace == "engine": 
     177            setattr(cherrypy.engine, atoms[1], v) 
     178        elif namespace == "log": 
     179            setattr(cherrypy.log, atoms[1], v) 
    177180     
    178181    def wrap(**kwargs): 
     
    266269                    value = unrepr(value) 
    267270                except Exception, x: 
    268                     msg = ("section: %s, option: %s, value: %s" % 
     271                    msg = ("Config error in section: %s, option: %s, value: %s" % 
    269272                           (repr(section), repr(option), repr(value))) 
    270                     e = cherrypy.WrongConfigValue(msg) 
    271                     e.args += (x.__class__.__name__, x.args) 
    272                     raise e 
     273                    raise ValueError(msg, x.__class__.__name__, x.args) 
    273274                result[section][option] = value 
    274275        return result 
  • trunk/cherrypy/_cpengine.py

    r1280 r1281  
    4747    response_class = _cprequest.Response 
    4848    deadlock_poll_freq = 60 
    49     autoreload_on = Fals
     49    autoreload_on = Tru
    5050    autoreload_frequency = 1 
    5151     
     
    173173     
    174174    def restart(self): 
    175         """Restart the application engine (doesn't block).""" 
     175        """Restart the application engine (does not block).""" 
    176176        self.stop() 
    177177        self.start(blocking=False) 
     
    216216     
    217217    def monitor(self): 
    218         """Check timeout on all responses.""" 
     218        """Check timeout on all responses (starts a recurring Timer).""" 
    219219        if self.state == STARTED: 
    220220            for req, resp in self.servings: 
  • trunk/cherrypy/_cperror.py

    r1278 r1281  
    77 
    88 
    9 class WrongConfigValue(Exception): 
    10     """ Happens when a config value can't be parsed, or is otherwise illegal. """ 
    11     pass 
    12  
    139class InternalRedirect(Exception): 
    1410    """Exception raised when processing should be handled by a different path. 
    1511     
    16     If you supply a query string, it will be replace request.params. 
     12    If you supply a query string, it will replace request.params. 
    1713    If you omit the query string, the params from the original request will 
    1814    remain in effect. 
     
    4642    """Exception raised when the request should be redirected. 
    4743     
    48     The new URL must be passed as the first argument to the Exception, e.g., 
    49         cperror.HTTPRedirect(newUrl). Multiple URLs are allowed. If a URL 
    50         is absolute, it will be used as-is. If it is relative, it is assumed 
    51         to be relative to the current cherrypy.request.path. 
     44    The new URL must be passed as the first argument to the Exception, 
     45    e.g., HTTPRedirect(newUrl). Multiple URLs are allowed. If a URL is 
     46    absolute, it will be used as-is. If it is relative, it is assumed 
     47    to be relative to the current cherrypy.request.path. 
    5248    """ 
    5349     
     
    8682     
    8783    def set_response(self): 
     84        """Modify cherrypy.response status, headers, and body to represent self. 
     85         
     86        CherryPy uses this internally, but you can also use it to create an 
     87        HTTPRedirect object and set its output without *raising* the exception. 
     88        """ 
    8889        import cherrypy 
    8990        response = cherrypy.response 
     
    131132     
    132133    def __call__(self): 
    133         # Allow the exception to be used as a request.handler. 
     134        """Use this exception as a request.handler (raise self).""" 
    134135        raise self 
    135136 
    136137 
    137138class HTTPError(Exception): 
    138     """ Exception used to return an HTTP error code to the client. 
     139    """ Exception used to return an HTTP error code (4xx-5xx) to the client. 
    139140        This exception will automatically set the response status and body. 
    140141         
     
    151152     
    152153    def set_response(self): 
    153         """Set cherrypy.response status, headers, and body.""" 
     154        """Modify cherrypy.response status, headers, and body to represent self. 
     155         
     156        CherryPy uses this internally, but you can also use it to create an 
     157        HTTPError object and set its output without *raising* the exception. 
     158        """ 
    154159        import cherrypy 
    155160         
     
    189194     
    190195    def __call__(self): 
    191         # Allow the exception to be used as a request.handler. 
     196        """Use this exception as a request.handler (raise self).""" 
    192197        raise self 
    193198 
    194199 
    195200class NotFound(HTTPError): 
    196     """ Happens when a URL couldn't be mapped to any class.method """ 
     201    """Exception raised when a URL could not be mapped to any handler (404).""" 
    197202     
    198203    def __init__(self, path=None): 
     
    314319 
    315320def format_exc(exc=None): 
    316     """format_exc(exc=None) -> exc (or sys.exc_info if None), formatted.""" 
     321    """Return exc (or sys.exc_info if None), formatted.""" 
    317322    if exc is None: 
    318323        exc = _exc_info() 
  • trunk/cherrypy/_cprequest.py

    r1280 r1281  
    4141     
    4242    def __call__(self): 
     43        """Run self.callback(**self.kwargs).""" 
    4344        return self.callback(**self.kwargs) 
    4445 
     
    102103 
    103104class LateParamPageHandler(PageHandler): 
    104     """When passing cherrypy.request.params to the page handler, we don'
     105    """When passing cherrypy.request.params to the page handler, we do no
    105106    want to capture that dict too early; we want to give tools like the 
    106107    decoding tool a chance to modify the params dict in-between the lookup 
     
    175176        def set_conf(): 
    176177            """Set cherrypy.request.config.""" 
    177             base = cherrypy.config.globalconf.copy() 
     178            base = cherrypy.config.copy() 
    178179            # Note that we merge the config from each node 
    179180            # even if that node was None. 
  • trunk/cherrypy/_cpserver.py

    r1278 r1281  
    1010 
    1111class Server(object): 
    12     """Manager for a set of HTTP servers.""" 
     12    """Manager for a set of HTTP servers. 
     13     
     14    This is both a container and controller for "HTTP server" objects, 
     15    which are kept in Server.httpservers, a dictionary of the form: 
     16    {httpserver: bind_addr} where 'bind_addr' is usually a (host, port) 
     17    tuple. 
     18     
     19    Most often, you will only be starting a single HTTP server. In this 
     20    common case, you can set attributes (like socket_host and socket_port) 
     21    on *this* object (which is probably cherrypy.server), and call 
     22    quickstart. For example: 
     23     
     24        cherrypy.server.socket_port = 80 
     25        cherrypy.server.quickstart() 
     26     
     27    But if you need to start more than one HTTP server (to serve on multiple 
     28    ports, or protocols, etc.), you can manually register each one and then 
     29    control them all through this object: 
     30     
     31        s1 = MyWSGIServer(host='', port=80) 
     32        s2 = another.HTTPServer(host='localhost', SSL=True) 
     33        cherrypy.server.httpservers = {s1: ('', 80), s2: ('localhost', 443)} 
     34        # Note we do not use quickstart when we define our own httpservers 
     35        cherrypy.server.start() 
     36     
     37    Whether you use quickstart(), or define your own httpserver entries and 
     38    use start(), you'll find that the start, wait, restart, and stop methods 
     39    work the same way, controlling all registered httpserver objects at once. 
     40    """ 
    1341     
    1442    socket_port = 8080 
     
    121149     
    122150    def stop(self): 
    123         """Stop all HTTP server(s).""" 
     151        """Stop all HTTP servers.""" 
    124152        for httpserver, bind_addr in self.httpservers.items(): 
    125153            try: 
     
    135163     
    136164    def restart(self): 
    137         """Restart the HTTP server.""" 
     165        """Restart all HTTP servers.""" 
    138166        self.stop() 
    139167        self.start() 
  • trunk/cherrypy/_cptree.py

    r1278 r1281  
    7676 
    7777 
    78 class Tree
     78class Tree(object)
    7979    """A registry of CherryPy applications, mounted at diverse points. 
    8080     
  • trunk/cherrypy/lib/profiler.py

    r1274 r1281  
    5252    pstats = None 
    5353    import warnings 
    54     msg = ("Your installation of Python doesn't have a profile module. " 
     54    msg = ("Your installation of Python does not have a profile module. " 
    5555           "If you're on Debian, you can apt-get python2.4-profiler from " 
    5656           "non-free in a separate step. See http://www.cherrypy.org/wiki/" 
  • trunk/cherrypy/lib/static.py

    r1275 r1281  
    147147        if not root: 
    148148            msg = "Static dir requires an absolute dir (or root)." 
    149             raise cherrypy.WrongConfigValue(msg) 
     149            raise ValueError(msg) 
    150150        dir = os.path.join(root, dir) 
    151151     
     
    183183        if not root: 
    184184            msg = "Static tool requires an absolute filename (got '%s')." % filename 
    185             raise cherrypy.WrongConfigValue(msg) 
     185            raise ValueError(msg) 
    186186        filename = os.path.join(root, filename) 
    187187     
  • trunk/cherrypy/lib/tidy.py

    r1243 r1281  
    1111     
    1212    Note that we use the standalone Tidy tool rather than the python 
    13     mxTidy module. This is because this module doesn't seem to be 
     13    mxTidy module. This is because this module does not seem to be 
    1414    stable and it crashes on some HTML pages (which means that the 
    1515    server would also crash) 
  • trunk/cherrypy/test/benchmark.py

    r1278 r1281  
    55     
    66    --null:        use a null Request object (to bench the HTTP server only) 
    7     --notests:     start the server but don't run the tests; this allows 
     7    --notests:     start the server but do not run the tests; this allows 
    88                   you to check the tested pages with a browser 
    99    --help:        show this help message 
  • trunk/cherrypy/test/test_config.py

    r1278 r1281  
    8888            'environment': 'test_suite', 
    8989            'autoreload.on': False, 
    90             # From globalconf 
     90            # From global config 
    9191            'luxuryyacht': 'throatwobblermangrove', 
    9292            # From Root._cp_config 
  • trunk/cherrypy/test/test_tutorials.py

    r1278 r1281  
    1010def setup_server(): 
    1111     
    12     conf = cherrypy.config.globalconf.copy() 
     12    conf = cherrypy.config.copy() 
    1313     
    1414    def load_tut_module(name): 
  • trunk/cherrypy/test/webtest.py

    r1272 r1281  
    1313When an error occurs in the framework, call server_error. It will print 
    1414the traceback to stdout, and keep any assertions you have from running 
    15 (the assumption is that, if the server errors, the page output won't be 
    16 of further significance to your tests). 
     15(the assumption is that, if the server errors, the page output will not 
     16be of further significance to your tests). 
    1717""" 
    1818 
     
    115115            return test 
    116116        else: 
    117             raise ValueError("don't know how to make test from: %s" % obj) 
     117            raise ValueError("do not know how to make test from: %s" % obj) 
    118118 
    119119 

Hosted by WebFaction

Log in as guest/cpguest to create tickets