From 72c85e80c8ef9e6d5b5644f7bb23cdc175ca3873 Mon Sep 17 00:00:00 2001 From: pgjones Date: Sat, 15 Jul 2023 17:28:04 +0100 Subject: [PATCH] Provide an extendable merge blueprint funcs method This allows a Blueprint implementation that has additional funcs, such as Quart with its before_websocket_funcs (as example), to extend the merge method to also merge these functions. --- src/flask/sansio/blueprints.py | 62 +++++++++++++++++----------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/src/flask/sansio/blueprints.py b/src/flask/sansio/blueprints.py index ecc862ba..38c92f45 100644 --- a/src/flask/sansio/blueprints.py +++ b/src/flask/sansio/blueprints.py @@ -329,37 +329,7 @@ class Blueprint(Scaffold): # Merge blueprint data into parent. if first_bp_registration or first_name_registration: - - def extend(bp_dict, parent_dict): - for key, values in bp_dict.items(): - key = name if key is None else f"{name}.{key}" - parent_dict[key].extend(values) - - for key, value in self.error_handler_spec.items(): - key = name if key is None else f"{name}.{key}" - value = defaultdict( - dict, - { - code: { - exc_class: func for exc_class, func in code_values.items() - } - for code, code_values in value.items() - }, - ) - app.error_handler_spec[key] = value - - for endpoint, func in self.view_functions.items(): - app.view_functions[endpoint] = func - - extend(self.before_request_funcs, app.before_request_funcs) - extend(self.after_request_funcs, app.after_request_funcs) - extend( - self.teardown_request_funcs, - app.teardown_request_funcs, - ) - extend(self.url_default_functions, app.url_default_functions) - extend(self.url_value_preprocessors, app.url_value_preprocessors) - extend(self.template_context_processors, app.template_context_processors) + self._merge_blueprint_funcs(app, name) for deferred in self.deferred_functions: deferred(state) @@ -406,6 +376,36 @@ class Blueprint(Scaffold): bp_options["name_prefix"] = name blueprint.register(app, bp_options) + def _merge_blueprint_funcs(self, app: App, name: str) -> None: + def extend(bp_dict, parent_dict): + for key, values in bp_dict.items(): + key = name if key is None else f"{name}.{key}" + parent_dict[key].extend(values) + + for key, value in self.error_handler_spec.items(): + key = name if key is None else f"{name}.{key}" + value = defaultdict( + dict, + { + code: {exc_class: func for exc_class, func in code_values.items()} + for code, code_values in value.items() + }, + ) + app.error_handler_spec[key] = value + + for endpoint, func in self.view_functions.items(): + app.view_functions[endpoint] = func + + extend(self.before_request_funcs, app.before_request_funcs) + extend(self.after_request_funcs, app.after_request_funcs) + extend( + self.teardown_request_funcs, + app.teardown_request_funcs, + ) + extend(self.url_default_functions, app.url_default_functions) + extend(self.url_value_preprocessors, app.url_value_preprocessors) + extend(self.template_context_processors, app.template_context_processors) + @setupmethod def add_url_rule( self,