Python cherrypy.engine() Examples

The following are 30 code examples of cherrypy.engine(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module cherrypy , or try the search function .
Example #1
Source File: test_states.py    From bazarr with GNU General Public License v3.0 6 votes vote down vote up
def test_5_Start_Error(self):
        # If test_3 has not been executed, the server won't be stopped,
        # so we'll have to do it.
        if engine.state != engine.states.EXITING:
            engine.exit()

        # If a process errors during start, it should stop the engine
        # and exit with a non-zero exit code.
        p = helper.CPProcess(ssl=(self.scheme.lower() == 'https'),
                             wait=True)
        p.write_conf(
            extra="""starterror: True
test_case_name: "test_5_Start_Error"
"""
        )
        p.start(imports='cherrypy.test._test_states_demo')
        if p.exit_code == 0:
            self.fail('Process failed to return nonzero exit code.') 
Example #2
Source File: _cpconfig.py    From moviegrabber with GNU General Public License v3.0 6 votes vote down vote up
def merge(base, other):
    """Merge one app config (from a dict, file, or filename) into another.
    
    If the given config is a filename, it will be appended to
    the list of files to monitor for "autoreload" changes.
    """
    if isinstance(other, basestring):
        cherrypy.engine.autoreload.files.add(other)
    
    # Load other into base
    for section, value_map in reprconf.as_dict(other).items():
        if not isinstance(value_map, dict):
            raise ValueError(
                "Application config must include section headers, but the "
                "config you tried to merge doesn't have any sections. "
                "Wrap your config in another dict with paths as section "
                "headers, for example: {'/': config}.")
        base.setdefault(section, {}).update(value_map) 
Example #3
Source File: test_states.py    From cherrypy with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def setup_server():
    class Root:

        @cherrypy.expose
        def index(self):
            return 'Hello World'

        @cherrypy.expose
        def ctrlc(self):
            raise KeyboardInterrupt()

        @cherrypy.expose
        def graceful(self):
            engine.graceful()
            return 'app was (gracefully) restarted succesfully'

    cherrypy.tree.mount(Root())
    cherrypy.config.update({
        'environment': 'test_suite',
    })

    db_connection.subscribe()

# ------------ Enough helpers. Time for real live test cases. ------------ # 
Example #4
Source File: _cpchecker.py    From cherrypy with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def _populate_known_types(self):
        b = [x for x in vars(builtins).values()
             if type(x) is type(str)]

        def traverse(obj, namespace):
            for name in dir(obj):
                # Hack for 3.2's warning about body_params
                if name == 'body_params':
                    continue
                vtype = type(getattr(obj, name, None))
                if vtype in b:
                    self.known_config_types[namespace + '.' + name] = vtype

        traverse(cherrypy.request, 'request')
        traverse(cherrypy.response, 'response')
        traverse(cherrypy.server, 'server')
        traverse(cherrypy.engine, 'engine')
        traverse(cherrypy.log, 'log') 
Example #5
Source File: test_states.py    From cherrypy with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def test_5_Start_Error(self):
        # If test_3 has not been executed, the server won't be stopped,
        # so we'll have to do it.
        if engine.state != engine.states.EXITING:
            engine.exit()

        # If a process errors during start, it should stop the engine
        # and exit with a non-zero exit code.
        p = helper.CPProcess(ssl=(self.scheme.lower() == 'https'),
                             wait=True)
        p.write_conf(
            extra="""starterror: True
test_case_name: "test_5_Start_Error"
"""
        )
        p.start(imports='cherrypy.test._test_states_demo')
        if p.exit_code == 0:
            self.fail('Process failed to return nonzero exit code.') 
Example #6
Source File: _cpconfig.py    From cherrypy with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def _engine_namespace_handler(k, v):
    """Config handler for the "engine" namespace."""
    engine = cherrypy.engine

    if k in {'SIGHUP', 'SIGTERM'}:
        engine.subscribe(k, v)
        return

    if '.' in k:
        plugin, attrname = k.split('.', 1)
        plugin = getattr(engine, plugin)
        op = 'subscribe' if v else 'unsubscribe'
        sub_unsub = getattr(plugin, op, None)
        if attrname == 'on' and callable(sub_unsub):
            sub_unsub()
            return
        setattr(plugin, attrname, v)
    else:
        setattr(engine, k, v) 
Example #7
Source File: sessions.py    From moviegrabber with GNU General Public License v3.0 6 votes vote down vote up
def load(self):
        """Copy stored session data into this session instance."""
        data = self._load()
        # data is either None or a tuple (session_data, expiration_time)
        if data is None or data[1] < self.now():
            if self.debug:
                cherrypy.log('Expired session, flushing data', 'TOOLS.SESSIONS')
            self._data = {}
        else:
            self._data = data[0]
        self.loaded = True
        
        # Stick the clean_thread in the class, not the instance.
        # The instances are created and destroyed per-request.
        cls = self.__class__
        if self.clean_freq and not cls.clean_thread:
            # clean_up is in instancemethod and not a classmethod,
            # so that tool config can be accessed inside the method.
            t = cherrypy.process.plugins.Monitor(
                cherrypy.engine, self.clean_up, self.clean_freq * 60,
                name='Session cleanup')
            t.subscribe()
            cls.clean_thread = t
            t.start() 
Example #8
Source File: desktop_app_main.py    From djanban with MIT License 6 votes vote down vote up
def add_server(self, netloc, path, config):
        """Add a new CherryPy Application for a Virtual Host.
        Creates a new CherryPy WSGI Server instance if the host resolves
        to a different IP address or port.
        """

        from cherrypy._cpwsgi_server import CPWSGIServer
        from cherrypy.process.servers import ServerAdapter

        host, port = urllib.splitnport(netloc, 80)
        host = socket.gethostbyname(host)
        bind_addr = (host, port)
        if bind_addr not in self.servers:
            self.servers.append(bind_addr)
            server = CPWSGIServer()
            server.bind_addr = bind_addr
            adapter = ServerAdapter(cherrypy.engine, server, server.bind_addr)
            adapter.subscribe()
        self.domains[netloc] = cherrypy.Application(root=None,
            config={path.rstrip('/') or '/': config}) 
Example #9
Source File: _cpchecker.py    From moviegrabber with GNU General Public License v3.0 6 votes vote down vote up
def _populate_known_types(self):
        b = [x for x in vars(builtins).values()
             if type(x) is type(str)]
        
        def traverse(obj, namespace):
            for name in dir(obj):
                # Hack for 3.2's warning about body_params
                if name == 'body_params':
                    continue
                vtype = type(getattr(obj, name, None))
                if vtype in b:
                    self.known_config_types[namespace + "." + name] = vtype
        
        traverse(cherrypy.request, "request")
        traverse(cherrypy.response, "response")
        traverse(cherrypy.server, "server")
        traverse(cherrypy.engine, "engine")
        traverse(cherrypy.log, "log") 
Example #10
Source File: _cpchecker.py    From moviegrabber with GNU General Public License v3.0 6 votes vote down vote up
def check_site_config_entries_in_app_config(self):
        """Check for mounted Applications that have site-scoped config."""
        for sn, app in iteritems(cherrypy.tree.apps):
            if not isinstance(app, cherrypy.Application):
                continue
            
            msg = []
            for section, entries in iteritems(app.config):
                if section.startswith('/'):
                    for key, value in iteritems(entries):
                        for n in ("engine.", "server.", "tree.", "checker."):
                            if key.startswith(n):
                                msg.append("[%s] %s = %s" % (section, key, value))
            if msg:
                msg.insert(0,
                    "The application mounted at %r contains the following "
                    "config entries, which are only allowed in site-wide "
                    "config. Move them to a [global] section and pass them "
                    "to cherrypy.config.update() instead of tree.mount()." % sn)
                warnings.warn(os.linesep.join(msg)) 
Example #11
Source File: _cpconfig.py    From Tautulli with GNU General Public License v3.0 6 votes vote down vote up
def _engine_namespace_handler(k, v):
    """Config handler for the "engine" namespace."""
    engine = cherrypy.engine

    if k in {'SIGHUP', 'SIGTERM'}:
        engine.subscribe(k, v)
        return

    if '.' in k:
        plugin, attrname = k.split('.', 1)
        plugin = getattr(engine, plugin)
        op = 'subscribe' if v else 'unsubscribe'
        sub_unsub = getattr(plugin, op, None)
        if attrname == 'on' and callable(sub_unsub):
            sub_unsub()
            return
        setattr(plugin, attrname, v)
    else:
        setattr(engine, k, v) 
Example #12
Source File: _cpchecker.py    From opsbro with MIT License 6 votes vote down vote up
def _populate_known_types(self):
        b = [x for x in vars(builtins).values()
             if type(x) is type(str)]

        def traverse(obj, namespace):
            for name in dir(obj):
                # Hack for 3.2's warning about body_params
                if name == 'body_params':
                    continue
                vtype = type(getattr(obj, name, None))
                if vtype in b:
                    self.known_config_types[namespace + "." + name] = vtype

        traverse(cherrypy.request, "request")
        traverse(cherrypy.response, "response")
        traverse(cherrypy.server, "server")
        traverse(cherrypy.engine, "engine")
        traverse(cherrypy.log, "log") 
Example #13
Source File: test_states.py    From Tautulli with GNU General Public License v3.0 6 votes vote down vote up
def test_5_Start_Error(self):
        # If test_3 has not been executed, the server won't be stopped,
        # so we'll have to do it.
        if engine.state != engine.states.EXITING:
            engine.exit()

        # If a process errors during start, it should stop the engine
        # and exit with a non-zero exit code.
        p = helper.CPProcess(ssl=(self.scheme.lower() == 'https'),
                             wait=True)
        p.write_conf(
            extra="""starterror: True
test_case_name: "test_5_Start_Error"
"""
        )
        p.start(imports='cherrypy.test._test_states_demo')
        if p.exit_code == 0:
            self.fail('Process failed to return nonzero exit code.') 
Example #14
Source File: test_states.py    From Tautulli with GNU General Public License v3.0 6 votes vote down vote up
def setup_server():
    class Root:

        @cherrypy.expose
        def index(self):
            return 'Hello World'

        @cherrypy.expose
        def ctrlc(self):
            raise KeyboardInterrupt()

        @cherrypy.expose
        def graceful(self):
            engine.graceful()
            return 'app was (gracefully) restarted succesfully'

    cherrypy.tree.mount(Root())
    cherrypy.config.update({
        'environment': 'test_suite',
    })

    db_connection.subscribe()

# ------------ Enough helpers. Time for real live test cases. ------------ # 
Example #15
Source File: _cpchecker.py    From bazarr with GNU General Public License v3.0 6 votes vote down vote up
def check_site_config_entries_in_app_config(self):
        """Check for mounted Applications that have site-scoped config."""
        for sn, app in iteritems(cherrypy.tree.apps):
            if not isinstance(app, cherrypy.Application):
                continue

            msg = []
            for section, entries in iteritems(app.config):
                if section.startswith('/'):
                    for key, value in iteritems(entries):
                        for n in ('engine.', 'server.', 'tree.', 'checker.'):
                            if key.startswith(n):
                                msg.append('[%s] %s = %s' %
                                           (section, key, value))
            if msg:
                msg.insert(0,
                           'The application mounted at %r contains the '
                           'following config entries, which are only allowed '
                           'in site-wide config. Move them to a [global] '
                           'section and pass them to cherrypy.config.update() '
                           'instead of tree.mount().' % sn)
                warnings.warn(os.linesep.join(msg)) 
Example #16
Source File: _cpchecker.py    From bazarr with GNU General Public License v3.0 6 votes vote down vote up
def _populate_known_types(self):
        b = [x for x in vars(builtins).values()
             if type(x) is type(str)]

        def traverse(obj, namespace):
            for name in dir(obj):
                # Hack for 3.2's warning about body_params
                if name == 'body_params':
                    continue
                vtype = type(getattr(obj, name, None))
                if vtype in b:
                    self.known_config_types[namespace + '.' + name] = vtype

        traverse(cherrypy.request, 'request')
        traverse(cherrypy.response, 'response')
        traverse(cherrypy.server, 'server')
        traverse(cherrypy.engine, 'engine')
        traverse(cherrypy.log, 'log') 
Example #17
Source File: _cpchecker.py    From opsbro with MIT License 6 votes vote down vote up
def check_site_config_entries_in_app_config(self):
        """Check for mounted Applications that have site-scoped config."""
        for sn, app in iteritems(cherrypy.tree.apps):
            if not isinstance(app, cherrypy.Application):
                continue

            msg = []
            for section, entries in iteritems(app.config):
                if section.startswith('/'):
                    for key, value in iteritems(entries):
                        for n in ("engine.", "server.", "tree.", "checker."):
                            if key.startswith(n):
                                msg.append("[%s] %s = %s" %
                                           (section, key, value))
            if msg:
                msg.insert(0,
                           "The application mounted at %r contains the "
                           "following config entries, which are only allowed "
                           "in site-wide config. Move them to a [global] "
                           "section and pass them to cherrypy.config.update() "
                           "instead of tree.mount()." % sn)
                warnings.warn(os.linesep.join(msg)) 
Example #18
Source File: _cpchecker.py    From Tautulli with GNU General Public License v3.0 6 votes vote down vote up
def _populate_known_types(self):
        b = [x for x in vars(builtins).values()
             if type(x) is type(str)]

        def traverse(obj, namespace):
            for name in dir(obj):
                # Hack for 3.2's warning about body_params
                if name == 'body_params':
                    continue
                vtype = type(getattr(obj, name, None))
                if vtype in b:
                    self.known_config_types[namespace + '.' + name] = vtype

        traverse(cherrypy.request, 'request')
        traverse(cherrypy.response, 'response')
        traverse(cherrypy.server, 'server')
        traverse(cherrypy.engine, 'engine')
        traverse(cherrypy.log, 'log') 
Example #19
Source File: _cpchecker.py    From Tautulli with GNU General Public License v3.0 6 votes vote down vote up
def check_site_config_entries_in_app_config(self):
        """Check for mounted Applications that have site-scoped config."""
        for sn, app in six.iteritems(cherrypy.tree.apps):
            if not isinstance(app, cherrypy.Application):
                continue

            msg = []
            for section, entries in six.iteritems(app.config):
                if section.startswith('/'):
                    for key, value in six.iteritems(entries):
                        for n in ('engine.', 'server.', 'tree.', 'checker.'):
                            if key.startswith(n):
                                msg.append('[%s] %s = %s' %
                                           (section, key, value))
            if msg:
                msg.insert(0,
                           'The application mounted at %r contains the '
                           'following config entries, which are only allowed '
                           'in site-wide config. Move them to a [global] '
                           'section and pass them to cherrypy.config.update() '
                           'instead of tree.mount().' % sn)
                warnings.warn(os.linesep.join(msg)) 
Example #20
Source File: _cpchecker.py    From cherrypy with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def check_site_config_entries_in_app_config(self):
        """Check for mounted Applications that have site-scoped config."""
        for sn, app in cherrypy.tree.apps.items():
            if not isinstance(app, cherrypy.Application):
                continue

            msg = []
            for section, entries in app.config.items():
                if section.startswith('/'):
                    for key, value in entries.items():
                        for n in ('engine.', 'server.', 'tree.', 'checker.'):
                            if key.startswith(n):
                                msg.append('[%s] %s = %s' %
                                           (section, key, value))
            if msg:
                msg.insert(0,
                           'The application mounted at %r contains the '
                           'following config entries, which are only allowed '
                           'in site-wide config. Move them to a [global] '
                           'section and pass them to cherrypy.config.update() '
                           'instead of tree.mount().' % sn)
                warnings.warn(os.linesep.join(msg)) 
Example #21
Source File: _cpconfig.py    From bazarr with GNU General Public License v3.0 6 votes vote down vote up
def _engine_namespace_handler(k, v):
    """Config handler for the "engine" namespace."""
    engine = cherrypy.engine

    if k == 'SIGHUP':
        engine.subscribe('SIGHUP', v)
    elif k == 'SIGTERM':
        engine.subscribe('SIGTERM', v)
    elif '.' in k:
        plugin, attrname = k.split('.', 1)
        plugin = getattr(engine, plugin)
        if attrname == 'on':
            if v and hasattr(getattr(plugin, 'subscribe', None), '__call__'):
                plugin.subscribe()
                return
            elif (
                (not v) and
                hasattr(getattr(plugin, 'unsubscribe', None), '__call__')
            ):
                plugin.unsubscribe()
                return
        setattr(plugin, attrname, v)
    else:
        setattr(engine, k, v) 
Example #22
Source File: _cpconfig.py    From bazarr with GNU General Public License v3.0 6 votes vote down vote up
def merge(base, other):
    """Merge one app config (from a dict, file, or filename) into another.

    If the given config is a filename, it will be appended to
    the list of files to monitor for "autoreload" changes.
    """
    if isinstance(other, text_or_bytes):
        cherrypy.engine.autoreload.files.add(other)

    # Load other into base
    for section, value_map in reprconf.as_dict(other).items():
        if not isinstance(value_map, dict):
            raise ValueError(
                'Application config must include section headers, but the '
                "config you tried to merge doesn't have any sections. "
                'Wrap your config in another dict with paths as section '
                "headers, for example: {'/': config}.")
        base.setdefault(section, {}).update(value_map) 
Example #23
Source File: test_states.py    From bazarr with GNU General Public License v3.0 5 votes vote down vote up
def test_4_Autoreload(self):
        # If test_3 has not been executed, the server won't be stopped,
        # so we'll have to do it.
        if engine.state != engine.states.EXITING:
            engine.exit()

        # Start the demo script in a new process
        p = helper.CPProcess(ssl=(self.scheme.lower() == 'https'))
        p.write_conf(extra='test_case_name: "test_4_Autoreload"')
        p.start(imports='cherrypy.test._test_states_demo')
        try:
            self.getPage('/start')
            start = float(self.body)

            # Give the autoreloader time to cache the file time.
            time.sleep(2)

            # Touch the file
            os.utime(os.path.join(thisdir, '_test_states_demo.py'), None)

            # Give the autoreloader time to re-exec the process
            time.sleep(2)
            host = cherrypy.server.socket_host
            port = cherrypy.server.socket_port
            cherrypy._cpserver.wait_for_occupied_port(host, port)

            self.getPage('/start')
            if not (float(self.body) > start):
                raise AssertionError('start time %s not greater than %s' %
                                     (float(self.body), start))
        finally:
            # Shut down the spawned process
            self.getPage('/exit')
        p.join() 
Example #24
Source File: test_states.py    From bazarr with GNU General Public License v3.0 5 votes vote down vote up
def test_3_Deadlocks(self):
        cherrypy.config.update({'response.timeout': 0.2})

        engine.start()
        cherrypy.server.start()
        try:
            self.assertNotEqual(engine.timeout_monitor.thread, None)

            # Request a "normal" page.
            self.assertEqual(engine.timeout_monitor.servings, [])
            self.getPage('/')
            self.assertBody('Hello World')
            # request.close is called async.
            while engine.timeout_monitor.servings:
                sys.stdout.write('.')
                time.sleep(0.01)

            # Request a page that explicitly checks itself for deadlock.
            # The deadlock_timeout should be 2 secs.
            self.getPage('/block_explicit')
            self.assertBody('broken!')

            # Request a page that implicitly breaks deadlock.
            # If we deadlock, we want to touch as little code as possible,
            # so we won't even call handle_error, just bail ASAP.
            self.getPage('/block_implicit')
            self.assertStatus(500)
            self.assertInBody('raise cherrypy.TimeoutError()')
        finally:
            engine.exit() 
Example #25
Source File: _cpconfig.py    From moviegrabber with GNU General Public License v3.0 5 votes vote down vote up
def _tree_namespace_handler(k, v):
    """Namespace handler for the 'tree' config namespace."""
    if isinstance(v, dict):
        for script_name, app in v.items():
            cherrypy.tree.graft(app, script_name)
            cherrypy.engine.log("Mounted: %s on %s" % (app, script_name or "/"))
    else:
        cherrypy.tree.graft(v, v.script_name)
        cherrypy.engine.log("Mounted: %s on %s" % (v, v.script_name or "/")) 
Example #26
Source File: test_states.py    From moviegrabber with GNU General Public License v3.0 5 votes vote down vote up
def test_5_Start_Error(self):
        # If a process errors during start, it should stop the engine
        # and exit with a non-zero exit code.
        p = helper.CPProcess(ssl=(self.scheme.lower()=='https'),
                             wait=True)
        p.write_conf(
                extra="""starterror: True
test_case_name: "test_5_Start_Error"
"""
        )
        p.start(imports='cherrypy.test._test_states_demo')
        if p.exit_code == 0:
            self.fail("Process failed to return nonzero exit code.") 
Example #27
Source File: test_states.py    From moviegrabber with GNU General Public License v3.0 5 votes vote down vote up
def test_3_Deadlocks(self):
        cherrypy.config.update({'response.timeout': 0.2})

        engine.start()
        cherrypy.server.start()
        try:
            self.assertNotEqual(engine.timeout_monitor.thread, None)

            # Request a "normal" page.
            self.assertEqual(engine.timeout_monitor.servings, [])
            self.getPage("/")
            self.assertBody("Hello World")
            # request.close is called async.
            while engine.timeout_monitor.servings:
                sys.stdout.write(".")
                time.sleep(0.01)

            # Request a page that explicitly checks itself for deadlock.
            # The deadlock_timeout should be 2 secs.
            self.getPage("/block_explicit")
            self.assertBody("broken!")

            # Request a page that implicitly breaks deadlock.
            # If we deadlock, we want to touch as little code as possible,
            # so we won't even call handle_error, just bail ASAP.
            self.getPage("/block_implicit")
            self.assertStatus(500)
            self.assertInBody("raise cherrypy.TimeoutError()")
        finally:
            engine.exit() 
Example #28
Source File: test_states.py    From moviegrabber with GNU General Public License v3.0 5 votes vote down vote up
def test_2_KeyboardInterrupt(self):
        # Raise a keyboard interrupt in the HTTP server's main thread.
        # We must start the server in this, the main thread
        engine.start()
        cherrypy.server.start()

        self.persistent = True
        try:
            # Make the first request and assert there's no "Connection: close".
            self.getPage("/")
            self.assertStatus('200 OK')
            self.assertBody("Hello World")
            self.assertNoHeader("Connection")

            cherrypy.server.httpserver.interrupt = KeyboardInterrupt
            engine.block()

            self.assertEqual(db_connection.running, False)
            self.assertEqual(len(db_connection.threads), 0)
            self.assertEqual(engine.state, engine.states.EXITING)
        finally:
            self.persistent = False

        # Raise a keyboard interrupt in a page handler; on multithreaded
        # servers, this should occur in one of the worker threads.
        # This should raise a BadStatusLine error, since the worker
        # thread will just die without writing a response.
        engine.start()
        cherrypy.server.start()

        try:
            self.getPage("/ctrlc")
        except BadStatusLine:
            pass
        else:
            print(self.body)
            self.fail("AssertionError: BadStatusLine not raised")

        engine.block()
        self.assertEqual(db_connection.running, False)
        self.assertEqual(len(db_connection.threads), 0) 
Example #29
Source File: sessions.py    From Tautulli with GNU General Public License v3.0 5 votes vote down vote up
def load(self):
        """Copy stored session data into this session instance."""
        data = self._load()
        # data is either None or a tuple (session_data, expiration_time)
        if data is None or data[1] < self.now():
            if self.debug:
                cherrypy.log('Expired session %r, flushing data.' % self.id,
                             'TOOLS.SESSIONS')
            self._data = {}
        else:
            if self.debug:
                cherrypy.log('Data loaded for session %r.' % self.id,
                             'TOOLS.SESSIONS')
            self._data = data[0]
        self.loaded = True

        # Stick the clean_thread in the class, not the instance.
        # The instances are created and destroyed per-request.
        cls = self.__class__
        if self.clean_freq and not cls.clean_thread:
            # clean_up is an instancemethod and not a classmethod,
            # so that tool config can be accessed inside the method.
            t = cherrypy.process.plugins.Monitor(
                cherrypy.engine, self.clean_up, self.clean_freq * 60,
                name='Session cleanup')
            t.subscribe()
            cls.clean_thread = t
            t.start()
            if self.debug:
                cherrypy.log('Started cleanup thread.', 'TOOLS.SESSIONS') 
Example #30
Source File: _cpconfig.py    From moviegrabber with GNU General Public License v3.0 5 votes vote down vote up
def update(self, config):
        """Update self from a dict, file or filename."""
        if isinstance(config, basestring):
            # Filename
            cherrypy.engine.autoreload.files.add(config)
        reprconf.Config.update(self, config)