diff options
-rw-r--r-- | cherrypy/__init__.py | 15 | ||||
-rw-r--r-- | cherrypy/_cpchecker.py | 18 | ||||
-rw-r--r-- | cherrypy/_cpconfig.py | 83 | ||||
-rw-r--r-- | cherrypy/_cpdispatch.py | 9 | ||||
-rw-r--r-- | cherrypy/_cperror.py | 1 | ||||
-rw-r--r-- | cherrypy/_cprequest.py | 40 | ||||
-rw-r--r-- | cherrypy/_cptree.py | 26 | ||||
-rw-r--r-- | sphinx/source/refman/_cperror.rst | 32 | ||||
-rw-r--r-- | sphinx/source/refman/_cprequest.rst | 22 |
9 files changed, 169 insertions, 77 deletions
diff --git a/cherrypy/__init__.py b/cherrypy/__init__.py index d10b86a9..817826ca 100644 --- a/cherrypy/__init__.py +++ b/cherrypy/__init__.py @@ -97,7 +97,7 @@ class _AttributeDocstrings(type): class Thing(__builtin__.object) | A thing and its properties. | - | height [= 50]: + | height [= 50] | The height of the Thing in inches. | @@ -136,18 +136,23 @@ class _AttributeDocstrings(type): delattr(cls, name) # Make a uniformly-indented docstring from it. + val = dct[name] + # Allow docstrings to start right after the initial + # triple-quote, or on the next line + val = val.lstrip('\r\n') val = '\n'.join([' ' + line.strip() - for line in dct[name].split('\n')]) + for line in val.split('\n')]) # Get the default value. attrname = name[:-5] + attrval = "" try: - attrval = getattr(cls, attrname) + attrval = " [= %s]" % repr(getattr(cls, attrname)) except AttributeError: - attrval = "missing" + attrval = " [missing]" # Add the complete attribute docstring to our list. - newdoc.append("%s [= %r]:\n%s" % (attrname, attrval, val)) + newdoc.append("%s%s\n%s" % (attrname, attrval, val)) # Add our list of new docstrings to the class docstring. cls.__doc__ = "\n\n".join(newdoc) diff --git a/cherrypy/_cpchecker.py b/cherrypy/_cpchecker.py index 5c2c77e8..3aafecc8 100644 --- a/cherrypy/_cpchecker.py +++ b/cherrypy/_cpchecker.py @@ -7,17 +7,18 @@ import cherrypy class Checker(object): """A checker for CherryPy sites and their mounted applications. - on: set this to False to turn off the checker completely. + on + set this to False to turn off the checker completely. When this object is called at engine startup, it executes each - of its own methods whose names start with "check_". If you wish + of its own methods whose names start with ``check_``. If you wish to disable selected checks, simply add a line in your global - config which sets the appropriate method to False: + config which sets the appropriate method to False:: - [global] - checker.check_skipped_app_config = False + [global] + checker.check_skipped_app_config = False - You may also dynamically add or replace check_* methods in this way. + You may also dynamically add or replace ``check_*`` methods in this way. """ on = True @@ -47,6 +48,7 @@ class Checker(object): global_config_contained_paths = False def check_app_config_entries_dont_start_with_script_name(self): + """Check for Application config with sections that repeat script_name.""" for sn, app in cherrypy.tree.apps.items(): if not isinstance(app, cherrypy.Application): continue @@ -63,6 +65,7 @@ class Checker(object): "entries that start with its script name: %r" % (sn, key)) def check_site_config_entries_in_app_config(self): + """Check for mounted Applications that have site-scoped config.""" for sn, app in cherrypy.tree.apps.iteritems(): if not isinstance(app, cherrypy.Application): continue @@ -83,6 +86,7 @@ class Checker(object): warnings.warn(os.linesep.join(msg)) def check_skipped_app_config(self): + """Check for mounted Applications that have no config.""" for sn, app in cherrypy.tree.apps.items(): if not isinstance(app, cherrypy.Application): continue @@ -98,6 +102,7 @@ class Checker(object): return def check_app_config_brackets(self): + """Check for Application config with extraneous brackets in section names.""" for sn, app in cherrypy.tree.apps.items(): if not isinstance(app, cherrypy.Application): continue @@ -112,6 +117,7 @@ class Checker(object): "(e.g. passed to tree.mount) do not." % (sn, key)) def check_static_paths(self): + """Check Application config for incorrect static paths.""" # Use the dummy Request object in the main thread. request = cherrypy.request for sn, app in cherrypy.tree.apps.items(): diff --git a/cherrypy/_cpconfig.py b/cherrypy/_cpconfig.py index 93d6fcb6..bc5b5332 100644 --- a/cherrypy/_cpconfig.py +++ b/cherrypy/_cpconfig.py @@ -1,4 +1,5 @@ -"""Configuration system for CherryPy. +""" +Configuration system for CherryPy. Configuration in CherryPy is implemented via dictionaries. Keys are strings which name the mapped value, which may be of any type. @@ -10,17 +11,20 @@ Architecture CherryPy Requests are part of an Application, which runs in a global context, and configuration data may apply to any of those three scopes: - Global: configuration entries which apply everywhere are stored in +Global + Configuration entries which apply everywhere are stored in cherrypy.config. - - Application: entries which apply to each mounted application are stored + +Application + Entries which apply to each mounted application are stored on the Application object itself, as 'app.config'. This is a two-level dict where each key is a path, or "relative URL" (for example, "/" or "/path/to/my/page"), and each value is a config dict. Usually, this data is provided in the call to tree.mount(root(), config=conf), although you may also use app.merge(conf). - - Request: each Request object possesses a single 'Request.config' dict. + +Request + Each Request object possesses a single 'Request.config' dict. Early in the request process, this dict is populated by merging global config entries, Application entries (whose path equals or is a parent of Request.path_info), and any config acquired while looking up the @@ -33,7 +37,7 @@ Declaration Configuration data may be supplied as a Python dictionary, as a filename, or as an open file object. When you supply a filename or file, CherryPy uses Python's builtin ConfigParser; you declare Application config by -writing each path as a section header: +writing each path as a section header:: [/path/to/my/page] request.stream = True @@ -41,8 +45,8 @@ writing each path as a section header: To declare global configuration entries, place them in a [global] section. You may also declare config entries directly on the classes and methods -(page handlers) that make up your CherryPy application via the '_cp_config' -attribute. For example: +(page handlers) that make up your CherryPy application via the ``_cp_config`` +attribute. For example:: class Demo: _cp_config = {'tools.gzip.on': True} @@ -52,9 +56,11 @@ attribute. For example: index.exposed = True index._cp_config = {'request.show_tracebacks': False} -Note, however, that this behavior is only guaranteed for the default -dispatcher. Other dispatchers may have different restrictions on where -you can attach _cp_config attributes. +.. note:: + + This behavior is only guaranteed for the default dispatcher. + Other dispatchers may have different restrictions on where + you can attach _cp_config attributes. Namespaces @@ -63,23 +69,42 @@ Namespaces Configuration keys are separated into namespaces by the first "." in the key. Current namespaces: - engine: Controls the 'application engine', including autoreload. - These can only be declared in the global config. - tree: Grafts cherrypy.Application objects onto cherrypy.tree. - These can only be declared in the global config. - hooks: Declares additional request-processing functions. - log: Configures the logging for each application. - These can only be declared in the global or / config. - request: Adds attributes to each Request. - response: Adds attributes to each Response. - server: Controls the default HTTP server via cherrypy.server. - These can only be declared in the global config. - tools: Runs and configures additional request-processing packages. - wsgi: Adds WSGI middleware to an Application's "pipeline". - These can only be declared in the app's root config ("/"). - checker: Controls the 'checker', which looks for common errors in - app state (including config) when the engine starts. - Global config only. +engine + Controls the 'application engine', including autoreload. + These can only be declared in the global config. + +tree + Grafts cherrypy.Application objects onto cherrypy.tree. + These can only be declared in the global config. + +hooks + Declares additional request-processing functions. + +log + Configures the logging for each application. + These can only be declared in the global or / config. + +request + Adds attributes to each Request. + +response + Adds attributes to each Response. + +server + Controls the default HTTP server via cherrypy.server. + These can only be declared in the global config. + +tools + Runs and configures additional request-processing packages. + +wsgi + Adds WSGI middleware to an Application's "pipeline". + These can only be declared in the app's root config ("/"). + +checker + Controls the 'checker', which looks for common errors in + app state (including config) when the engine starts. + Global config only. The only key that does not exist in a namespace is the "environment" entry. This special entry 'imports' other config entries from a template stored in diff --git a/cherrypy/_cpdispatch.py b/cherrypy/_cpdispatch.py index ac291e75..26754adb 100644 --- a/cherrypy/_cpdispatch.py +++ b/cherrypy/_cpdispatch.py @@ -527,15 +527,18 @@ def VirtualHost(next_dispatcher=Dispatcher(), use_x_forwarded_host=True, **domai 'www.domain2.example:443': '/secure', }) - ``next_dispatcher``: the next dispatcher object in the dispatch chain. + next_dispatcher + The next dispatcher object in the dispatch chain. The VirtualHost dispatcher adds a prefix to the URL and calls another dispatcher. Defaults to cherrypy.dispatch.Dispatcher(). - ``use_x_forwarded_host``: if True (the default), any "X-Forwarded-Host" + use_x_forwarded_host + If True (the default), any "X-Forwarded-Host" request header will be used instead of the "Host" header. This is commonly added by HTTP servers (such as Apache) when proxying. - ``**domains``: a dict mapping host header values to virtual prefixes. + ``**domains`` + A dict of {host header value: virtual prefix} pairs. The incoming "Host" request header is looked up in this dict, and, if a match is found, the corresponding "virtual prefix" value will be prepended to the URL path before calling the diff --git a/cherrypy/_cperror.py b/cherrypy/_cperror.py index 308086e5..4438be6d 100644 --- a/cherrypy/_cperror.py +++ b/cherrypy/_cperror.py @@ -8,6 +8,7 @@ from cherrypy.lib import httputil as _httputil class CherryPyException(Exception): + """A base class for CherryPy exceptions.""" pass diff --git a/cherrypy/_cprequest.py b/cherrypy/_cprequest.py index b80b56f8..6bca67b3 100644 --- a/cherrypy/_cprequest.py +++ b/cherrypy/_cprequest.py @@ -246,11 +246,11 @@ class Request(object): protocol = (1, 1) protocol__doc = """The HTTP protocol version corresponding to the set - of features which should be allowed in the response. If BOTH - the client's request message AND the server's level of HTTP - compliance is HTTP/1.1, this attribute will be the tuple (1, 1). - If either is 1.0, this attribute will be the tuple (1, 0). - Lower HTTP protocol versions are not explicitly supported.""" + of features which should be allowed in the response. If BOTH + the client's request message AND the server's level of HTTP + compliance is HTTP/1.1, this attribute will be the tuple (1, 1). + If either is 1.0, this attribute will be the tuple (1, 0). + Lower HTTP protocol versions are not explicitly supported.""" params = {} params__doc = """ @@ -318,16 +318,6 @@ class Request(object): this value is set between the 'before_request_body' and 'before_handler' hooks (assuming that process_request_body is True).""" - body_params = None - body_params__doc = """ - If the request Content-Type is 'application/x-www-form-urlencoded' or - multipart, this will be a dict of the params pulled from the entity - body; that is, it will be the portion of request.params that come - from the message body (sometimes called "POST params", although they - can be sent with various HTTP method verbs). This value is set between - the 'before_request_body' and 'before_handler' hooks (assuming that - process_request_body is True).""" - # Dispatch attributes dispatch = cherrypy.dispatch.Dispatcher() dispatch__doc = """ @@ -513,16 +503,20 @@ class Request(object): """Process the Request. (Core) method, path, query_string, and req_protocol should be pulled directly - from the Request-Line (e.g. "GET /path?key=val HTTP/1.0"). + from the Request-Line (e.g. "GET /path?key=val HTTP/1.0"). + path should be %XX-unquoted, but query_string should not be. - They both MUST be byte strings, not unicode strings. + They both MUST be byte strings, not unicode strings. + headers should be a list of (name, value) tuples. + rfile should be a file-like object containing the HTTP request entity. When run() is done, the returned object should have 3 attributes: - status, e.g. "200 OK" - header_list, a list of (name, value) tuples - body, an iterable yielding strings + + * status, e.g. "200 OK" + * header_list, a list of (name, value) tuples + * body, an iterable yielding strings Consumer code (HTTP servers) should then access these response attributes to build the outbound stream. @@ -833,8 +827,10 @@ class Response(object): names (in Title-Case format); however, you may get and set them in a case-insensitive manner. That is, headers['Content-Type'] and headers['content-type'] refer to the same value. Values are header - values (decoded according to RFC 2047 if necessary). See also: - httputil.HeaderMap, httputil.HeaderElement.""" + values (decoded according to RFC 2047 if necessary). + + .. seealso:: classes :class:`HeaderMap`, :class:`HeaderElement` + """ cookie = SimpleCookie() cookie__doc = """See help(Cookie).""" diff --git a/cherrypy/_cptree.py b/cherrypy/_cptree.py index 9c89bdb8..8f34fd5a 100644 --- a/cherrypy/_cptree.py +++ b/cherrypy/_cptree.py @@ -8,10 +8,10 @@ from cherrypy.lib import httputil class Application(object): """A CherryPy Application. - + Servers and gateways should not instantiate Request objects directly. Instead, they should ask an Application object for a request object. - + An instance of this class may also be used as a WSGI callable (WSGI application object) for itself. """ @@ -19,16 +19,14 @@ class Application(object): __metaclass__ = cherrypy._AttributeDocstrings root = None - root__doc = """ - The top-most container of page handlers for this app. Handlers should + root__doc = """The top-most container of page handlers for this app. Handlers should be arranged in a hierarchy of attributes, matching the expected URI hierarchy; the default dispatcher then searches this hierarchy for a matching handler. When using a dispatcher other than the default, this value may be None.""" config = {} - config__doc = """ - A dict of {path: pathconf} pairs, where 'pathconf' is itself a dict + config__doc = """A dict of {path: pathconf} pairs, where 'pathconf' is itself a dict of {key: value} pairs.""" namespaces = _cpconfig.NamespaceSet() @@ -63,8 +61,7 @@ class Application(object): return "%s.%s(%r, %r)" % (self.__module__, self.__class__.__name__, self.root, self.script_name) - script_name__doc = """ - The URI "mount point" for this app. A mount point is that portion of + script_name_doc = """The URI "mount point" for this app. A mount point is that portion of the URI which is constant for all URIs that are serviced by this application; it does not include scheme, host, or proxy ("virtual host") portions of the URI. @@ -89,7 +86,7 @@ class Application(object): value = value.rstrip("/") self._script_name = value script_name = property(fget=_get_script_name, fset=_set_script_name, - doc=script_name__doc) + doc=script_name_doc) def merge(self, config): """Merge the given config into self.config.""" @@ -170,11 +167,14 @@ class Tree(object): def mount(self, root, script_name="", config=None): """Mount a new app from a root object, script_name, and config. - root: an instance of a "controller class" (a collection of page + root + An instance of a "controller class" (a collection of page handler methods) which represents the root of the application. This may also be an Application instance, or None if using a dispatcher other than the default. - script_name: a string containing the "mount point" of the application. + + script_name + A string containing the "mount point" of the application. This should start with a slash, and be the path portion of the URL at which to mount the given root. For example, if root.index() will handle requests to "http://www.example.com:8080/dept/app1/", @@ -182,7 +182,9 @@ class Tree(object): It MUST NOT end in a slash. If the script_name refers to the root of the URI, it MUST be an empty string (not "/"). - config: a file or dict containing application config. + + config + A file or dict containing application config. """ if script_name is None: raise TypeError( diff --git a/sphinx/source/refman/_cperror.rst b/sphinx/source/refman/_cperror.rst new file mode 100644 index 00000000..1e6042c2 --- /dev/null +++ b/sphinx/source/refman/_cperror.rst @@ -0,0 +1,32 @@ +************************* +:mod:`cherrypy._cperror` +************************* + +.. automodule:: cherrypy._cperror + +Classes +======= + +.. autoclass:: CherryPyException + :members: + +.. autoclass:: TimeoutError + :members: + +.. autoclass:: InternalRedirect + :members: + +.. autoclass:: HTTPRedirect + :members: + +.. autoclass:: HTTPError + :members: + +.. autoclass:: NotFound + :members: + +Functions +========= + +.. autofunction:: format_exc + diff --git a/sphinx/source/refman/_cprequest.rst b/sphinx/source/refman/_cprequest.rst new file mode 100644 index 00000000..475666ae --- /dev/null +++ b/sphinx/source/refman/_cprequest.rst @@ -0,0 +1,22 @@ +************************** +:mod:`cherrypy._cprequest` +************************** + +.. automodule:: cherrypy._cprequest + +Classes +======= + +.. autoclass:: Request + :members: + +.. autoclass:: Response + :members: + +.. autoclass:: Hook + :members: + +.. autoclass:: HookMap + :members: + + |