| 157 | | def _call_namespaces(config, namespaces): |
|---|
| 158 | | """Iterate through config and pass it to each namespace. |
|---|
| 159 | | |
|---|
| 160 | | 'config' should be a flat dict, where keys use dots to separate |
|---|
| 161 | | namespaces, and values are arbitrary. |
|---|
| 162 | | 'namespaces' should be a dict whose keys are strings and whose |
|---|
| 163 | | values are namespace handlers. |
|---|
| 164 | | |
|---|
| 165 | | The first name in each config key is used to look up the corresponding |
|---|
| 166 | | namespace handler. For example, a config entry of {'tools.gzip.on': v} |
|---|
| 167 | | will call the 'tools' namespace handler with the args: ('gzip.on', v) |
|---|
| 168 | | |
|---|
| 169 | | Each handler may be a bare callable, or it may be a context manager |
|---|
| 170 | | with __enter__ and __exit__ methods, in which case the __enter__ |
|---|
| 171 | | method should return the callable. |
|---|
| | 157 | class NamespaceSet(dict): |
|---|
| | 158 | """A dict of config namespace names and handlers. |
|---|
| | 159 | |
|---|
| | 160 | Each config entry should begin with a namespace name; the corresponding |
|---|
| | 161 | namespace handler will be called once for each config entry in that |
|---|
| | 162 | namespace, and will be passed two arguments: the config key (with the |
|---|
| | 163 | namespace removed) and the config value. |
|---|
| | 164 | |
|---|
| | 165 | Namespace handlers may be any Python callable; they may also be |
|---|
| | 166 | Python 2.5-style 'context managers', in which case their __enter__ |
|---|
| | 167 | method should return a callable to be used as the handler. |
|---|
| | 168 | See cherrypy.tools (the Toolbox class) for an example. |
|---|
| 173 | | # Separate the given config into namespaces |
|---|
| 174 | | ns_confs = {} |
|---|
| 175 | | for k in config: |
|---|
| 176 | | if "." in k: |
|---|
| 177 | | ns, name = k.split(".", 1) |
|---|
| 178 | | bucket = ns_confs.setdefault(ns, {}) |
|---|
| 179 | | bucket[name] = config[k] |
|---|
| 180 | | |
|---|
| 181 | | # I chose __enter__ and __exit__ so someday this could be |
|---|
| 182 | | # rewritten using Python 2.5's 'with' statement: |
|---|
| 183 | | # for ns, handler in namespaces.iteritems(): |
|---|
| 184 | | # with handler as callable: |
|---|
| 185 | | # for k, v in ns_confs.get(ns, {}).iteritems(): |
|---|
| 186 | | # callable(k, v) |
|---|
| 187 | | for ns, handler in namespaces.iteritems(): |
|---|
| 188 | | exit = getattr(handler, "__exit__", None) |
|---|
| 189 | | if exit: |
|---|
| 190 | | callable = handler.__enter__() |
|---|
| 191 | | no_exc = True |
|---|
| 192 | | try: |
|---|
| | 170 | |
|---|
| | 171 | def __call__(self, config): |
|---|
| | 172 | """Iterate through config and pass it to each namespace handler. |
|---|
| | 173 | |
|---|
| | 174 | 'config' should be a flat dict, where keys use dots to separate |
|---|
| | 175 | namespaces, and values are arbitrary. |
|---|
| | 176 | |
|---|
| | 177 | The first name in each config key is used to look up the corresponding |
|---|
| | 178 | namespace handler. For example, a config entry of {'tools.gzip.on': v} |
|---|
| | 179 | will call the 'tools' namespace handler with the args: ('gzip.on', v) |
|---|
| | 180 | """ |
|---|
| | 181 | # Separate the given config into namespaces |
|---|
| | 182 | ns_confs = {} |
|---|
| | 183 | for k in config: |
|---|
| | 184 | if "." in k: |
|---|
| | 185 | ns, name = k.split(".", 1) |
|---|
| | 186 | bucket = ns_confs.setdefault(ns, {}) |
|---|
| | 187 | bucket[name] = config[k] |
|---|
| | 188 | |
|---|
| | 189 | # I chose __enter__ and __exit__ so someday this could be |
|---|
| | 190 | # rewritten using Python 2.5's 'with' statement: |
|---|
| | 191 | # for ns, handler in self.iteritems(): |
|---|
| | 192 | # with handler as callable: |
|---|
| | 193 | # for k, v in ns_confs.get(ns, {}).iteritems(): |
|---|
| | 194 | # callable(k, v) |
|---|
| | 195 | for ns, handler in self.iteritems(): |
|---|
| | 196 | exit = getattr(handler, "__exit__", None) |
|---|
| | 197 | if exit: |
|---|
| | 198 | callable = handler.__enter__() |
|---|
| | 199 | no_exc = True |
|---|
| 194 | | for k, v in ns_confs.get(ns, {}).iteritems(): |
|---|
| 195 | | callable(k, v) |
|---|
| 196 | | except: |
|---|
| 197 | | # The exceptional case is handled here |
|---|
| 198 | | no_exc = False |
|---|
| 199 | | if exit is None: |
|---|
| 200 | | raise |
|---|
| 201 | | if not exit(*sys.exc_info()): |
|---|
| 202 | | raise |
|---|
| 203 | | # The exception is swallowed if exit() returns true |
|---|
| 204 | | finally: |
|---|
| 205 | | # The normal and non-local-goto cases are handled here |
|---|
| 206 | | if no_exc and exit: |
|---|
| 207 | | exit(None, None, None) |
|---|
| 208 | | else: |
|---|
| 209 | | for k, v in ns_confs.get(ns, {}).iteritems(): |
|---|
| 210 | | handler(k, v) |
|---|
| | 201 | try: |
|---|
| | 202 | for k, v in ns_confs.get(ns, {}).iteritems(): |
|---|
| | 203 | callable(k, v) |
|---|
| | 204 | except: |
|---|
| | 205 | # The exceptional case is handled here |
|---|
| | 206 | no_exc = False |
|---|
| | 207 | if exit is None: |
|---|
| | 208 | raise |
|---|
| | 209 | if not exit(*sys.exc_info()): |
|---|
| | 210 | raise |
|---|
| | 211 | # The exception is swallowed if exit() returns true |
|---|
| | 212 | finally: |
|---|
| | 213 | # The normal and non-local-goto cases are handled here |
|---|
| | 214 | if no_exc and exit: |
|---|
| | 215 | exit(None, None, None) |
|---|
| | 216 | else: |
|---|
| | 217 | for k, v in ns_confs.get(ns, {}).iteritems(): |
|---|
| | 218 | handler(k, v) |
|---|
| | 219 | |
|---|
| | 220 | def __repr__(self): |
|---|
| | 221 | return "%s.%s(%s)" % (self.__module__, self.__class__.__name__, |
|---|
| | 222 | dict.__repr__(self)) |
|---|
| | 223 | |
|---|
| | 224 | def __copy__(self): |
|---|
| | 225 | newobj = self.__class__() |
|---|
| | 226 | newobj.update(self) |
|---|
| | 227 | return newobj |
|---|
| | 228 | copy = __copy__ |
|---|
| 222 | | namespaces = {"server": lambda k, v: setattr(cherrypy.server, k, v), |
|---|
| 223 | | "engine": lambda k, v: setattr(cherrypy.engine, k, v), |
|---|
| 224 | | "log": lambda k, v: setattr(cherrypy.log, k, v), |
|---|
| 225 | | "checker": lambda k, v: setattr(cherrypy.checker, k, v), |
|---|
| 226 | | } |
|---|
| | 240 | namespaces = NamespaceSet( |
|---|
| | 241 | **{"server": lambda k, v: setattr(cherrypy.server, k, v), |
|---|
| | 242 | "engine": lambda k, v: setattr(cherrypy.engine, k, v), |
|---|
| | 243 | "log": lambda k, v: setattr(cherrypy.log, k, v), |
|---|
| | 244 | "checker": lambda k, v: setattr(cherrypy.checker, k, v), |
|---|
| | 245 | }) |
|---|