Package cherrypy :: Module _cpchecker
[hide private]
[frames] | no frames]

Source Code for Module cherrypy._cpchecker

  1  import os 
  2  import warnings 
  3   
  4  import cherrypy 
  5   
  6   
7 -class Checker(object):
8 9 on = True 10
11 - def __init__(self):
13
14 - def __call__(self):
15 """Run all check_* methods.""" 16 if self.on: 17 oldformatwarning = warnings.formatwarning 18 warnings.formatwarning = self.formatwarning 19 try: 20 for name in dir(self): 21 if name.startswith("check_"): 22 method = getattr(self, name) 23 if method and callable(method): 24 method() 25 finally: 26 warnings.formatwarning = oldformatwarning
27
28 - def formatwarning(self, message, category, filename, lineno):
29 """Function to format a warning.""" 30 return "CherryPy Checker:\n%s\n\n" % message
31 32 # This value should be set inside _cpconfig. 33 global_config_contained_paths = False 34
35 - def check_skipped_app_config(self):
36 for sn, app in cherrypy.tree.apps.iteritems(): 37 if not isinstance(app, cherrypy.Application): 38 continue 39 if not app.config: 40 msg = "The Application mounted at %r has an empty config." % sn 41 if self.global_config_contained_paths: 42 msg += (" It looks like the config you passed to " 43 "cherrypy.config.update() contains application-" 44 "specific sections. You must explicitly pass " 45 "application config via " 46 "cherrypy.tree.mount(..., config=app_config)") 47 warnings.warn(msg) 48 return
49
50 - def check_static_paths(self):
51 # Use the dummy Request object in the main thread. 52 request = cherrypy.request 53 for sn, app in cherrypy.tree.apps.iteritems(): 54 if not isinstance(app, cherrypy.Application): 55 continue 56 request.app = app 57 for section in app.config: 58 # get_resource will populate request.config 59 request.get_resource(section + "/dummy.html") 60 conf = request.config.get 61 62 if conf("tools.staticdir.on", False): 63 msg = "" 64 root = conf("tools.staticdir.root") 65 dir = conf("tools.staticdir.dir") 66 if dir is None: 67 msg = "tools.staticdir.dir is not set." 68 else: 69 fulldir = "" 70 if os.path.isabs(dir): 71 fulldir = dir 72 if root: 73 msg = ("dir is an absolute path, even " 74 "though a root is provided.") 75 testdir = os.path.join(root, dir[1:]) 76 if os.path.exists(testdir): 77 msg += ("\nIf you meant to serve the " 78 "filesystem folder at %r, remove " 79 "the leading slash from dir." % testdir) 80 else: 81 if not root: 82 msg = "dir is a relative path and no root provided." 83 else: 84 fulldir = os.path.join(root, dir) 85 if not os.path.isabs(fulldir): 86 msg = "%r is not an absolute path." % fulldir 87 88 if fulldir and not os.path.exists(fulldir): 89 if msg: 90 msg += "\n" 91 msg += ("%r (root + dir) is not an existing " 92 "filesystem path." % fulldir) 93 94 if msg: 95 warnings.warn("%s\nsection: [%s]\nroot: %r\ndir: %r" 96 % (msg, section, root, dir))
97 98 99 # -------------------------- Compatibility -------------------------- # 100 101 obsolete = { 102 'server.default_content_type': 'tools.response_headers.headers', 103 'log_access_file': 'log.access_file', 104 'log_config_options': None, 105 'log_file': 'log.error_file', 106 'log_file_not_found': None, 107 'log_request_headers': 'tools.log_headers.on', 108 'log_to_screen': 'log.screen', 109 'show_tracebacks': 'request.show_tracebacks', 110 'throw_errors': 'request.throw_errors', 111 'profiler.on': ('cherrypy.tree.mount(profiler.make_app(' 112 'cherrypy.Application(Root())))'), 113 } 114 115 deprecated = {} 116
117 - def _compat(self, config):
118 """Process config and warn on each obsolete or deprecated entry.""" 119 for section, conf in config.iteritems(): 120 if isinstance(conf, dict): 121 for k, v in conf.iteritems(): 122 if k in self.obsolete: 123 warnings.warn("%r is obsolete. Use %r instead.\n" 124 "section: [%s]" % 125 (k, self.obsolete[k], section)) 126 elif k in self.deprecated: 127 warnings.warn("%r is deprecated. Use %r instead.\n" 128 "section: [%s]" % 129 (k, self.deprecated[k], section)) 130 else: 131 if section in self.obsolete: 132 warnings.warn("%r is obsolete. Use %r instead." 133 % (section, self.obsolete[section])) 134 elif section in self.deprecated: 135 warnings.warn("%r is deprecated. Use %r instead." 136 % (section, self.deprecated[section]))
137
138 - def check_compatibility(self):
139 """Process config and warn on each obsolete or deprecated entry.""" 140 self._compat(cherrypy.config) 141 for sn, app in cherrypy.tree.apps.iteritems(): 142 if not isinstance(app, cherrypy.Application): 143 continue 144 self._compat(app.config)
145 146 147 # ------------------------ Known Namespaces ------------------------ # 148 149 extra_config_namespaces = [] 150
151 - def _known_ns(self, config):
152 ns = ["wsgi"] 153 ns.extend(cherrypy.engine.request_class.namespaces.keys()) 154 ns.extend(cherrypy.config.namespaces.keys()) 155 ns += self.extra_config_namespaces 156 157 for section, conf in config.iteritems(): 158 is_path_section = section.startswith("/") 159 if is_path_section and isinstance(conf, dict): 160 for k, v in conf.iteritems(): 161 atoms = k.split(".") 162 if len(atoms) > 1: 163 if atoms[0] not in ns: 164 # Spit out a special warning if a known 165 # namespace is preceded by "cherrypy." 166 if (atoms[0] == "cherrypy" and atoms[1] in ns): 167 msg = ("The config entry %r is invalid; " 168 "try %r instead.\nsection: [%s]" 169 % (k, ".".join(atoms[1:]), section)) 170 else: 171 msg = ("The config entry %r is invalid, because " 172 "the %r config namespace is unknown.\n" 173 "section: [%s]" % (k, atoms[0], section)) 174 warnings.warn(msg) 175 elif atoms[0] == "tools": 176 if atoms[1] not in dir(cherrypy.tools): 177 msg = ("The config entry %r may be invalid, " 178 "because the %r tool was not found.\n" 179 "section: [%s]" % (k, atoms[1], section)) 180 warnings.warn(msg)
181
182 - def check_config_namespaces(self):
183 """Process config and warn on each unknown config namespace.""" 184 for sn, app in cherrypy.tree.apps.iteritems(): 185 if not isinstance(app, cherrypy.Application): 186 continue 187 self._known_ns(app.config)
188 189 190 # -------------------------- Config Types -------------------------- # 191 192 known_config_types = {} 193
194 - def _populate_known_types(self):
195 import __builtin__ 196 builtins = [x for x in vars(__builtin__).values() 197 if type(x) is type(str)] 198 199 def traverse(obj, namespace): 200 for name in dir(obj): 201 vtype = type(getattr(obj, name, None)) 202 if vtype in builtins: 203 self.known_config_types[namespace + "." + name] = vtype
204 205 traverse(cherrypy.request, "request") 206 traverse(cherrypy.response, "response") 207 traverse(cherrypy.server, "server") 208 traverse(cherrypy.engine, "engine") 209 traverse(cherrypy.log, "log")
210
211 - def _known_types(self, config):
212 msg = ("The config entry %r in section %r is of type %r, " 213 "which does not match the expected type %r.") 214 215 for section, conf in config.iteritems(): 216 if isinstance(conf, dict): 217 for k, v in conf.iteritems(): 218 if v is not None: 219 expected_type = self.known_config_types.get(k, None) 220 vtype = type(v) 221 if expected_type and vtype != expected_type: 222 warnings.warn(msg % (k, section, vtype.__name__, 223 expected_type.__name__)) 224 else: 225 k, v = section, conf 226 if v is not None: 227 expected_type = self.known_config_types.get(k, None) 228 vtype = type(v) 229 if expected_type and vtype != expected_type: 230 warnings.warn(msg % (k, section, vtype.__name__, 231 expected_type.__name__))
232
233 - def check_config_types(self):
234 """Assert that config values are of the same type as default values.""" 235 self._known_types(cherrypy.config) 236 for sn, app in cherrypy.tree.apps.iteritems(): 237 if not isinstance(app, cherrypy.Application): 238 continue 239 self._known_types(app.config)
240