~ubuntu-branches/debian/wheezy/calibre/wheezy

« back to all changes in this revision

Viewing changes to src/cherrypy/_cpchecker.py

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2012-01-07 11:22:54 UTC
  • mfrom: (29.4.10 precise)
  • Revision ID: package-import@ubuntu.com-20120107112254-n1syr437o46ds802
Tags: 0.8.34+dfsg-1
* New upstream version. (Closes: #654751)
* debian/rules: Do not install calibre copy of chardet; instead, add
  build/binary python-chardet dependency.
* Add disable_plugins.py: Disable plugin dialog. It uses a totally
  non-authenticated and non-trusted way of installing arbitrary code.
  (Closes: #640026)
* debian/rules: Install with POSIX locale, to avoid installing translated
  manpages into the standard locations. (Closes: #646674)

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
import warnings
3
3
 
4
4
import cherrypy
 
5
from cherrypy._cpcompat import iteritems, copykeys, builtins
5
6
 
6
7
 
7
8
class Checker(object):
8
9
    """A checker for CherryPy sites and their mounted applications.
9
10
    
10
 
    on: set this to False to turn off the checker completely.
11
 
    
12
11
    When this object is called at engine startup, it executes each
13
 
    of its own methods whose names start with "check_". If you wish
 
12
    of its own methods whose names start with ``check_``. If you wish
14
13
    to disable selected checks, simply add a line in your global
15
 
    config which sets the appropriate method to False:
16
 
    
17
 
    [global]
18
 
    checker.check_skipped_app_config = False
19
 
    
20
 
    You may also dynamically add or replace check_* methods in this way.
 
14
    config which sets the appropriate method to False::
 
15
    
 
16
        [global]
 
17
        checker.check_skipped_app_config = False
 
18
    
 
19
    You may also dynamically add or replace ``check_*`` methods in this way.
21
20
    """
22
21
    
23
22
    on = True
 
23
    """If True (the default), run all checks; if False, turn off all checks."""
 
24
    
24
25
    
25
26
    def __init__(self):
26
27
        self._populate_known_types()
34
35
                for name in dir(self):
35
36
                    if name.startswith("check_"):
36
37
                        method = getattr(self, name)
37
 
                        if method and callable(method):
 
38
                        if method and hasattr(method, '__call__'):
38
39
                            method()
39
40
            finally:
40
41
                warnings.formatwarning = oldformatwarning
46
47
    # This value should be set inside _cpconfig.
47
48
    global_config_contained_paths = False
48
49
    
 
50
    def check_app_config_entries_dont_start_with_script_name(self):
 
51
        """Check for Application config with sections that repeat script_name."""
 
52
        for sn, app in cherrypy.tree.apps.items():
 
53
            if not isinstance(app, cherrypy.Application):
 
54
                continue
 
55
            if not app.config:
 
56
                continue
 
57
            if sn == '':
 
58
                continue
 
59
            sn_atoms = sn.strip("/").split("/")
 
60
            for key in app.config.keys():
 
61
                key_atoms = key.strip("/").split("/")
 
62
                if key_atoms[:len(sn_atoms)] == sn_atoms:
 
63
                    warnings.warn(
 
64
                        "The application mounted at %r has config " \
 
65
                        "entries that start with its script name: %r" % (sn, key))
 
66
    
 
67
    def check_site_config_entries_in_app_config(self):
 
68
        """Check for mounted Applications that have site-scoped config."""
 
69
        for sn, app in iteritems(cherrypy.tree.apps):
 
70
            if not isinstance(app, cherrypy.Application):
 
71
                continue
 
72
            
 
73
            msg = []
 
74
            for section, entries in iteritems(app.config):
 
75
                if section.startswith('/'):
 
76
                    for key, value in iteritems(entries):
 
77
                        for n in ("engine.", "server.", "tree.", "checker."):
 
78
                            if key.startswith(n):
 
79
                                msg.append("[%s] %s = %s" % (section, key, value))
 
80
            if msg:
 
81
                msg.insert(0,
 
82
                    "The application mounted at %r contains the following "
 
83
                    "config entries, which are only allowed in site-wide "
 
84
                    "config. Move them to a [global] section and pass them "
 
85
                    "to cherrypy.config.update() instead of tree.mount()." % sn)
 
86
                warnings.warn(os.linesep.join(msg))
 
87
    
49
88
    def check_skipped_app_config(self):
50
 
        for sn, app in cherrypy.tree.apps.iteritems():
 
89
        """Check for mounted Applications that have no config."""
 
90
        for sn, app in cherrypy.tree.apps.items():
51
91
            if not isinstance(app, cherrypy.Application):
52
92
                continue
53
93
            if not app.config:
61
101
                warnings.warn(msg)
62
102
                return
63
103
    
 
104
    def check_app_config_brackets(self):
 
105
        """Check for Application config with extraneous brackets in section names."""
 
106
        for sn, app in cherrypy.tree.apps.items():
 
107
            if not isinstance(app, cherrypy.Application):
 
108
                continue
 
109
            if not app.config:
 
110
                continue
 
111
            for key in app.config.keys():
 
112
                if key.startswith("[") or key.endswith("]"):
 
113
                    warnings.warn(
 
114
                        "The application mounted at %r has config " \
 
115
                        "section names with extraneous brackets: %r. "
 
116
                        "Config *files* need brackets; config *dicts* "
 
117
                        "(e.g. passed to tree.mount) do not." % (sn, key))
 
118
    
64
119
    def check_static_paths(self):
 
120
        """Check Application config for incorrect static paths."""
65
121
        # Use the dummy Request object in the main thread.
66
122
        request = cherrypy.request
67
 
        for sn, app in cherrypy.tree.apps.iteritems():
 
123
        for sn, app in cherrypy.tree.apps.items():
68
124
            if not isinstance(app, cherrypy.Application):
69
125
                continue
70
126
            request.app = app
130
186
    
131
187
    def _compat(self, config):
132
188
        """Process config and warn on each obsolete or deprecated entry."""
133
 
        for section, conf in config.iteritems():
 
189
        for section, conf in config.items():
134
190
            if isinstance(conf, dict):
135
 
                for k, v in conf.iteritems():
 
191
                for k, v in conf.items():
136
192
                    if k in self.obsolete:
137
193
                        warnings.warn("%r is obsolete. Use %r instead.\n"
138
194
                                      "section: [%s]" %
152
208
    def check_compatibility(self):
153
209
        """Process config and warn on each obsolete or deprecated entry."""
154
210
        self._compat(cherrypy.config)
155
 
        for sn, app in cherrypy.tree.apps.iteritems():
 
211
        for sn, app in cherrypy.tree.apps.items():
156
212
            if not isinstance(app, cherrypy.Application):
157
213
                continue
158
214
            self._compat(app.config)
164
220
    
165
221
    def _known_ns(self, app):
166
222
        ns = ["wsgi"]
167
 
        ns.extend(app.toolboxes.keys())
168
 
        ns.extend(app.namespaces.keys())
169
 
        ns.extend(app.request_class.namespaces.keys())
170
 
        ns.extend(cherrypy.config.namespaces.keys())
 
223
        ns.extend(copykeys(app.toolboxes))
 
224
        ns.extend(copykeys(app.namespaces))
 
225
        ns.extend(copykeys(app.request_class.namespaces))
 
226
        ns.extend(copykeys(cherrypy.config.namespaces))
171
227
        ns += self.extra_config_namespaces
172
228
        
173
 
        for section, conf in app.config.iteritems():
 
229
        for section, conf in app.config.items():
174
230
            is_path_section = section.startswith("/")
175
231
            if is_path_section and isinstance(conf, dict):
176
 
                for k, v in conf.iteritems():
 
232
                for k, v in conf.items():
177
233
                    atoms = k.split(".")
178
234
                    if len(atoms) > 1:
179
235
                        if atoms[0] not in ns:
197
253
    
198
254
    def check_config_namespaces(self):
199
255
        """Process config and warn on each unknown config namespace."""
200
 
        for sn, app in cherrypy.tree.apps.iteritems():
 
256
        for sn, app in cherrypy.tree.apps.items():
201
257
            if not isinstance(app, cherrypy.Application):
202
258
                continue
203
259
            self._known_ns(app)
210
266
    known_config_types = {}
211
267
    
212
268
    def _populate_known_types(self):
213
 
        import __builtin__
214
 
        builtins = [x for x in vars(__builtin__).values()
215
 
                    if type(x) is type(str)]
 
269
        b = [x for x in vars(builtins).values()
 
270
             if type(x) is type(str)]
216
271
        
217
272
        def traverse(obj, namespace):
218
273
            for name in dir(obj):
 
274
                # Hack for 3.2's warning about body_params
 
275
                if name == 'body_params':
 
276
                    continue
219
277
                vtype = type(getattr(obj, name, None))
220
 
                if vtype in builtins:
 
278
                if vtype in b:
221
279
                    self.known_config_types[namespace + "." + name] = vtype
222
280
        
223
281
        traverse(cherrypy.request, "request")
230
288
        msg = ("The config entry %r in section %r is of type %r, "
231
289
               "which does not match the expected type %r.")
232
290
        
233
 
        for section, conf in config.iteritems():
 
291
        for section, conf in config.items():
234
292
            if isinstance(conf, dict):
235
 
                for k, v in conf.iteritems():
 
293
                for k, v in conf.items():
236
294
                    if v is not None:
237
295
                        expected_type = self.known_config_types.get(k, None)
238
296
                        vtype = type(v)
251
309
    def check_config_types(self):
252
310
        """Assert that config values are of the same type as default values."""
253
311
        self._known_types(cherrypy.config)
254
 
        for sn, app in cherrypy.tree.apps.iteritems():
 
312
        for sn, app in cherrypy.tree.apps.items():
255
313
            if not isinstance(app, cherrypy.Application):
256
314
                continue
257
315
            self._known_types(app.config)
261
319
    
262
320
    def check_localhost(self):
263
321
        """Warn if any socket_host is 'localhost'. See #711."""
264
 
        for k, v in cherrypy.config.iteritems():
 
322
        for k, v in cherrypy.config.items():
265
323
            if k == 'server.socket_host' and v == 'localhost':
266
324
                warnings.warn("The use of 'localhost' as a socket host can "
267
325
                    "cause problems on newer systems, since 'localhost' can "