Merge pull request #3918 from pgjones/defaultdict

This commit is contained in:
David Lord 2021-03-08 10:15:26 -08:00 committed by GitHub
commit 6d9d79c70d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 27 deletions

View file

@ -430,13 +430,13 @@ class Flask(Scaffold):
#: .. versionadded:: 0.11
self.shell_context_processors = []
#: all the attached blueprints in a dictionary by name. Blueprints
#: can be attached multiple times so this dictionary does not tell
#: you how often they got attached.
#: Maps registered blueprint names to blueprint objects. The
#: dict retains the order the blueprints were registered in.
#: Blueprints can be registered multiple times, this dict does
#: not track how often they were attached.
#:
#: .. versionadded:: 0.7
self.blueprints = {}
self._blueprint_order = []
#: a place where extensions can store application specific state. For
#: example this is where an extension could store database engines and
@ -997,7 +997,6 @@ class Flask(Scaffold):
)
else:
self.blueprints[blueprint.name] = blueprint
self._blueprint_order.append(blueprint)
first_registration = True
blueprint.register(self, options, first_registration)
@ -1007,7 +1006,7 @@ class Flask(Scaffold):
.. versionadded:: 0.11
"""
return iter(self._blueprint_order)
return self.blueprints.values()
@setupmethod
def add_url_rule(
@ -1292,7 +1291,7 @@ class Flask(Scaffold):
(request.blueprint, None),
(None, None),
):
handler_map = self.error_handler_spec.setdefault(name, {}).get(c)
handler_map = self.error_handler_spec[name][c]
if not handler_map:
continue
@ -1753,10 +1752,10 @@ class Flask(Scaffold):
.. versionadded:: 0.7
"""
funcs = self.url_default_functions.get(None, ())
funcs = self.url_default_functions[None]
if "." in endpoint:
bp = endpoint.rsplit(".", 1)[0]
funcs = chain(funcs, self.url_default_functions.get(bp, ()))
funcs = chain(funcs, self.url_default_functions[bp])
for func in funcs:
func(endpoint, values)
@ -1794,13 +1793,13 @@ class Flask(Scaffold):
bp = _request_ctx_stack.top.request.blueprint
funcs = self.url_value_preprocessors.get(None, ())
funcs = self.url_value_preprocessors[None]
if bp is not None and bp in self.url_value_preprocessors:
funcs = chain(funcs, self.url_value_preprocessors[bp])
for func in funcs:
func(request.endpoint, request.view_args)
funcs = self.before_request_funcs.get(None, ())
funcs = self.before_request_funcs[None]
if bp is not None and bp in self.before_request_funcs:
funcs = chain(funcs, self.before_request_funcs[bp])
for func in funcs:
@ -1857,7 +1856,7 @@ class Flask(Scaffold):
"""
if exc is _sentinel:
exc = sys.exc_info()[1]
funcs = reversed(self.teardown_request_funcs.get(None, ()))
funcs = reversed(self.teardown_request_funcs[None])
bp = _request_ctx_stack.top.request.blueprint
if bp is not None and bp in self.teardown_request_funcs:
funcs = chain(funcs, reversed(self.teardown_request_funcs[bp]))

View file

@ -251,7 +251,7 @@ class Blueprint(Scaffold):
"""
for key, values in self_dict.items():
key = self.name if key is None else f"{self.name}.{key}"
app_dict.setdefault(key, []).extend(values)
app_dict[key].extend(values)
def merge_dict_nested(self_dict, app_dict):
"""Merges self_dict into app_dict. Replaces None keys with self.name.

View file

@ -1,3 +1,4 @@
from collections import defaultdict
from functools import update_wrapper
from werkzeug.exceptions import default_exceptions
@ -86,21 +87,21 @@ class Scaffold(_PackageBoundObject):
#:
#: To register an error handler, use the :meth:`errorhandler`
#: decorator.
self.error_handler_spec = {}
self.error_handler_spec = defaultdict(lambda: defaultdict(dict))
#: A dictionary with lists of functions that will be called at the
#: beginning of each request. The key of the dictionary is the name of
#: the blueprint this function is active for, or ``None`` for all
#: requests. To register a function, use the :meth:`before_request`
#: decorator.
self.before_request_funcs = {}
self.before_request_funcs = defaultdict(list)
#: A dictionary with lists of functions that should be called after
#: each request. The key of the dictionary is the name of the blueprint
#: this function is active for, ``None`` for all requests. This can for
#: example be used to close database connections. To register a function
#: here, use the :meth:`after_request` decorator.
self.after_request_funcs = {}
self.after_request_funcs = defaultdict(list)
#: A dictionary with lists of functions that are called after
#: each request, even if an exception has occurred. The key of the
@ -112,7 +113,7 @@ class Scaffold(_PackageBoundObject):
#: :meth:`teardown_request` decorator.
#:
#: .. versionadded:: 0.7
self.teardown_request_funcs = {}
self.teardown_request_funcs = defaultdict(list)
#: A dictionary with list of functions that are called without argument
#: to populate the template context. The key of the dictionary is the
@ -120,7 +121,9 @@ class Scaffold(_PackageBoundObject):
#: requests. Each returns a dictionary that the template context is
#: updated with. To register a function here, use the
#: :meth:`context_processor` decorator.
self.template_context_processors = {None: [_default_template_ctx_processor]}
self.template_context_processors = defaultdict(
list, {None: [_default_template_ctx_processor]}
)
#: A dictionary with lists of functions that are called before the
#: :attr:`before_request_funcs` functions. The key of the dictionary is
@ -129,7 +132,7 @@ class Scaffold(_PackageBoundObject):
#: :meth:`url_value_preprocessor`.
#:
#: .. versionadded:: 0.7
self.url_value_preprocessors = {}
self.url_value_preprocessors = defaultdict(list)
#: A dictionary with lists of functions that can be used as URL value
#: preprocessors. The key ``None`` here is used for application wide
@ -141,7 +144,7 @@ class Scaffold(_PackageBoundObject):
#: automatically again that were removed that way.
#:
#: .. versionadded:: 0.7
self.url_default_functions = {}
self.url_default_functions = defaultdict(list)
def _is_setup_finished(self):
raise NotImplementedError
@ -258,7 +261,7 @@ class Scaffold(_PackageBoundObject):
non-None value, the value is handled as if it was the return value from
the view, and further request handling is stopped.
"""
self.before_request_funcs.setdefault(None, []).append(f)
self.before_request_funcs[None].append(f)
return f
@setupmethod
@ -272,7 +275,7 @@ class Scaffold(_PackageBoundObject):
As of Flask 0.7 this function might not be executed at the end of the
request in case an unhandled exception occurred.
"""
self.after_request_funcs.setdefault(None, []).append(f)
self.after_request_funcs[None].append(f)
return f
@setupmethod
@ -311,7 +314,7 @@ class Scaffold(_PackageBoundObject):
debugger can still access it. This behavior can be controlled
by the ``PRESERVE_CONTEXT_ON_EXCEPTION`` configuration variable.
"""
self.teardown_request_funcs.setdefault(None, []).append(f)
self.teardown_request_funcs[None].append(f)
return f
@setupmethod
@ -334,7 +337,7 @@ class Scaffold(_PackageBoundObject):
The function is passed the endpoint name and values dict. The return
value is ignored.
"""
self.url_value_preprocessors.setdefault(None, []).append(f)
self.url_value_preprocessors[None].append(f)
return f
@setupmethod
@ -343,7 +346,7 @@ class Scaffold(_PackageBoundObject):
application. It's called with the endpoint and values and should
update the values passed in place.
"""
self.url_default_functions.setdefault(None, []).append(f)
self.url_default_functions[None].append(f)
return f
@setupmethod
@ -416,8 +419,7 @@ class Scaffold(_PackageBoundObject):
" instead."
)
handlers = self.error_handler_spec.setdefault(key, {}).setdefault(code, {})
handlers[exc_class] = f
self.error_handler_spec[key][code][exc_class] = f
@staticmethod
def _get_exc_class_and_code(exc_class_or_code):