source file: /Library/Python/2.3/site-packages/CherryPy-3.0.1-py2.3.egg/cherrypy/_cpchecker.py
file stats: 133 lines, 81 executed: 60.9% covered
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): 12. self._populate_known_types() 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 app.config: 38. msg = "The Application mounted at %r has an empty config." % sn 39. if self.global_config_contained_paths: 40. msg += (" It looks like the config you passed to " 41. "cherrypy.config.update() contains application-" 42. "specific sections. You must explicitly pass " 43. "application config via " 44. "cherrypy.tree.mount(..., config=app_config)") 45. warnings.warn(msg) 46. return 47. 48. def check_static_paths(self): 49. # Use the dummy Request object in the main thread. 50. request = cherrypy.request 51. for sn, app in cherrypy.tree.apps.iteritems(): 52. request.app = app 53. for section in app.config: 54. # get_resource will populate request.config 55. request.get_resource(section + "/dummy.html") 56. conf = request.config.get 57. 58. if conf("tools.staticdir.on", False): 59. msg = "" 60. root = conf("tools.staticdir.root") 61. dir = conf("tools.staticdir.dir") 62. if dir is None: 63. msg = "tools.staticdir.dir is not set." 64. else: 65. fulldir = "" 66. if os.path.isabs(dir): 67. fulldir = dir 68. if root: 69. msg = ("dir is an absolute path, even " 70. "though a root is provided.") 71. testdir = os.path.join(root, dir[1:]) 72. if os.path.exists(testdir): 73. msg += ("\nIf you meant to serve the " 74. "filesystem folder at %r, remove " 75. "the leading slash from dir." % testdir) 76. else: 77. if not root: 78. msg = "dir is a relative path and no root provided." 79. else: 80. fulldir = os.path.join(root, dir) 81. if not os.path.isabs(fulldir): 82. msg = "%r is not an absolute path." % fulldir 83. 84. if fulldir and not os.path.exists(fulldir): 85. if msg: 86. msg += "\n" 87. msg += ("%r (root + dir) is not an existing " 88. "filesystem path." % fulldir) 89. 90. if msg: 91. warnings.warn("%s\nsection: [%s]\nroot: %r\ndir: %r" 92. % (msg, section, root, dir)) 93. 94. 95. # -------------------------- Compatibility -------------------------- # 96. 97. obsolete = { 98. 'server.default_content_type': 'tools.response_headers.headers', 99. 'log_access_file': 'log.access_file', 100. 'log_config_options': None, 101. 'log_file': 'log.error_file', 102. 'log_file_not_found': None, 103. 'log_request_headers': 'tools.log_headers.on', 104. 'log_to_screen': 'log.screen', 105. 'show_tracebacks': 'request.show_tracebacks', 106. 'throw_errors': 'request.throw_errors', 107. 'profiler.on': ('cherrypy.tree.mount(profiler.make_app(' 108. 'cherrypy.Application(Root())))'), 109. } 110. 111. deprecated = {} 112. 113. def _compat(self, config): 114. """Process config and warn on each obsolete or deprecated entry.""" 115. for section, conf in config.iteritems(): 116. if isinstance(conf, dict): 117. for k, v in conf.iteritems(): 118. if k in self.obsolete: 119. warnings.warn("%r is obsolete. Use %r instead.\n" 120. "section: [%s]" % 121. (k, self.obsolete[k], section)) 122. elif k in self.deprecated: 123. warnings.warn("%r is deprecated. Use %r instead.\n" 124. "section: [%s]" % 125. (k, self.deprecated[k], section)) 126. else: 127. if section in self.obsolete: 128. warnings.warn("%r is obsolete. Use %r instead." 129. % (section, self.obsolete[section])) 130. elif section in self.deprecated: 131. warnings.warn("%r is deprecated. Use %r instead." 132. % (section, self.deprecated[section])) 133. 134. def check_compatibility(self): 135. """Process config and warn on each obsolete or deprecated entry.""" 136. self._compat(cherrypy.config) 137. for sn, app in cherrypy.tree.apps.iteritems(): 138. self._compat(app.config) 139. 140. 141. # ------------------------ Known Namespaces ------------------------ # 142. 143. extra_config_namespaces = [] 144. 145. def _known_ns(self, config): 146. ns = ["wsgi"] 147. ns.extend(cherrypy.engine.request_class.namespaces.keys()) 148. ns.extend(cherrypy.config.namespaces.keys()) 149. ns += self.extra_config_namespaces 150. 151. for section, conf in config.iteritems(): 152. is_path_section = section.startswith("/") 153. if is_path_section and isinstance(conf, dict): 154. for k, v in conf.iteritems(): 155. atoms = k.split(".") 156. if len(atoms) > 1: 157. if atoms[0] not in ns: 158. if (atoms[0] == "cherrypy" and atoms[1] in ns): 159. msg = ("The config entry %r is invalid; " 160. "try %r instead.\nsection: [%s]" 161. % (k, ".".join(atoms[1:]), section)) 162. else: 163. msg = ("The config entry %r is invalid, because " 164. "the %r config namespace is unknown.\n" 165. "section: [%s]" % (k, atoms[0], section)) 166. warnings.warn(msg) 167. 168. def check_config_namespaces(self): 169. """Process config and warn on each unknown config namespace.""" 170. for sn, app in cherrypy.tree.apps.iteritems(): 171. self._known_ns(app.config) 172. 173. 174. # -------------------------- Config Types -------------------------- # 175. 176. known_config_types = {} 177. 178. def _populate_known_types(self): 179. import __builtin__ 180. builtins = [x for x in vars(__builtin__).values() 181. if type(x) is type(str)] 182. 183. def traverse(obj, namespace): 184. for name in dir(obj): 185. vtype = type(getattr(obj, name, None)) 186. if vtype in builtins: 187. self.known_config_types[namespace + "." + name] = vtype 188. 189. traverse(cherrypy.request, "request") 190. traverse(cherrypy.response, "response") 191. traverse(cherrypy.server, "server") 192. traverse(cherrypy.engine, "engine") 193. traverse(cherrypy.log, "log") 194. 195. def _known_types(self, config): 196. msg = ("The config entry %r in section %r is of type %r, " 197. "which does not match the expected type %r.") 198. 199. for section, conf in config.iteritems(): 200. if isinstance(conf, dict): 201. for k, v in conf.iteritems(): 202. if v is not None: 203. expected_type = self.known_config_types.get(k, None) 204. vtype = type(v) 205. if expected_type and vtype != expected_type: 206. warnings.warn(msg % (k, section, vtype.__name__, 207. expected_type.__name__)) 208. else: 209. k, v = section, conf 210. if v is not None: 211. expected_type = self.known_config_types.get(k, None) 212. vtype = type(v) 213. if expected_type and vtype != expected_type: 214. warnings.warn(msg % (k, section, vtype.__name__, 215. expected_type.__name__)) 216. 217. def check_config_types(self): 218. """Assert that config values are of the same type as default values.""" 219. self._known_types(cherrypy.config) 220. for sn, app in cherrypy.tree.apps.iteritems(): 221. self._known_types(app.config) 222. 223.