Update cherrpy to 17.4.2

This commit is contained in:
JonnyWong16 2019-11-23 18:55:19 -08:00
commit 4d6279a626
131 changed files with 15864 additions and 10389 deletions

View file

@ -46,21 +46,21 @@ To declare global configuration entries, place them in a [global] section.
You may also declare config entries directly on the classes and methods
(page handlers) that make up your CherryPy application via the ``_cp_config``
attribute. For example::
attribute, set with the ``cherrypy.config`` decorator. For example::
@cherrypy.config(**{'tools.gzip.on': True})
class Demo:
_cp_config = {'tools.gzip.on': True}
@cherrypy.expose
@cherrypy.config(**{'request.show_tracebacks': False})
def index(self):
return "Hello world"
index.exposed = True
index._cp_config = {'request.show_tracebacks': False}
.. note::
This behavior is only guaranteed for the default dispatcher.
Other dispatchers may have different restrictions on where
you can attach _cp_config attributes.
you can attach config attributes.
Namespaces
@ -119,11 +119,14 @@ style) context manager.
"""
import cherrypy
from cherrypy._cpcompat import basestring
from cherrypy._cpcompat import text_or_bytes
from cherrypy.lib import reprconf
# Deprecated in CherryPy 3.2--remove in 3.3
NamespaceSet = reprconf.NamespaceSet
def _if_filename_register_autoreload(ob):
"""Register for autoreload if ob is a string (presumed filename)."""
is_filename = isinstance(ob, text_or_bytes)
is_filename and cherrypy.engine.autoreload.files.add(ob)
def merge(base, other):
@ -132,67 +135,68 @@ def merge(base, other):
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)
_if_filename_register_autoreload(other)
# Load other into base
for section, value_map in reprconf.as_dict(other).items():
for section, value_map in reprconf.Parser.load(other).items():
if not isinstance(value_map, dict):
raise ValueError(
"Application config must include section headers, but the "
'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 "
'Wrap your config in another dict with paths as section '
"headers, for example: {'/': config}.")
base.setdefault(section, {}).update(value_map)
class Config(reprconf.Config):
"""The 'global' configuration data for the entire CherryPy process."""
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)
_if_filename_register_autoreload(config)
super(Config, self).update(config)
def _apply(self, config):
"""Update self from a dict."""
if isinstance(config.get("global"), dict):
if isinstance(config.get('global'), dict):
if len(config) > 1:
cherrypy.checker.global_config_contained_paths = True
config = config["global"]
config = config['global']
if 'tools.staticdir.dir' in config:
config['tools.staticdir.section'] = "global"
reprconf.Config._apply(self, config)
def __call__(self, *args, **kwargs):
"""Decorator for page handlers to set _cp_config."""
if args:
raise TypeError(
"The cherrypy.config decorator does not accept positional "
"arguments; you must use keyword arguments.")
config['tools.staticdir.section'] = 'global'
super(Config, self)._apply(config)
@staticmethod
def __call__(**kwargs):
"""Decorate for page handlers to set _cp_config."""
def tool_decorator(f):
if not hasattr(f, "_cp_config"):
f._cp_config = {}
for k, v in kwargs.items():
f._cp_config[k] = v
_Vars(f).setdefault('_cp_config', {}).update(kwargs)
return f
return tool_decorator
class _Vars(object):
"""Adapter allowing setting a default attribute on a function or class."""
def __init__(self, target):
self.target = target
def setdefault(self, key, default):
if not hasattr(self.target, key):
setattr(self.target, key, default)
return getattr(self.target, key)
# Sphinx begin config.environments
Config.environments = environments = {
"staging": {
'staging': {
'engine.autoreload.on': False,
'checker.on': False,
'tools.log_headers.on': False,
'request.show_tracebacks': False,
'request.show_mismatched_params': False,
},
"production": {
'production': {
'engine.autoreload.on': False,
'checker.on': False,
'tools.log_headers.on': False,
@ -200,7 +204,7 @@ Config.environments = environments = {
'request.show_mismatched_params': False,
'log.screen': False,
},
"embedded": {
'embedded': {
# For use with CherryPy embedded in another deployment stack.
'engine.autoreload.on': False,
'checker.on': False,
@ -211,7 +215,7 @@ Config.environments = environments = {
'engine.SIGHUP': None,
'engine.SIGTERM': None,
},
"test_suite": {
'test_suite': {
'engine.autoreload.on': False,
'checker.on': False,
'tools.log_headers.on': False,
@ -225,11 +229,11 @@ Config.environments = environments = {
def _server_namespace_handler(k, v):
"""Config handler for the "server" namespace."""
atoms = k.split(".", 1)
atoms = k.split('.', 1)
if len(atoms) > 1:
# Special-case config keys of the form 'server.servername.socket_port'
# to configure additional HTTP servers.
if not hasattr(cherrypy, "servers"):
if not hasattr(cherrypy, 'servers'):
cherrypy.servers = {}
servername, k = atoms
@ -248,60 +252,33 @@ def _server_namespace_handler(k, v):
setattr(cherrypy.servers[servername], k, v)
else:
setattr(cherrypy.server, k, v)
Config.namespaces["server"] = _server_namespace_handler
Config.namespaces['server'] = _server_namespace_handler
def _engine_namespace_handler(k, v):
"""Backward compatibility handler for the "engine" namespace."""
"""Config handler for the "engine" namespace."""
engine = cherrypy.engine
deprecated = {
'autoreload_on': 'autoreload.on',
'autoreload_frequency': 'autoreload.frequency',
'autoreload_match': 'autoreload.match',
'reload_files': 'autoreload.files',
'deadlock_poll_freq': 'timeout_monitor.frequency'
}
if k in {'SIGHUP', 'SIGTERM'}:
engine.subscribe(k, v)
return
if k in deprecated:
engine.log(
'WARNING: Use of engine.%s is deprecated and will be removed in a '
'future version. Use engine.%s instead.' % (k, deprecated[k]))
if k == 'autoreload_on':
if v:
engine.autoreload.subscribe()
else:
engine.autoreload.unsubscribe()
elif k == 'autoreload_frequency':
engine.autoreload.frequency = v
elif k == 'autoreload_match':
engine.autoreload.match = v
elif k == 'reload_files':
engine.autoreload.files = set(v)
elif k == 'deadlock_poll_freq':
engine.timeout_monitor.frequency = v
elif k == 'SIGHUP':
engine.listeners['SIGHUP'] = set([v])
elif k == 'SIGTERM':
engine.listeners['SIGTERM'] = set([v])
elif "." in k:
plugin, attrname = k.split(".", 1)
if '.' 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
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)
Config.namespaces["engine"] = _engine_namespace_handler
Config.namespaces['engine'] = _engine_namespace_handler
def _tree_namespace_handler(k, v):
@ -309,9 +286,11 @@ def _tree_namespace_handler(k, v):
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 "/"))
msg = 'Mounted: %s on %s' % (app, script_name or '/')
cherrypy.engine.log(msg)
else:
cherrypy.tree.graft(v, v.script_name)
cherrypy.engine.log("Mounted: %s on %s" % (v, v.script_name or "/"))
Config.namespaces["tree"] = _tree_namespace_handler
cherrypy.engine.log('Mounted: %s on %s' % (v, v.script_name or '/'))
Config.namespaces['tree'] = _tree_namespace_handler