Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

Changeset 1574

Show
Ignore:
Timestamp:
12/28/06 14:34:24
Author:
fumanchu
Message:

Moved checker back to cherrypy.checker from engine, and also added a new check_config_types method. There's also a new checker config namespace, so you can turn off the checker with "checker.on = False", or turn off specific methods with "checker.check_method_foo = None".

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/cherrypy/__init__.py

    r1546 r1574  
    270270# without shadowing cherrypy.config. 
    271271config = _global_conf_alias = _cpconfig.Config() 
     272 
     273from cherrypy import _cpchecker 
     274checker = _cpchecker.Checker() 
  • trunk/cherrypy/_cpchecker.py

    r1544 r1574  
    77class Checker(object): 
    88     
    9     global_config_contained_paths = False 
     9    on = True 
     10     
     11    def __init__(self): 
     12        self._populate_known_types() 
    1013     
    1114    def __call__(self): 
    12         oldformatwarning = warnings.formatwarning 
    13         warnings.formatwarning = self.formatwarning 
    14         try: 
    15             for name in dir(self): 
    16                 if name.startswith("check_"): 
    17                     method = getattr(self, name) 
    18                     if method and callable(method): 
    19                         method() 
    20         finally: 
    21             warnings.formatwarning = oldformatwarning 
     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 
    2227     
    2328    def formatwarning(self, message, category, filename, lineno): 
    2429        """Function to format a warning.""" 
    2530        return "CherryPy Checker:\n%s\n\n" % message 
     31     
     32    # This value should be set inside _cpconfig. 
     33    global_config_contained_paths = False 
    2634     
    2735    def check_skipped_app_config(self): 
     
    5967                            fulldir = dir 
    6068                            if root: 
    61                                 msg = "dir is an absolute path, even though a root is provided." 
     69                                msg = ("dir is an absolute path, even " 
     70                                       "though a root is provided.") 
    6271                                testdir = os.path.join(root, dir[1:]) 
    6372                                if os.path.exists(testdir): 
    64                                     msg += ("\nIf you meant to serve the filesystem folder at %r, " 
    65                                             "remove the leading slash from dir." % testdir) 
     73                                    msg += ("\nIf you meant to serve the " 
     74                                            "filesystem folder at %r, remove " 
     75                                            "the leading slash from dir." % testdir) 
    6676                        else: 
    6777                            if not root: 
     
    7585                            if msg: 
    7686                                msg += "\n" 
    77                             msg += "%r (root + dir) is not an existing filesystem path." % fulldir 
     87                            msg += ("%r (root + dir) is not an existing " 
     88                                    "filesystem path." % fulldir) 
    7889                     
    7990                    if msg: 
    8091                        warnings.warn("%s\nsection: [%s]\nroot: %r\ndir: %r" 
    8192                                      % (msg, section, root, dir)) 
     93     
     94     
     95    # -------------------------- Compatibility -------------------------- # 
    8296     
    8397    obsolete = { 
     
    91105        'show_tracebacks': 'request.show_tracebacks', 
    92106        'throw_errors': 'request.throw_errors', 
    93         'profiler.on': 'cherrypy.tree.mount(profiler.make_app(cherrypy.Application(Root())))', 
     107        'profiler.on': ('cherrypy.tree.mount(profiler.make_app(' 
     108                        'cherrypy.Application(Root())))'), 
    94109        } 
    95110     
     
    103118                    if k in self.obsolete: 
    104119                        warnings.warn("%r is obsolete. Use %r instead.\n" 
    105                                       "section: [%s]" % (k, self.obsolete[k], section)) 
     120                                      "section: [%s]" % 
     121                                      (k, self.obsolete[k], section)) 
    106122                    elif k in self.deprecated: 
    107123                        warnings.warn("%r is deprecated. Use %r instead.\n" 
    108                                       "section: [%s]" % (k, self.deprecated[k], section)) 
     124                                      "section: [%s]" % 
     125                                      (k, self.deprecated[k], section)) 
    109126            else: 
    110127                if section in self.obsolete: 
     
    121138            self._compat(app.config) 
    122139     
    123     known_config_namespaces = ["engine", "hooks", "log", "request", 
    124                                "response", "server", "tools", "wsgi"] 
     140     
     141    # ------------------------ Known Namespaces ------------------------ # 
     142     
     143    known_config_namespaces = ["checker", "engine", "hooks", "log", 
     144                               "request", "response", "server", 
     145                               "tools", 
     146                               "wsgi"] 
    125147     
    126148    def _known_ns(self, config): 
     
    132154                    if len(atoms) > 1: 
    133155                        if atoms[0] not in self.known_config_namespaces: 
    134                             if atoms[0] == "cherrypy" and atoms[1] in self.known_config_namespaces: 
     156                            if (atoms[0] == "cherrypy" and 
     157                                    atoms[1] in self.known_config_namespaces): 
    135158                                msg = ("The config entry %r is invalid; " 
    136159                                       "try %r instead.\nsection: [%s]" 
     
    146169        for sn, app in cherrypy.tree.apps.iteritems(): 
    147170            self._known_ns(app.config) 
     171     
     172     
     173    # -------------------------- Config Types -------------------------- # 
     174     
     175    known_config_types = {} 
     176     
     177    def _populate_known_types(self): 
     178        import __builtin__ 
     179        builtins = [x for x in vars(__builtin__).values() 
     180                    if type(x) is type(str)] 
     181         
     182        def traverse(obj, namespace): 
     183            for name in dir(obj): 
     184                vtype = type(getattr(obj, name, None)) 
     185                if vtype in builtins: 
     186                    self.known_config_types[namespace + "." + name] = vtype 
     187         
     188        traverse(cherrypy.request, "request") 
     189        traverse(cherrypy.response, "response") 
     190        traverse(cherrypy.server, "server") 
     191        traverse(cherrypy.engine, "engine") 
     192        traverse(cherrypy.log, "log") 
     193     
     194    def _known_types(self, config): 
     195        msg = ("The config entry %r in section %r is of type %r, " 
     196               "which does not match the expected type %r.") 
     197         
     198        for section, conf in config.iteritems(): 
     199            if isinstance(conf, dict): 
     200                for k, v in conf.iteritems(): 
     201                    if v is not None: 
     202                        expected_type = self.known_config_types.get(k, None) 
     203                        vtype = type(v) 
     204                        if expected_type and vtype != expected_type: 
     205                            warnings.warn(msg % (k, section, vtype.__name__, 
     206                                                 expected_type.__name__)) 
     207            else: 
     208                k, v = section, conf 
     209                if v is not None: 
     210                    expected_type = self.known_config_types.get(k, None) 
     211                    vtype = type(v) 
     212                    if expected_type and vtype != expected_type: 
     213                        warnings.warn(msg % (k, section, vtype.__name__, 
     214                                             expected_type.__name__)) 
     215     
     216    def check_config_types(self): 
     217        """Assert that config values are of the same type as default values.""" 
     218        self._known_types(cherrypy.config) 
     219        for sn, app in cherrypy.tree.apps.iteritems(): 
     220            self._known_types(app.config) 
     221 
     222 
  • trunk/cherrypy/_cpconfig.py

    r1558 r1574  
    7070                These can only be declared in the global config. 
    7171    tools:      Runs and configures additional request-processing packages. 
     72    checker:    Controls the 'checker', which looks for common errors in 
     73                app state (including config) when the engine starts. 
     74                Global config only. 
    7275 
    7376The only key that does not exist in a namespace is the "environment" entry. 
     
    9396    "staging": { 
    9497        'engine.autoreload_on': False, 
    95         'engine.checker': None, 
     98        'checker.on': False, 
    9699        'tools.log_headers.on': False, 
    97100        'request.show_tracebacks': False, 
     
    99102    "production": { 
    100103        'engine.autoreload_on': False, 
    101         'engine.checker': None, 
     104        'checker.on': False, 
    102105        'tools.log_headers.on': False, 
    103106        'request.show_tracebacks': False, 
     
    106109    "test_suite": { 
    107110        'engine.autoreload_on': False, 
    108         'engine.checker': None, 
     111        'checker.on': False, 
    109112        'tools.log_headers.on': False, 
    110113        'request.show_tracebacks': True, 
     
    204207                  "engine": lambda k, v: setattr(cherrypy.engine, k, v), 
    205208                  "log": lambda k, v: setattr(cherrypy.log, k, v), 
     209                  "checker": lambda k, v: setattr(cherrypy.checker, k, v), 
    206210                  } 
    207211     
     
    229233        if isinstance(config.get("global", None), dict): 
    230234            if len(config) > 1: 
    231                 cherrypy.engine.checker.global_config_contained_paths = True 
     235                cherrypy.checker.global_config_contained_paths = True 
    232236            config = config["global"] 
    233237         
  • trunk/cherrypy/_cpengine.py

    r1541 r1574  
    1010 
    1111import cherrypy 
    12 from cherrypy import _cprequest, _cpchecker 
     12from cherrypy import _cprequest 
    1313 
    1414# Use a flag to indicate the state of the application engine. 
     
    5353    autoreload_frequency = 1 
    5454    autoreload_match = ".*" 
    55     checker = _cpchecker.Checker() 
    5655     
    5756    def __init__(self): 
     
    7675        self.state = STARTING 
    7776         
    78         if self.checker: 
    79             self.checker() 
     77        cherrypy.checker() 
    8078         
    8179        for func in self.on_start_engine_list: 
  • trunk/cherrypy/test/checkerdemo.py

    r1544 r1574  
    3434            # Warn special on cherrypy.<known ns>.* 
    3535            '/cpknown': {'cherrypy.tools.encode.on': True}, 
     36            # Warn on mismatched types 
     37            '/conftype': {'request.show_tracebacks': 14}, 
    3638            } 
    3739    cherrypy.quickstart(Root(), config=conf) 

Hosted by WebFaction

Log in as guest/cpguest to create tickets