Method: flask.blueprints.Blueprint.register
Calls: 91, Exceptions: 6, Paths: 16Back
Path 1: 55 calls (0.6)
Flask (55)
{} (24) {'url_prefix': '/py'} (19) {'url_prefix': '/parent/child', 'name_prefix': 'parent'} (4) dict (2) {'url_prefix': '/bp'} (1) {'name_prefix': 'pa...
GeneratorExit (2)
1def register(self, app: Flask, options: dict) -> None:
2 """Called by :meth:`Flask.register_blueprint` to register all
3 views and callbacks registered on the blueprint with the
4 application. Creates a :class:`.BlueprintSetupState` and calls
5 each :meth:`record` callback with it.
6
7 :param app: The application this blueprint is being registered
8 with.
9 :param options: Keyword arguments forwarded from
10 :meth:`~Flask.register_blueprint`.
11
12 .. versionchanged:: 2.3
13 Nested blueprints now correctly apply subdomains.
14
15 .. versionchanged:: 2.1
16 Registering the same blueprint with the same name multiple
17 times is an error.
18
19 .. versionchanged:: 2.0.1
20 Nested blueprints are registered with their dotted name.
21 This allows different blueprints with the same name to be
22 nested at different locations.
23
24 .. versionchanged:: 2.0.1
25 The ``name`` option can be used to change the (pre-dotted)
26 name the blueprint is registered with. This allows the same
27 blueprint to be registered multiple times with unique names
28 for ``url_for``.
29 """
30 name_prefix = options.get("name_prefix", "")
31 self_name = options.get("name", self.name)
32 name = f"{name_prefix}.{self_name}".lstrip(".")
33
34 if name in app.blueprints:
35 bp_desc = "this" if app.blueprints[name] is self else "a different"
36 existing_at = f" '{name}'" if self_name != name else ""
37
38 raise ValueError(
39 f"The name '{self_name}' is already registered for"
40 f" {bp_desc} blueprint{existing_at}. Use 'name=' to"
41 f" provide a unique name."
42 )
43
44 first_bp_registration = not any(bp is self for bp in app.blueprints.values())
45 first_name_registration = name not in app.blueprints
46
47 app.blueprints[name] = self
48 self._got_registered_once = True
49 state = self.make_setup_state(app, options, first_bp_registration)
50
51 if self.has_static_folder:
52 state.add_url_rule(
53 f"{self.static_url_path}/<path:filename>",
54 view_func=self.send_static_file,
55 endpoint="static",
56 )
57
58 # Merge blueprint data into parent.
59 if first_bp_registration or first_name_registration:
60
61 def extend(bp_dict, parent_dict):
62 for key, values in bp_dict.items():
63 key = name if key is None else f"{name}.{key}"
64 parent_dict[key].extend(values)
65
66 for key, value in self.error_handler_spec.items():
67 key = name if key is None else f"{name}.{key}"
68 value = defaultdict(
69 dict,
70 {
71 code: {
72 exc_class: func for exc_class, func in code_values.items()
73 }
74 for code, code_values in value.items()
75 },
76 )
77 app.error_handler_spec[key] = value
78
79 for endpoint, func in self.view_functions.items():
80 app.view_functions[endpoint] = func
81
82 extend(self.before_request_funcs, app.before_request_funcs)
83 extend(self.after_request_funcs, app.after_request_funcs)
84 extend(
85 self.teardown_request_funcs,
86 app.teardown_request_funcs,
87 )
88 extend(self.url_default_functions, app.url_default_functions)
89 extend(self.url_value_preprocessors, app.url_value_preprocessors)
90 extend(self.template_context_processors, app.template_context_processors)
91
92 for deferred in self.deferred_functions:
93 deferred(state)
94
95 cli_resolved_group = options.get("cli_group", self.cli_group)
96
97 if self.cli.commands:
98 if cli_resolved_group is None:
99 app.cli.commands.update(self.cli.commands)
100 elif cli_resolved_group is _sentinel:
101 self.cli.name = name
102 app.cli.add_command(self.cli)
103 else:
104 self.cli.name = cli_resolved_group
105 app.cli.add_command(self.cli)
106
107 for blueprint, bp_options in self._blueprints:
108 bp_options = bp_options.copy()
109 bp_url_prefix = bp_options.get("url_prefix")
110 bp_subdomain = bp_options.get("subdomain")
111
112 if bp_subdomain is None:
113 bp_subdomain = blueprint.subdomain
114
115 if state.subdomain is not None and bp_subdomain is not None:
116 bp_options["subdomain"] = bp_subdomain + "." + state.subdomain
117 elif bp_subdomain is not None:
118 bp_options["subdomain"] = bp_subdomain
119 elif state.subdomain is not None:
120 bp_options["subdomain"] = state.subdomain
121
122 if bp_url_prefix is None:
123 bp_url_prefix = blueprint.url_prefix
124
125 if state.url_prefix is not None and bp_url_prefix is not None:
126 bp_options["url_prefix"] = (
127 state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/")
128 )
129 elif bp_url_prefix is not None:
130 bp_options["url_prefix"] = bp_url_prefix
131 elif state.url_prefix is not None:
132 bp_options["url_prefix"] = state.url_prefix
133
134 bp_options["name_prefix"] = name
135 blueprint.register(app, bp_options)
Path 2: 13 calls (0.14)
Flask (13)
{'url_prefix': '/bp'} (9) {} (3) {'url_prefix': '/parent/child/grandchild', 'name_prefix': 'parent.child'} (1)
1def register(self, app: Flask, options: dict) -> None:
2 """Called by :meth:`Flask.register_blueprint` to register all
3 views and callbacks registered on the blueprint with the
4 application. Creates a :class:`.BlueprintSetupState` and calls
5 each :meth:`record` callback with it.
6
7 :param app: The application this blueprint is being registered
8 with.
9 :param options: Keyword arguments forwarded from
10 :meth:`~Flask.register_blueprint`.
11
12 .. versionchanged:: 2.3
13 Nested blueprints now correctly apply subdomains.
14
15 .. versionchanged:: 2.1
16 Registering the same blueprint with the same name multiple
17 times is an error.
18
19 .. versionchanged:: 2.0.1
20 Nested blueprints are registered with their dotted name.
21 This allows different blueprints with the same name to be
22 nested at different locations.
23
24 .. versionchanged:: 2.0.1
25 The ``name`` option can be used to change the (pre-dotted)
26 name the blueprint is registered with. This allows the same
27 blueprint to be registered multiple times with unique names
28 for ``url_for``.
29 """
30 name_prefix = options.get("name_prefix", "")
31 self_name = options.get("name", self.name)
32 name = f"{name_prefix}.{self_name}".lstrip(".")
33
34 if name in app.blueprints:
35 bp_desc = "this" if app.blueprints[name] is self else "a different"
36 existing_at = f" '{name}'" if self_name != name else ""
37
38 raise ValueError(
39 f"The name '{self_name}' is already registered for"
40 f" {bp_desc} blueprint{existing_at}. Use 'name=' to"
41 f" provide a unique name."
42 )
43
44 first_bp_registration = not any(bp is self for bp in app.blueprints.values())
45 first_name_registration = name not in app.blueprints
46
47 app.blueprints[name] = self
48 self._got_registered_once = True
49 state = self.make_setup_state(app, options, first_bp_registration)
50
51 if self.has_static_folder:
52 state.add_url_rule(
53 f"{self.static_url_path}/<path:filename>",
54 view_func=self.send_static_file,
55 endpoint="static",
56 )
57
58 # Merge blueprint data into parent.
59 if first_bp_registration or first_name_registration:
60
61 def extend(bp_dict, parent_dict):
62 for key, values in bp_dict.items():
63 key = name if key is None else f"{name}.{key}"
64 parent_dict[key].extend(values)
65
66 for key, value in self.error_handler_spec.items():
67 key = name if key is None else f"{name}.{key}"
68 value = defaultdict(
69 dict,
70 {
71 code: {
72 exc_class: func for exc_class, func in code_values.items()
73 }
74 for code, code_values in value.items()
75 },
76 )
77 app.error_handler_spec[key] = value
78
79 for endpoint, func in self.view_functions.items():
80 app.view_functions[endpoint] = func
81
82 extend(self.before_request_funcs, app.before_request_funcs)
83 extend(self.after_request_funcs, app.after_request_funcs)
84 extend(
85 self.teardown_request_funcs,
86 app.teardown_request_funcs,
87 )
88 extend(self.url_default_functions, app.url_default_functions)
89 extend(self.url_value_preprocessors, app.url_value_preprocessors)
90 extend(self.template_context_processors, app.template_context_processors)
91
92 for deferred in self.deferred_functions:
93 deferred(state)
94
95 cli_resolved_group = options.get("cli_group", self.cli_group)
96
97 if self.cli.commands:
98 if cli_resolved_group is None:
99 app.cli.commands.update(self.cli.commands)
100 elif cli_resolved_group is _sentinel:
101 self.cli.name = name
102 app.cli.add_command(self.cli)
103 else:
104 self.cli.name = cli_resolved_group
105 app.cli.add_command(self.cli)
106
107 for blueprint, bp_options in self._blueprints:
108 bp_options = bp_options.copy()
109 bp_url_prefix = bp_options.get("url_prefix")
110 bp_subdomain = bp_options.get("subdomain")
111
112 if bp_subdomain is None:
113 bp_subdomain = blueprint.subdomain
114
115 if state.subdomain is not None and bp_subdomain is not None:
116 bp_options["subdomain"] = bp_subdomain + "." + state.subdomain
117 elif bp_subdomain is not None:
118 bp_options["subdomain"] = bp_subdomain
119 elif state.subdomain is not None:
120 bp_options["subdomain"] = state.subdomain
121
122 if bp_url_prefix is None:
123 bp_url_prefix = blueprint.url_prefix
124
125 if state.url_prefix is not None and bp_url_prefix is not None:
126 bp_options["url_prefix"] = (
127 state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/")
128 )
129 elif bp_url_prefix is not None:
130 bp_options["url_prefix"] = bp_url_prefix
131 elif state.url_prefix is not None:
132 bp_options["url_prefix"] = state.url_prefix
133
134 bp_options["name_prefix"] = name
135 blueprint.register(app, bp_options)
Path 3: 4 calls (0.04)
Flask (4)
{} (2) {'name': 'again'} (1) {'name': 'alt'} (1)
GeneratorExit (1)
1def register(self, app: Flask, options: dict) -> None:
2 """Called by :meth:`Flask.register_blueprint` to register all
3 views and callbacks registered on the blueprint with the
4 application. Creates a :class:`.BlueprintSetupState` and calls
5 each :meth:`record` callback with it.
6
7 :param app: The application this blueprint is being registered
8 with.
9 :param options: Keyword arguments forwarded from
10 :meth:`~Flask.register_blueprint`.
11
12 .. versionchanged:: 2.3
13 Nested blueprints now correctly apply subdomains.
14
15 .. versionchanged:: 2.1
16 Registering the same blueprint with the same name multiple
17 times is an error.
18
19 .. versionchanged:: 2.0.1
20 Nested blueprints are registered with their dotted name.
21 This allows different blueprints with the same name to be
22 nested at different locations.
23
24 .. versionchanged:: 2.0.1
25 The ``name`` option can be used to change the (pre-dotted)
26 name the blueprint is registered with. This allows the same
27 blueprint to be registered multiple times with unique names
28 for ``url_for``.
29 """
30 name_prefix = options.get("name_prefix", "")
31 self_name = options.get("name", self.name)
32 name = f"{name_prefix}.{self_name}".lstrip(".")
33
34 if name in app.blueprints:
35 bp_desc = "this" if app.blueprints[name] is self else "a different"
36 existing_at = f" '{name}'" if self_name != name else ""
37
38 raise ValueError(
39 f"The name '{self_name}' is already registered for"
40 f" {bp_desc} blueprint{existing_at}. Use 'name=' to"
41 f" provide a unique name."
42 )
43
44 first_bp_registration = not any(bp is self for bp in app.blueprints.values())
45 first_name_registration = name not in app.blueprints
46
47 app.blueprints[name] = self
48 self._got_registered_once = True
49 state = self.make_setup_state(app, options, first_bp_registration)
50
51 if self.has_static_folder:
52 state.add_url_rule(
53 f"{self.static_url_path}/<path:filename>",
54 view_func=self.send_static_file,
55 endpoint="static",
56 )
57
58 # Merge blueprint data into parent.
59 if first_bp_registration or first_name_registration:
60
61 def extend(bp_dict, parent_dict):
62 for key, values in bp_dict.items():
63 key = name if key is None else f"{name}.{key}"
64 parent_dict[key].extend(values)
65
66 for key, value in self.error_handler_spec.items():
67 key = name if key is None else f"{name}.{key}"
68 value = defaultdict(
69 dict,
70 {
71 code: {
72 exc_class: func for exc_class, func in code_values.items()
73 }
74 for code, code_values in value.items()
75 },
76 )
77 app.error_handler_spec[key] = value
78
79 for endpoint, func in self.view_functions.items():
80 app.view_functions[endpoint] = func
81
82 extend(self.before_request_funcs, app.before_request_funcs)
83 extend(self.after_request_funcs, app.after_request_funcs)
84 extend(
85 self.teardown_request_funcs,
86 app.teardown_request_funcs,
87 )
88 extend(self.url_default_functions, app.url_default_functions)
89 extend(self.url_value_preprocessors, app.url_value_preprocessors)
90 extend(self.template_context_processors, app.template_context_processors)
91
92 for deferred in self.deferred_functions:
93 deferred(state)
94
95 cli_resolved_group = options.get("cli_group", self.cli_group)
96
97 if self.cli.commands:
98 if cli_resolved_group is None:
99 app.cli.commands.update(self.cli.commands)
100 elif cli_resolved_group is _sentinel:
101 self.cli.name = name
102 app.cli.add_command(self.cli)
103 else:
104 self.cli.name = cli_resolved_group
105 app.cli.add_command(self.cli)
106
107 for blueprint, bp_options in self._blueprints:
108 bp_options = bp_options.copy()
109 bp_url_prefix = bp_options.get("url_prefix")
110 bp_subdomain = bp_options.get("subdomain")
111
112 if bp_subdomain is None:
113 bp_subdomain = blueprint.subdomain
114
115 if state.subdomain is not None and bp_subdomain is not None:
116 bp_options["subdomain"] = bp_subdomain + "." + state.subdomain
117 elif bp_subdomain is not None:
118 bp_options["subdomain"] = bp_subdomain
119 elif state.subdomain is not None:
120 bp_options["subdomain"] = state.subdomain
121
122 if bp_url_prefix is None:
123 bp_url_prefix = blueprint.url_prefix
124
125 if state.url_prefix is not None and bp_url_prefix is not None:
126 bp_options["url_prefix"] = (
127 state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/")
128 )
129 elif bp_url_prefix is not None:
130 bp_options["url_prefix"] = bp_url_prefix
131 elif state.url_prefix is not None:
132 bp_options["url_prefix"] = state.url_prefix
133
134 bp_options["name_prefix"] = name
135 blueprint.register(app, bp_options)
Path 4: 3 calls (0.03)
Flask (3)
{'url_prefix': '/parent'} (1) {'url_prefix': '/a'} (1) {'url_prefix': '/b', 'name': 'alt'} (1)
GeneratorExit (1)
1def register(self, app: Flask, options: dict) -> None:
2 """Called by :meth:`Flask.register_blueprint` to register all
3 views and callbacks registered on the blueprint with the
4 application. Creates a :class:`.BlueprintSetupState` and calls
5 each :meth:`record` callback with it.
6
7 :param app: The application this blueprint is being registered
8 with.
9 :param options: Keyword arguments forwarded from
10 :meth:`~Flask.register_blueprint`.
11
12 .. versionchanged:: 2.3
13 Nested blueprints now correctly apply subdomains.
14
15 .. versionchanged:: 2.1
16 Registering the same blueprint with the same name multiple
17 times is an error.
18
19 .. versionchanged:: 2.0.1
20 Nested blueprints are registered with their dotted name.
21 This allows different blueprints with the same name to be
22 nested at different locations.
23
24 .. versionchanged:: 2.0.1
25 The ``name`` option can be used to change the (pre-dotted)
26 name the blueprint is registered with. This allows the same
27 blueprint to be registered multiple times with unique names
28 for ``url_for``.
29 """
30 name_prefix = options.get("name_prefix", "")
31 self_name = options.get("name", self.name)
32 name = f"{name_prefix}.{self_name}".lstrip(".")
33
34 if name in app.blueprints:
35 bp_desc = "this" if app.blueprints[name] is self else "a different"
36 existing_at = f" '{name}'" if self_name != name else ""
37
38 raise ValueError(
39 f"The name '{self_name}' is already registered for"
40 f" {bp_desc} blueprint{existing_at}. Use 'name=' to"
41 f" provide a unique name."
42 )
43
44 first_bp_registration = not any(bp is self for bp in app.blueprints.values())
45 first_name_registration = name not in app.blueprints
46
47 app.blueprints[name] = self
48 self._got_registered_once = True
49 state = self.make_setup_state(app, options, first_bp_registration)
50
51 if self.has_static_folder:
52 state.add_url_rule(
53 f"{self.static_url_path}/<path:filename>",
54 view_func=self.send_static_file,
55 endpoint="static",
56 )
57
58 # Merge blueprint data into parent.
59 if first_bp_registration or first_name_registration:
60
61 def extend(bp_dict, parent_dict):
62 for key, values in bp_dict.items():
63 key = name if key is None else f"{name}.{key}"
64 parent_dict[key].extend(values)
65
66 for key, value in self.error_handler_spec.items():
67 key = name if key is None else f"{name}.{key}"
68 value = defaultdict(
69 dict,
70 {
71 code: {
72 exc_class: func for exc_class, func in code_values.items()
73 }
74 for code, code_values in value.items()
75 },
76 )
77 app.error_handler_spec[key] = value
78
79 for endpoint, func in self.view_functions.items():
80 app.view_functions[endpoint] = func
81
82 extend(self.before_request_funcs, app.before_request_funcs)
83 extend(self.after_request_funcs, app.after_request_funcs)
84 extend(
85 self.teardown_request_funcs,
86 app.teardown_request_funcs,
87 )
88 extend(self.url_default_functions, app.url_default_functions)
89 extend(self.url_value_preprocessors, app.url_value_preprocessors)
90 extend(self.template_context_processors, app.template_context_processors)
91
92 for deferred in self.deferred_functions:
93 deferred(state)
94
95 cli_resolved_group = options.get("cli_group", self.cli_group)
96
97 if self.cli.commands:
98 if cli_resolved_group is None:
99 app.cli.commands.update(self.cli.commands)
100 elif cli_resolved_group is _sentinel:
101 self.cli.name = name
102 app.cli.add_command(self.cli)
103 else:
104 self.cli.name = cli_resolved_group
105 app.cli.add_command(self.cli)
106
107 for blueprint, bp_options in self._blueprints:
108 bp_options = bp_options.copy()
109 bp_url_prefix = bp_options.get("url_prefix")
110 bp_subdomain = bp_options.get("subdomain")
111
112 if bp_subdomain is None:
113 bp_subdomain = blueprint.subdomain
114
115 if state.subdomain is not None and bp_subdomain is not None:
116 bp_options["subdomain"] = bp_subdomain + "." + state.subdomain
117 elif bp_subdomain is not None:
118 bp_options["subdomain"] = bp_subdomain
119 elif state.subdomain is not None:
120 bp_options["subdomain"] = state.subdomain
121
122 if bp_url_prefix is None:
123 bp_url_prefix = blueprint.url_prefix
124
125 if state.url_prefix is not None and bp_url_prefix is not None:
126 bp_options["url_prefix"] = (
127 state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/")
128 )
129 elif bp_url_prefix is not None:
130 bp_options["url_prefix"] = bp_url_prefix
131 elif state.url_prefix is not None:
132 bp_options["url_prefix"] = state.url_prefix
133
134 bp_options["name_prefix"] = name
135 blueprint.register(app, bp_options)
Path 5: 3 calls (0.03)
Flask (3)
{'url_prefix': '/parent'} (2) {'url_prefix': None} (1)
1def register(self, app: Flask, options: dict) -> None:
2 """Called by :meth:`Flask.register_blueprint` to register all
3 views and callbacks registered on the blueprint with the
4 application. Creates a :class:`.BlueprintSetupState` and calls
5 each :meth:`record` callback with it.
6
7 :param app: The application this blueprint is being registered
8 with.
9 :param options: Keyword arguments forwarded from
10 :meth:`~Flask.register_blueprint`.
11
12 .. versionchanged:: 2.3
13 Nested blueprints now correctly apply subdomains.
14
15 .. versionchanged:: 2.1
16 Registering the same blueprint with the same name multiple
17 times is an error.
18
19 .. versionchanged:: 2.0.1
20 Nested blueprints are registered with their dotted name.
21 This allows different blueprints with the same name to be
22 nested at different locations.
23
24 .. versionchanged:: 2.0.1
25 The ``name`` option can be used to change the (pre-dotted)
26 name the blueprint is registered with. This allows the same
27 blueprint to be registered multiple times with unique names
28 for ``url_for``.
29 """
30 name_prefix = options.get("name_prefix", "")
31 self_name = options.get("name", self.name)
32 name = f"{name_prefix}.{self_name}".lstrip(".")
33
34 if name in app.blueprints:
35 bp_desc = "this" if app.blueprints[name] is self else "a different"
36 existing_at = f" '{name}'" if self_name != name else ""
37
38 raise ValueError(
39 f"The name '{self_name}' is already registered for"
40 f" {bp_desc} blueprint{existing_at}. Use 'name=' to"
41 f" provide a unique name."
42 )
43
44 first_bp_registration = not any(bp is self for bp in app.blueprints.values())
45 first_name_registration = name not in app.blueprints
46
47 app.blueprints[name] = self
48 self._got_registered_once = True
49 state = self.make_setup_state(app, options, first_bp_registration)
50
51 if self.has_static_folder:
52 state.add_url_rule(
53 f"{self.static_url_path}/<path:filename>",
54 view_func=self.send_static_file,
55 endpoint="static",
56 )
57
58 # Merge blueprint data into parent.
59 if first_bp_registration or first_name_registration:
60
61 def extend(bp_dict, parent_dict):
62 for key, values in bp_dict.items():
63 key = name if key is None else f"{name}.{key}"
64 parent_dict[key].extend(values)
65
66 for key, value in self.error_handler_spec.items():
67 key = name if key is None else f"{name}.{key}"
68 value = defaultdict(
69 dict,
70 {
71 code: {
72 exc_class: func for exc_class, func in code_values.items()
73 }
74 for code, code_values in value.items()
75 },
76 )
77 app.error_handler_spec[key] = value
78
79 for endpoint, func in self.view_functions.items():
80 app.view_functions[endpoint] = func
81
82 extend(self.before_request_funcs, app.before_request_funcs)
83 extend(self.after_request_funcs, app.after_request_funcs)
84 extend(
85 self.teardown_request_funcs,
86 app.teardown_request_funcs,
87 )
88 extend(self.url_default_functions, app.url_default_functions)
89 extend(self.url_value_preprocessors, app.url_value_preprocessors)
90 extend(self.template_context_processors, app.template_context_processors)
91
92 for deferred in self.deferred_functions:
93 deferred(state)
94
95 cli_resolved_group = options.get("cli_group", self.cli_group)
96
97 if self.cli.commands:
98 if cli_resolved_group is None:
99 app.cli.commands.update(self.cli.commands)
100 elif cli_resolved_group is _sentinel:
101 self.cli.name = name
102 app.cli.add_command(self.cli)
103 else:
104 self.cli.name = cli_resolved_group
105 app.cli.add_command(self.cli)
106
107 for blueprint, bp_options in self._blueprints:
108 bp_options = bp_options.copy()
109 bp_url_prefix = bp_options.get("url_prefix")
110 bp_subdomain = bp_options.get("subdomain")
111
112 if bp_subdomain is None:
113 bp_subdomain = blueprint.subdomain
114
115 if state.subdomain is not None and bp_subdomain is not None:
116 bp_options["subdomain"] = bp_subdomain + "." + state.subdomain
117 elif bp_subdomain is not None:
118 bp_options["subdomain"] = bp_subdomain
119 elif state.subdomain is not None:
120 bp_options["subdomain"] = state.subdomain
121
122 if bp_url_prefix is None:
123 bp_url_prefix = blueprint.url_prefix
124
125 if state.url_prefix is not None and bp_url_prefix is not None:
126 bp_options["url_prefix"] = (
127 state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/")
128 )
129 elif bp_url_prefix is not None:
130 bp_options["url_prefix"] = bp_url_prefix
131 elif state.url_prefix is not None:
132 bp_options["url_prefix"] = state.url_prefix
133
134 bp_options["name_prefix"] = name
135 blueprint.register(app, bp_options)
Path 6: 2 calls (0.02)
Flask (2)
{} (2)
ValueError (2)
1def register(self, app: Flask, options: dict) -> None:
2 """Called by :meth:`Flask.register_blueprint` to register all
3 views and callbacks registered on the blueprint with the
4 application. Creates a :class:`.BlueprintSetupState` and calls
5 each :meth:`record` callback with it.
6
7 :param app: The application this blueprint is being registered
8 with.
9 :param options: Keyword arguments forwarded from
10 :meth:`~Flask.register_blueprint`.
11
12 .. versionchanged:: 2.3
13 Nested blueprints now correctly apply subdomains.
14
15 .. versionchanged:: 2.1
16 Registering the same blueprint with the same name multiple
17 times is an error.
18
19 .. versionchanged:: 2.0.1
20 Nested blueprints are registered with their dotted name.
21 This allows different blueprints with the same name to be
22 nested at different locations.
23
24 .. versionchanged:: 2.0.1
25 The ``name`` option can be used to change the (pre-dotted)
26 name the blueprint is registered with. This allows the same
27 blueprint to be registered multiple times with unique names
28 for ``url_for``.
29 """
30 name_prefix = options.get("name_prefix", "")
31 self_name = options.get("name", self.name)
32 name = f"{name_prefix}.{self_name}".lstrip(".")
33
34 if name in app.blueprints:
35 bp_desc = "this" if app.blueprints[name] is self else "a different"
36 existing_at = f" '{name}'" if self_name != name else ""
37
38 raise ValueError(
39 f"The name '{self_name}' is already registered for"
40 f" {bp_desc} blueprint{existing_at}. Use 'name=' to"
41 f" provide a unique name."
42 )
43
44 first_bp_registration = not any(bp is self for bp in app.blueprints.values())
45 first_name_registration = name not in app.blueprints
46
47 app.blueprints[name] = self
48 self._got_registered_once = True
49 state = self.make_setup_state(app, options, first_bp_registration)
50
51 if self.has_static_folder:
52 state.add_url_rule(
53 f"{self.static_url_path}/<path:filename>",
54 view_func=self.send_static_file,
55 endpoint="static",
56 )
57
58 # Merge blueprint data into parent.
59 if first_bp_registration or first_name_registration:
60
61 def extend(bp_dict, parent_dict):
62 for key, values in bp_dict.items():
63 key = name if key is None else f"{name}.{key}"
64 parent_dict[key].extend(values)
65
66 for key, value in self.error_handler_spec.items():
67 key = name if key is None else f"{name}.{key}"
68 value = defaultdict(
69 dict,
70 {
71 code: {
72 exc_class: func for exc_class, func in code_values.items()
73 }
74 for code, code_values in value.items()
75 },
76 )
77 app.error_handler_spec[key] = value
78
79 for endpoint, func in self.view_functions.items():
80 app.view_functions[endpoint] = func
81
82 extend(self.before_request_funcs, app.before_request_funcs)
83 extend(self.after_request_funcs, app.after_request_funcs)
84 extend(
85 self.teardown_request_funcs,
86 app.teardown_request_funcs,
87 )
88 extend(self.url_default_functions, app.url_default_functions)
89 extend(self.url_value_preprocessors, app.url_value_preprocessors)
90 extend(self.template_context_processors, app.template_context_processors)
91
92 for deferred in self.deferred_functions:
93 deferred(state)
94
95 cli_resolved_group = options.get("cli_group", self.cli_group)
96
97 if self.cli.commands:
98 if cli_resolved_group is None:
99 app.cli.commands.update(self.cli.commands)
100 elif cli_resolved_group is _sentinel:
101 self.cli.name = name
102 app.cli.add_command(self.cli)
103 else:
104 self.cli.name = cli_resolved_group
105 app.cli.add_command(self.cli)
106
107 for blueprint, bp_options in self._blueprints:
108 bp_options = bp_options.copy()
109 bp_url_prefix = bp_options.get("url_prefix")
110 bp_subdomain = bp_options.get("subdomain")
111
112 if bp_subdomain is None:
113 bp_subdomain = blueprint.subdomain
114
115 if state.subdomain is not None and bp_subdomain is not None:
116 bp_options["subdomain"] = bp_subdomain + "." + state.subdomain
117 elif bp_subdomain is not None:
118 bp_options["subdomain"] = bp_subdomain
119 elif state.subdomain is not None:
120 bp_options["subdomain"] = state.subdomain
121
122 if bp_url_prefix is None:
123 bp_url_prefix = blueprint.url_prefix
124
125 if state.url_prefix is not None and bp_url_prefix is not None:
126 bp_options["url_prefix"] = (
127 state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/")
128 )
129 elif bp_url_prefix is not None:
130 bp_options["url_prefix"] = bp_url_prefix
131 elif state.url_prefix is not None:
132 bp_options["url_prefix"] = state.url_prefix
133
134 bp_options["name_prefix"] = name
135 blueprint.register(app, bp_options)
Path 7: 2 calls (0.02)
Flask (2)
{} (1) {'cli_group': 'late_registration'} (1)
1def register(self, app: Flask, options: dict) -> None:
2 """Called by :meth:`Flask.register_blueprint` to register all
3 views and callbacks registered on the blueprint with the
4 application. Creates a :class:`.BlueprintSetupState` and calls
5 each :meth:`record` callback with it.
6
7 :param app: The application this blueprint is being registered
8 with.
9 :param options: Keyword arguments forwarded from
10 :meth:`~Flask.register_blueprint`.
11
12 .. versionchanged:: 2.3
13 Nested blueprints now correctly apply subdomains.
14
15 .. versionchanged:: 2.1
16 Registering the same blueprint with the same name multiple
17 times is an error.
18
19 .. versionchanged:: 2.0.1
20 Nested blueprints are registered with their dotted name.
21 This allows different blueprints with the same name to be
22 nested at different locations.
23
24 .. versionchanged:: 2.0.1
25 The ``name`` option can be used to change the (pre-dotted)
26 name the blueprint is registered with. This allows the same
27 blueprint to be registered multiple times with unique names
28 for ``url_for``.
29 """
30 name_prefix = options.get("name_prefix", "")
31 self_name = options.get("name", self.name)
32 name = f"{name_prefix}.{self_name}".lstrip(".")
33
34 if name in app.blueprints:
35 bp_desc = "this" if app.blueprints[name] is self else "a different"
36 existing_at = f" '{name}'" if self_name != name else ""
37
38 raise ValueError(
39 f"The name '{self_name}' is already registered for"
40 f" {bp_desc} blueprint{existing_at}. Use 'name=' to"
41 f" provide a unique name."
42 )
43
44 first_bp_registration = not any(bp is self for bp in app.blueprints.values())
45 first_name_registration = name not in app.blueprints
46
47 app.blueprints[name] = self
48 self._got_registered_once = True
49 state = self.make_setup_state(app, options, first_bp_registration)
50
51 if self.has_static_folder:
52 state.add_url_rule(
53 f"{self.static_url_path}/<path:filename>",
54 view_func=self.send_static_file,
55 endpoint="static",
56 )
57
58 # Merge blueprint data into parent.
59 if first_bp_registration or first_name_registration:
60
61 def extend(bp_dict, parent_dict):
62 for key, values in bp_dict.items():
63 key = name if key is None else f"{name}.{key}"
64 parent_dict[key].extend(values)
65
66 for key, value in self.error_handler_spec.items():
67 key = name if key is None else f"{name}.{key}"
68 value = defaultdict(
69 dict,
70 {
71 code: {
72 exc_class: func for exc_class, func in code_values.items()
73 }
74 for code, code_values in value.items()
75 },
76 )
77 app.error_handler_spec[key] = value
78
79 for endpoint, func in self.view_functions.items():
80 app.view_functions[endpoint] = func
81
82 extend(self.before_request_funcs, app.before_request_funcs)
83 extend(self.after_request_funcs, app.after_request_funcs)
84 extend(
85 self.teardown_request_funcs,
86 app.teardown_request_funcs,
87 )
88 extend(self.url_default_functions, app.url_default_functions)
89 extend(self.url_value_preprocessors, app.url_value_preprocessors)
90 extend(self.template_context_processors, app.template_context_processors)
91
92 for deferred in self.deferred_functions:
93 deferred(state)
94
95 cli_resolved_group = options.get("cli_group", self.cli_group)
96
97 if self.cli.commands:
98 if cli_resolved_group is None:
99 app.cli.commands.update(self.cli.commands)
100 elif cli_resolved_group is _sentinel:
101 self.cli.name = name
102 app.cli.add_command(self.cli)
103 else:
104 self.cli.name = cli_resolved_group
105 app.cli.add_command(self.cli)
106
107 for blueprint, bp_options in self._blueprints:
108 bp_options = bp_options.copy()
109 bp_url_prefix = bp_options.get("url_prefix")
110 bp_subdomain = bp_options.get("subdomain")
111
112 if bp_subdomain is None:
113 bp_subdomain = blueprint.subdomain
114
115 if state.subdomain is not None and bp_subdomain is not None:
116 bp_options["subdomain"] = bp_subdomain + "." + state.subdomain
117 elif bp_subdomain is not None:
118 bp_options["subdomain"] = bp_subdomain
119 elif state.subdomain is not None:
120 bp_options["subdomain"] = state.subdomain
121
122 if bp_url_prefix is None:
123 bp_url_prefix = blueprint.url_prefix
124
125 if state.url_prefix is not None and bp_url_prefix is not None:
126 bp_options["url_prefix"] = (
127 state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/")
128 )
129 elif bp_url_prefix is not None:
130 bp_options["url_prefix"] = bp_url_prefix
131 elif state.url_prefix is not None:
132 bp_options["url_prefix"] = state.url_prefix
133
134 bp_options["name_prefix"] = name
135 blueprint.register(app, bp_options)
Path 8: 1 calls (0.01)
Flask (1)
{} (1)
1def register(self, app: Flask, options: dict) -> None:
2 """Called by :meth:`Flask.register_blueprint` to register all
3 views and callbacks registered on the blueprint with the
4 application. Creates a :class:`.BlueprintSetupState` and calls
5 each :meth:`record` callback with it.
6
7 :param app: The application this blueprint is being registered
8 with.
9 :param options: Keyword arguments forwarded from
10 :meth:`~Flask.register_blueprint`.
11
12 .. versionchanged:: 2.3
13 Nested blueprints now correctly apply subdomains.
14
15 .. versionchanged:: 2.1
16 Registering the same blueprint with the same name multiple
17 times is an error.
18
19 .. versionchanged:: 2.0.1
20 Nested blueprints are registered with their dotted name.
21 This allows different blueprints with the same name to be
22 nested at different locations.
23
24 .. versionchanged:: 2.0.1
25 The ``name`` option can be used to change the (pre-dotted)
26 name the blueprint is registered with. This allows the same
27 blueprint to be registered multiple times with unique names
28 for ``url_for``.
29 """
30 name_prefix = options.get("name_prefix", "")
31 self_name = options.get("name", self.name)
32 name = f"{name_prefix}.{self_name}".lstrip(".")
33
34 if name in app.blueprints:
35 bp_desc = "this" if app.blueprints[name] is self else "a different"
36 existing_at = f" '{name}'" if self_name != name else ""
37
38 raise ValueError(
39 f"The name '{self_name}' is already registered for"
40 f" {bp_desc} blueprint{existing_at}. Use 'name=' to"
41 f" provide a unique name."
42 )
43
44 first_bp_registration = not any(bp is self for bp in app.blueprints.values())
45 first_name_registration = name not in app.blueprints
46
47 app.blueprints[name] = self
48 self._got_registered_once = True
49 state = self.make_setup_state(app, options, first_bp_registration)
50
51 if self.has_static_folder:
52 state.add_url_rule(
53 f"{self.static_url_path}/<path:filename>",
54 view_func=self.send_static_file,
55 endpoint="static",
56 )
57
58 # Merge blueprint data into parent.
59 if first_bp_registration or first_name_registration:
60
61 def extend(bp_dict, parent_dict):
62 for key, values in bp_dict.items():
63 key = name if key is None else f"{name}.{key}"
64 parent_dict[key].extend(values)
65
66 for key, value in self.error_handler_spec.items():
67 key = name if key is None else f"{name}.{key}"
68 value = defaultdict(
69 dict,
70 {
71 code: {
72 exc_class: func for exc_class, func in code_values.items()
73 }
74 for code, code_values in value.items()
75 },
76 )
77 app.error_handler_spec[key] = value
78
79 for endpoint, func in self.view_functions.items():
80 app.view_functions[endpoint] = func
81
82 extend(self.before_request_funcs, app.before_request_funcs)
83 extend(self.after_request_funcs, app.after_request_funcs)
84 extend(
85 self.teardown_request_funcs,
86 app.teardown_request_funcs,
87 )
88 extend(self.url_default_functions, app.url_default_functions)
89 extend(self.url_value_preprocessors, app.url_value_preprocessors)
90 extend(self.template_context_processors, app.template_context_processors)
91
92 for deferred in self.deferred_functions:
93 deferred(state)
94
95 cli_resolved_group = options.get("cli_group", self.cli_group)
96
97 if self.cli.commands:
98 if cli_resolved_group is None:
99 app.cli.commands.update(self.cli.commands)
100 elif cli_resolved_group is _sentinel:
101 self.cli.name = name
102 app.cli.add_command(self.cli)
103 else:
104 self.cli.name = cli_resolved_group
105 app.cli.add_command(self.cli)
106
107 for blueprint, bp_options in self._blueprints:
108 bp_options = bp_options.copy()
109 bp_url_prefix = bp_options.get("url_prefix")
110 bp_subdomain = bp_options.get("subdomain")
111
112 if bp_subdomain is None:
113 bp_subdomain = blueprint.subdomain
114
115 if state.subdomain is not None and bp_subdomain is not None:
116 bp_options["subdomain"] = bp_subdomain + "." + state.subdomain
117 elif bp_subdomain is not None:
118 bp_options["subdomain"] = bp_subdomain
119 elif state.subdomain is not None:
120 bp_options["subdomain"] = state.subdomain
121
122 if bp_url_prefix is None:
123 bp_url_prefix = blueprint.url_prefix
124
125 if state.url_prefix is not None and bp_url_prefix is not None:
126 bp_options["url_prefix"] = (
127 state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/")
128 )
129 elif bp_url_prefix is not None:
130 bp_options["url_prefix"] = bp_url_prefix
131 elif state.url_prefix is not None:
132 bp_options["url_prefix"] = state.url_prefix
133
134 bp_options["name_prefix"] = name
135 blueprint.register(app, bp_options)
Path 9: 1 calls (0.01)
Flask (1)
{'url_prefix': '/bp_prefix'} (1)
1def register(self, app: Flask, options: dict) -> None:
2 """Called by :meth:`Flask.register_blueprint` to register all
3 views and callbacks registered on the blueprint with the
4 application. Creates a :class:`.BlueprintSetupState` and calls
5 each :meth:`record` callback with it.
6
7 :param app: The application this blueprint is being registered
8 with.
9 :param options: Keyword arguments forwarded from
10 :meth:`~Flask.register_blueprint`.
11
12 .. versionchanged:: 2.3
13 Nested blueprints now correctly apply subdomains.
14
15 .. versionchanged:: 2.1
16 Registering the same blueprint with the same name multiple
17 times is an error.
18
19 .. versionchanged:: 2.0.1
20 Nested blueprints are registered with their dotted name.
21 This allows different blueprints with the same name to be
22 nested at different locations.
23
24 .. versionchanged:: 2.0.1
25 The ``name`` option can be used to change the (pre-dotted)
26 name the blueprint is registered with. This allows the same
27 blueprint to be registered multiple times with unique names
28 for ``url_for``.
29 """
30 name_prefix = options.get("name_prefix", "")
31 self_name = options.get("name", self.name)
32 name = f"{name_prefix}.{self_name}".lstrip(".")
33
34 if name in app.blueprints:
35 bp_desc = "this" if app.blueprints[name] is self else "a different"
36 existing_at = f" '{name}'" if self_name != name else ""
37
38 raise ValueError(
39 f"The name '{self_name}' is already registered for"
40 f" {bp_desc} blueprint{existing_at}. Use 'name=' to"
41 f" provide a unique name."
42 )
43
44 first_bp_registration = not any(bp is self for bp in app.blueprints.values())
45 first_name_registration = name not in app.blueprints
46
47 app.blueprints[name] = self
48 self._got_registered_once = True
49 state = self.make_setup_state(app, options, first_bp_registration)
50
51 if self.has_static_folder:
52 state.add_url_rule(
53 f"{self.static_url_path}/<path:filename>",
54 view_func=self.send_static_file,
55 endpoint="static",
56 )
57
58 # Merge blueprint data into parent.
59 if first_bp_registration or first_name_registration:
60
61 def extend(bp_dict, parent_dict):
62 for key, values in bp_dict.items():
63 key = name if key is None else f"{name}.{key}"
64 parent_dict[key].extend(values)
65
66 for key, value in self.error_handler_spec.items():
67 key = name if key is None else f"{name}.{key}"
68 value = defaultdict(
69 dict,
70 {
71 code: {
72 exc_class: func for exc_class, func in code_values.items()
73 }
74 for code, code_values in value.items()
75 },
76 )
77 app.error_handler_spec[key] = value
78
79 for endpoint, func in self.view_functions.items():
80 app.view_functions[endpoint] = func
81
82 extend(self.before_request_funcs, app.before_request_funcs)
83 extend(self.after_request_funcs, app.after_request_funcs)
84 extend(
85 self.teardown_request_funcs,
86 app.teardown_request_funcs,
87 )
88 extend(self.url_default_functions, app.url_default_functions)
89 extend(self.url_value_preprocessors, app.url_value_preprocessors)
90 extend(self.template_context_processors, app.template_context_processors)
91
92 for deferred in self.deferred_functions:
93 deferred(state)
94
95 cli_resolved_group = options.get("cli_group", self.cli_group)
96
97 if self.cli.commands:
98 if cli_resolved_group is None:
99 app.cli.commands.update(self.cli.commands)
100 elif cli_resolved_group is _sentinel:
101 self.cli.name = name
102 app.cli.add_command(self.cli)
103 else:
104 self.cli.name = cli_resolved_group
105 app.cli.add_command(self.cli)
106
107 for blueprint, bp_options in self._blueprints:
108 bp_options = bp_options.copy()
109 bp_url_prefix = bp_options.get("url_prefix")
110 bp_subdomain = bp_options.get("subdomain")
111
112 if bp_subdomain is None:
113 bp_subdomain = blueprint.subdomain
114
115 if state.subdomain is not None and bp_subdomain is not None:
116 bp_options["subdomain"] = bp_subdomain + "." + state.subdomain
117 elif bp_subdomain is not None:
118 bp_options["subdomain"] = bp_subdomain
119 elif state.subdomain is not None:
120 bp_options["subdomain"] = state.subdomain
121
122 if bp_url_prefix is None:
123 bp_url_prefix = blueprint.url_prefix
124
125 if state.url_prefix is not None and bp_url_prefix is not None:
126 bp_options["url_prefix"] = (
127 state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/")
128 )
129 elif bp_url_prefix is not None:
130 bp_options["url_prefix"] = bp_url_prefix
131 elif state.url_prefix is not None:
132 bp_options["url_prefix"] = state.url_prefix
133
134 bp_options["name_prefix"] = name
135 blueprint.register(app, bp_options)
Path 10: 1 calls (0.01)
Flask (1)
{'url_prefix': '/parent/child', 'name_prefix': 'parent'} (1)
1def register(self, app: Flask, options: dict) -> None:
2 """Called by :meth:`Flask.register_blueprint` to register all
3 views and callbacks registered on the blueprint with the
4 application. Creates a :class:`.BlueprintSetupState` and calls
5 each :meth:`record` callback with it.
6
7 :param app: The application this blueprint is being registered
8 with.
9 :param options: Keyword arguments forwarded from
10 :meth:`~Flask.register_blueprint`.
11
12 .. versionchanged:: 2.3
13 Nested blueprints now correctly apply subdomains.
14
15 .. versionchanged:: 2.1
16 Registering the same blueprint with the same name multiple
17 times is an error.
18
19 .. versionchanged:: 2.0.1
20 Nested blueprints are registered with their dotted name.
21 This allows different blueprints with the same name to be
22 nested at different locations.
23
24 .. versionchanged:: 2.0.1
25 The ``name`` option can be used to change the (pre-dotted)
26 name the blueprint is registered with. This allows the same
27 blueprint to be registered multiple times with unique names
28 for ``url_for``.
29 """
30 name_prefix = options.get("name_prefix", "")
31 self_name = options.get("name", self.name)
32 name = f"{name_prefix}.{self_name}".lstrip(".")
33
34 if name in app.blueprints:
35 bp_desc = "this" if app.blueprints[name] is self else "a different"
36 existing_at = f" '{name}'" if self_name != name else ""
37
38 raise ValueError(
39 f"The name '{self_name}' is already registered for"
40 f" {bp_desc} blueprint{existing_at}. Use 'name=' to"
41 f" provide a unique name."
42 )
43
44 first_bp_registration = not any(bp is self for bp in app.blueprints.values())
45 first_name_registration = name not in app.blueprints
46
47 app.blueprints[name] = self
48 self._got_registered_once = True
49 state = self.make_setup_state(app, options, first_bp_registration)
50
51 if self.has_static_folder:
52 state.add_url_rule(
53 f"{self.static_url_path}/<path:filename>",
54 view_func=self.send_static_file,
55 endpoint="static",
56 )
57
58 # Merge blueprint data into parent.
59 if first_bp_registration or first_name_registration:
60
61 def extend(bp_dict, parent_dict):
62 for key, values in bp_dict.items():
63 key = name if key is None else f"{name}.{key}"
64 parent_dict[key].extend(values)
65
66 for key, value in self.error_handler_spec.items():
67 key = name if key is None else f"{name}.{key}"
68 value = defaultdict(
69 dict,
70 {
71 code: {
72 exc_class: func for exc_class, func in code_values.items()
73 }
74 for code, code_values in value.items()
75 },
76 )
77 app.error_handler_spec[key] = value
78
79 for endpoint, func in self.view_functions.items():
80 app.view_functions[endpoint] = func
81
82 extend(self.before_request_funcs, app.before_request_funcs)
83 extend(self.after_request_funcs, app.after_request_funcs)
84 extend(
85 self.teardown_request_funcs,
86 app.teardown_request_funcs,
87 )
88 extend(self.url_default_functions, app.url_default_functions)
89 extend(self.url_value_preprocessors, app.url_value_preprocessors)
90 extend(self.template_context_processors, app.template_context_processors)
91
92 for deferred in self.deferred_functions:
93 deferred(state)
94
95 cli_resolved_group = options.get("cli_group", self.cli_group)
96
97 if self.cli.commands:
98 if cli_resolved_group is None:
99 app.cli.commands.update(self.cli.commands)
100 elif cli_resolved_group is _sentinel:
101 self.cli.name = name
102 app.cli.add_command(self.cli)
103 else:
104 self.cli.name = cli_resolved_group
105 app.cli.add_command(self.cli)
106
107 for blueprint, bp_options in self._blueprints:
108 bp_options = bp_options.copy()
109 bp_url_prefix = bp_options.get("url_prefix")
110 bp_subdomain = bp_options.get("subdomain")
111
112 if bp_subdomain is None:
113 bp_subdomain = blueprint.subdomain
114
115 if state.subdomain is not None and bp_subdomain is not None:
116 bp_options["subdomain"] = bp_subdomain + "." + state.subdomain
117 elif bp_subdomain is not None:
118 bp_options["subdomain"] = bp_subdomain
119 elif state.subdomain is not None:
120 bp_options["subdomain"] = state.subdomain
121
122 if bp_url_prefix is None:
123 bp_url_prefix = blueprint.url_prefix
124
125 if state.url_prefix is not None and bp_url_prefix is not None:
126 bp_options["url_prefix"] = (
127 state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/")
128 )
129 elif bp_url_prefix is not None:
130 bp_options["url_prefix"] = bp_url_prefix
131 elif state.url_prefix is not None:
132 bp_options["url_prefix"] = state.url_prefix
133
134 bp_options["name_prefix"] = name
135 blueprint.register(app, bp_options)
Path 11: 1 calls (0.01)
Flask (1)
{} (1)
1def register(self, app: Flask, options: dict) -> None:
2 """Called by :meth:`Flask.register_blueprint` to register all
3 views and callbacks registered on the blueprint with the
4 application. Creates a :class:`.BlueprintSetupState` and calls
5 each :meth:`record` callback with it.
6
7 :param app: The application this blueprint is being registered
8 with.
9 :param options: Keyword arguments forwarded from
10 :meth:`~Flask.register_blueprint`.
11
12 .. versionchanged:: 2.3
13 Nested blueprints now correctly apply subdomains.
14
15 .. versionchanged:: 2.1
16 Registering the same blueprint with the same name multiple
17 times is an error.
18
19 .. versionchanged:: 2.0.1
20 Nested blueprints are registered with their dotted name.
21 This allows different blueprints with the same name to be
22 nested at different locations.
23
24 .. versionchanged:: 2.0.1
25 The ``name`` option can be used to change the (pre-dotted)
26 name the blueprint is registered with. This allows the same
27 blueprint to be registered multiple times with unique names
28 for ``url_for``.
29 """
30 name_prefix = options.get("name_prefix", "")
31 self_name = options.get("name", self.name)
32 name = f"{name_prefix}.{self_name}".lstrip(".")
33
34 if name in app.blueprints:
35 bp_desc = "this" if app.blueprints[name] is self else "a different"
36 existing_at = f" '{name}'" if self_name != name else ""
37
38 raise ValueError(
39 f"The name '{self_name}' is already registered for"
40 f" {bp_desc} blueprint{existing_at}. Use 'name=' to"
41 f" provide a unique name."
42 )
43
44 first_bp_registration = not any(bp is self for bp in app.blueprints.values())
45 first_name_registration = name not in app.blueprints
46
47 app.blueprints[name] = self
48 self._got_registered_once = True
49 state = self.make_setup_state(app, options, first_bp_registration)
50
51 if self.has_static_folder:
52 state.add_url_rule(
53 f"{self.static_url_path}/<path:filename>",
54 view_func=self.send_static_file,
55 endpoint="static",
56 )
57
58 # Merge blueprint data into parent.
59 if first_bp_registration or first_name_registration:
60
61 def extend(bp_dict, parent_dict):
62 for key, values in bp_dict.items():
63 key = name if key is None else f"{name}.{key}"
64 parent_dict[key].extend(values)
65
66 for key, value in self.error_handler_spec.items():
67 key = name if key is None else f"{name}.{key}"
68 value = defaultdict(
69 dict,
70 {
71 code: {
72 exc_class: func for exc_class, func in code_values.items()
73 }
74 for code, code_values in value.items()
75 },
76 )
77 app.error_handler_spec[key] = value
78
79 for endpoint, func in self.view_functions.items():
80 app.view_functions[endpoint] = func
81
82 extend(self.before_request_funcs, app.before_request_funcs)
83 extend(self.after_request_funcs, app.after_request_funcs)
84 extend(
85 self.teardown_request_funcs,
86 app.teardown_request_funcs,
87 )
88 extend(self.url_default_functions, app.url_default_functions)
89 extend(self.url_value_preprocessors, app.url_value_preprocessors)
90 extend(self.template_context_processors, app.template_context_processors)
91
92 for deferred in self.deferred_functions:
93 deferred(state)
94
95 cli_resolved_group = options.get("cli_group", self.cli_group)
96
97 if self.cli.commands:
98 if cli_resolved_group is None:
99 app.cli.commands.update(self.cli.commands)
100 elif cli_resolved_group is _sentinel:
101 self.cli.name = name
102 app.cli.add_command(self.cli)
103 else:
104 self.cli.name = cli_resolved_group
105 app.cli.add_command(self.cli)
106
107 for blueprint, bp_options in self._blueprints:
108 bp_options = bp_options.copy()
109 bp_url_prefix = bp_options.get("url_prefix")
110 bp_subdomain = bp_options.get("subdomain")
111
112 if bp_subdomain is None:
113 bp_subdomain = blueprint.subdomain
114
115 if state.subdomain is not None and bp_subdomain is not None:
116 bp_options["subdomain"] = bp_subdomain + "." + state.subdomain
117 elif bp_subdomain is not None:
118 bp_options["subdomain"] = bp_subdomain
119 elif state.subdomain is not None:
120 bp_options["subdomain"] = state.subdomain
121
122 if bp_url_prefix is None:
123 bp_url_prefix = blueprint.url_prefix
124
125 if state.url_prefix is not None and bp_url_prefix is not None:
126 bp_options["url_prefix"] = (
127 state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/")
128 )
129 elif bp_url_prefix is not None:
130 bp_options["url_prefix"] = bp_url_prefix
131 elif state.url_prefix is not None:
132 bp_options["url_prefix"] = state.url_prefix
133
134 bp_options["name_prefix"] = name
135 blueprint.register(app, bp_options)
Path 12: 1 calls (0.01)
Flask (1)
{'url_prefix': None} (1)
1def register(self, app: Flask, options: dict) -> None:
2 """Called by :meth:`Flask.register_blueprint` to register all
3 views and callbacks registered on the blueprint with the
4 application. Creates a :class:`.BlueprintSetupState` and calls
5 each :meth:`record` callback with it.
6
7 :param app: The application this blueprint is being registered
8 with.
9 :param options: Keyword arguments forwarded from
10 :meth:`~Flask.register_blueprint`.
11
12 .. versionchanged:: 2.3
13 Nested blueprints now correctly apply subdomains.
14
15 .. versionchanged:: 2.1
16 Registering the same blueprint with the same name multiple
17 times is an error.
18
19 .. versionchanged:: 2.0.1
20 Nested blueprints are registered with their dotted name.
21 This allows different blueprints with the same name to be
22 nested at different locations.
23
24 .. versionchanged:: 2.0.1
25 The ``name`` option can be used to change the (pre-dotted)
26 name the blueprint is registered with. This allows the same
27 blueprint to be registered multiple times with unique names
28 for ``url_for``.
29 """
30 name_prefix = options.get("name_prefix", "")
31 self_name = options.get("name", self.name)
32 name = f"{name_prefix}.{self_name}".lstrip(".")
33
34 if name in app.blueprints:
35 bp_desc = "this" if app.blueprints[name] is self else "a different"
36 existing_at = f" '{name}'" if self_name != name else ""
37
38 raise ValueError(
39 f"The name '{self_name}' is already registered for"
40 f" {bp_desc} blueprint{existing_at}. Use 'name=' to"
41 f" provide a unique name."
42 )
43
44 first_bp_registration = not any(bp is self for bp in app.blueprints.values())
45 first_name_registration = name not in app.blueprints
46
47 app.blueprints[name] = self
48 self._got_registered_once = True
49 state = self.make_setup_state(app, options, first_bp_registration)
50
51 if self.has_static_folder:
52 state.add_url_rule(
53 f"{self.static_url_path}/<path:filename>",
54 view_func=self.send_static_file,
55 endpoint="static",
56 )
57
58 # Merge blueprint data into parent.
59 if first_bp_registration or first_name_registration:
60
61 def extend(bp_dict, parent_dict):
62 for key, values in bp_dict.items():
63 key = name if key is None else f"{name}.{key}"
64 parent_dict[key].extend(values)
65
66 for key, value in self.error_handler_spec.items():
67 key = name if key is None else f"{name}.{key}"
68 value = defaultdict(
69 dict,
70 {
71 code: {
72 exc_class: func for exc_class, func in code_values.items()
73 }
74 for code, code_values in value.items()
75 },
76 )
77 app.error_handler_spec[key] = value
78
79 for endpoint, func in self.view_functions.items():
80 app.view_functions[endpoint] = func
81
82 extend(self.before_request_funcs, app.before_request_funcs)
83 extend(self.after_request_funcs, app.after_request_funcs)
84 extend(
85 self.teardown_request_funcs,
86 app.teardown_request_funcs,
87 )
88 extend(self.url_default_functions, app.url_default_functions)
89 extend(self.url_value_preprocessors, app.url_value_preprocessors)
90 extend(self.template_context_processors, app.template_context_processors)
91
92 for deferred in self.deferred_functions:
93 deferred(state)
94
95 cli_resolved_group = options.get("cli_group", self.cli_group)
96
97 if self.cli.commands:
98 if cli_resolved_group is None:
99 app.cli.commands.update(self.cli.commands)
100 elif cli_resolved_group is _sentinel:
101 self.cli.name = name
102 app.cli.add_command(self.cli)
103 else:
104 self.cli.name = cli_resolved_group
105 app.cli.add_command(self.cli)
106
107 for blueprint, bp_options in self._blueprints:
108 bp_options = bp_options.copy()
109 bp_url_prefix = bp_options.get("url_prefix")
110 bp_subdomain = bp_options.get("subdomain")
111
112 if bp_subdomain is None:
113 bp_subdomain = blueprint.subdomain
114
115 if state.subdomain is not None and bp_subdomain is not None:
116 bp_options["subdomain"] = bp_subdomain + "." + state.subdomain
117 elif bp_subdomain is not None:
118 bp_options["subdomain"] = bp_subdomain
119 elif state.subdomain is not None:
120 bp_options["subdomain"] = state.subdomain
121
122 if bp_url_prefix is None:
123 bp_url_prefix = blueprint.url_prefix
124
125 if state.url_prefix is not None and bp_url_prefix is not None:
126 bp_options["url_prefix"] = (
127 state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/")
128 )
129 elif bp_url_prefix is not None:
130 bp_options["url_prefix"] = bp_url_prefix
131 elif state.url_prefix is not None:
132 bp_options["url_prefix"] = state.url_prefix
133
134 bp_options["name_prefix"] = name
135 blueprint.register(app, bp_options)
Path 13: 1 calls (0.01)
Flask (1)
{'subdomain': 'api'} (1)
1def register(self, app: Flask, options: dict) -> None:
2 """Called by :meth:`Flask.register_blueprint` to register all
3 views and callbacks registered on the blueprint with the
4 application. Creates a :class:`.BlueprintSetupState` and calls
5 each :meth:`record` callback with it.
6
7 :param app: The application this blueprint is being registered
8 with.
9 :param options: Keyword arguments forwarded from
10 :meth:`~Flask.register_blueprint`.
11
12 .. versionchanged:: 2.3
13 Nested blueprints now correctly apply subdomains.
14
15 .. versionchanged:: 2.1
16 Registering the same blueprint with the same name multiple
17 times is an error.
18
19 .. versionchanged:: 2.0.1
20 Nested blueprints are registered with their dotted name.
21 This allows different blueprints with the same name to be
22 nested at different locations.
23
24 .. versionchanged:: 2.0.1
25 The ``name`` option can be used to change the (pre-dotted)
26 name the blueprint is registered with. This allows the same
27 blueprint to be registered multiple times with unique names
28 for ``url_for``.
29 """
30 name_prefix = options.get("name_prefix", "")
31 self_name = options.get("name", self.name)
32 name = f"{name_prefix}.{self_name}".lstrip(".")
33
34 if name in app.blueprints:
35 bp_desc = "this" if app.blueprints[name] is self else "a different"
36 existing_at = f" '{name}'" if self_name != name else ""
37
38 raise ValueError(
39 f"The name '{self_name}' is already registered for"
40 f" {bp_desc} blueprint{existing_at}. Use 'name=' to"
41 f" provide a unique name."
42 )
43
44 first_bp_registration = not any(bp is self for bp in app.blueprints.values())
45 first_name_registration = name not in app.blueprints
46
47 app.blueprints[name] = self
48 self._got_registered_once = True
49 state = self.make_setup_state(app, options, first_bp_registration)
50
51 if self.has_static_folder:
52 state.add_url_rule(
53 f"{self.static_url_path}/<path:filename>",
54 view_func=self.send_static_file,
55 endpoint="static",
56 )
57
58 # Merge blueprint data into parent.
59 if first_bp_registration or first_name_registration:
60
61 def extend(bp_dict, parent_dict):
62 for key, values in bp_dict.items():
63 key = name if key is None else f"{name}.{key}"
64 parent_dict[key].extend(values)
65
66 for key, value in self.error_handler_spec.items():
67 key = name if key is None else f"{name}.{key}"
68 value = defaultdict(
69 dict,
70 {
71 code: {
72 exc_class: func for exc_class, func in code_values.items()
73 }
74 for code, code_values in value.items()
75 },
76 )
77 app.error_handler_spec[key] = value
78
79 for endpoint, func in self.view_functions.items():
80 app.view_functions[endpoint] = func
81
82 extend(self.before_request_funcs, app.before_request_funcs)
83 extend(self.after_request_funcs, app.after_request_funcs)
84 extend(
85 self.teardown_request_funcs,
86 app.teardown_request_funcs,
87 )
88 extend(self.url_default_functions, app.url_default_functions)
89 extend(self.url_value_preprocessors, app.url_value_preprocessors)
90 extend(self.template_context_processors, app.template_context_processors)
91
92 for deferred in self.deferred_functions:
93 deferred(state)
94
95 cli_resolved_group = options.get("cli_group", self.cli_group)
96
97 if self.cli.commands:
98 if cli_resolved_group is None:
99 app.cli.commands.update(self.cli.commands)
100 elif cli_resolved_group is _sentinel:
101 self.cli.name = name
102 app.cli.add_command(self.cli)
103 else:
104 self.cli.name = cli_resolved_group
105 app.cli.add_command(self.cli)
106
107 for blueprint, bp_options in self._blueprints:
108 bp_options = bp_options.copy()
109 bp_url_prefix = bp_options.get("url_prefix")
110 bp_subdomain = bp_options.get("subdomain")
111
112 if bp_subdomain is None:
113 bp_subdomain = blueprint.subdomain
114
115 if state.subdomain is not None and bp_subdomain is not None:
116 bp_options["subdomain"] = bp_subdomain + "." + state.subdomain
117 elif bp_subdomain is not None:
118 bp_options["subdomain"] = bp_subdomain
119 elif state.subdomain is not None:
120 bp_options["subdomain"] = state.subdomain
121
122 if bp_url_prefix is None:
123 bp_url_prefix = blueprint.url_prefix
124
125 if state.url_prefix is not None and bp_url_prefix is not None:
126 bp_options["url_prefix"] = (
127 state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/")
128 )
129 elif bp_url_prefix is not None:
130 bp_options["url_prefix"] = bp_url_prefix
131 elif state.url_prefix is not None:
132 bp_options["url_prefix"] = state.url_prefix
133
134 bp_options["name_prefix"] = name
135 blueprint.register(app, bp_options)
Path 14: 1 calls (0.01)
Flask (1)
{'subdomain': 'parent'} (1)
1def register(self, app: Flask, options: dict) -> None:
2 """Called by :meth:`Flask.register_blueprint` to register all
3 views and callbacks registered on the blueprint with the
4 application. Creates a :class:`.BlueprintSetupState` and calls
5 each :meth:`record` callback with it.
6
7 :param app: The application this blueprint is being registered
8 with.
9 :param options: Keyword arguments forwarded from
10 :meth:`~Flask.register_blueprint`.
11
12 .. versionchanged:: 2.3
13 Nested blueprints now correctly apply subdomains.
14
15 .. versionchanged:: 2.1
16 Registering the same blueprint with the same name multiple
17 times is an error.
18
19 .. versionchanged:: 2.0.1
20 Nested blueprints are registered with their dotted name.
21 This allows different blueprints with the same name to be
22 nested at different locations.
23
24 .. versionchanged:: 2.0.1
25 The ``name`` option can be used to change the (pre-dotted)
26 name the blueprint is registered with. This allows the same
27 blueprint to be registered multiple times with unique names
28 for ``url_for``.
29 """
30 name_prefix = options.get("name_prefix", "")
31 self_name = options.get("name", self.name)
32 name = f"{name_prefix}.{self_name}".lstrip(".")
33
34 if name in app.blueprints:
35 bp_desc = "this" if app.blueprints[name] is self else "a different"
36 existing_at = f" '{name}'" if self_name != name else ""
37
38 raise ValueError(
39 f"The name '{self_name}' is already registered for"
40 f" {bp_desc} blueprint{existing_at}. Use 'name=' to"
41 f" provide a unique name."
42 )
43
44 first_bp_registration = not any(bp is self for bp in app.blueprints.values())
45 first_name_registration = name not in app.blueprints
46
47 app.blueprints[name] = self
48 self._got_registered_once = True
49 state = self.make_setup_state(app, options, first_bp_registration)
50
51 if self.has_static_folder:
52 state.add_url_rule(
53 f"{self.static_url_path}/<path:filename>",
54 view_func=self.send_static_file,
55 endpoint="static",
56 )
57
58 # Merge blueprint data into parent.
59 if first_bp_registration or first_name_registration:
60
61 def extend(bp_dict, parent_dict):
62 for key, values in bp_dict.items():
63 key = name if key is None else f"{name}.{key}"
64 parent_dict[key].extend(values)
65
66 for key, value in self.error_handler_spec.items():
67 key = name if key is None else f"{name}.{key}"
68 value = defaultdict(
69 dict,
70 {
71 code: {
72 exc_class: func for exc_class, func in code_values.items()
73 }
74 for code, code_values in value.items()
75 },
76 )
77 app.error_handler_spec[key] = value
78
79 for endpoint, func in self.view_functions.items():
80 app.view_functions[endpoint] = func
81
82 extend(self.before_request_funcs, app.before_request_funcs)
83 extend(self.after_request_funcs, app.after_request_funcs)
84 extend(
85 self.teardown_request_funcs,
86 app.teardown_request_funcs,
87 )
88 extend(self.url_default_functions, app.url_default_functions)
89 extend(self.url_value_preprocessors, app.url_value_preprocessors)
90 extend(self.template_context_processors, app.template_context_processors)
91
92 for deferred in self.deferred_functions:
93 deferred(state)
94
95 cli_resolved_group = options.get("cli_group", self.cli_group)
96
97 if self.cli.commands:
98 if cli_resolved_group is None:
99 app.cli.commands.update(self.cli.commands)
100 elif cli_resolved_group is _sentinel:
101 self.cli.name = name
102 app.cli.add_command(self.cli)
103 else:
104 self.cli.name = cli_resolved_group
105 app.cli.add_command(self.cli)
106
107 for blueprint, bp_options in self._blueprints:
108 bp_options = bp_options.copy()
109 bp_url_prefix = bp_options.get("url_prefix")
110 bp_subdomain = bp_options.get("subdomain")
111
112 if bp_subdomain is None:
113 bp_subdomain = blueprint.subdomain
114
115 if state.subdomain is not None and bp_subdomain is not None:
116 bp_options["subdomain"] = bp_subdomain + "." + state.subdomain
117 elif bp_subdomain is not None:
118 bp_options["subdomain"] = bp_subdomain
119 elif state.subdomain is not None:
120 bp_options["subdomain"] = state.subdomain
121
122 if bp_url_prefix is None:
123 bp_url_prefix = blueprint.url_prefix
124
125 if state.url_prefix is not None and bp_url_prefix is not None:
126 bp_options["url_prefix"] = (
127 state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/")
128 )
129 elif bp_url_prefix is not None:
130 bp_options["url_prefix"] = bp_url_prefix
131 elif state.url_prefix is not None:
132 bp_options["url_prefix"] = state.url_prefix
133
134 bp_options["name_prefix"] = name
135 blueprint.register(app, bp_options)
Path 15: 1 calls (0.01)
Flask (1)
{} (1)
1def register(self, app: Flask, options: dict) -> None:
2 """Called by :meth:`Flask.register_blueprint` to register all
3 views and callbacks registered on the blueprint with the
4 application. Creates a :class:`.BlueprintSetupState` and calls
5 each :meth:`record` callback with it.
6
7 :param app: The application this blueprint is being registered
8 with.
9 :param options: Keyword arguments forwarded from
10 :meth:`~Flask.register_blueprint`.
11
12 .. versionchanged:: 2.3
13 Nested blueprints now correctly apply subdomains.
14
15 .. versionchanged:: 2.1
16 Registering the same blueprint with the same name multiple
17 times is an error.
18
19 .. versionchanged:: 2.0.1
20 Nested blueprints are registered with their dotted name.
21 This allows different blueprints with the same name to be
22 nested at different locations.
23
24 .. versionchanged:: 2.0.1
25 The ``name`` option can be used to change the (pre-dotted)
26 name the blueprint is registered with. This allows the same
27 blueprint to be registered multiple times with unique names
28 for ``url_for``.
29 """
30 name_prefix = options.get("name_prefix", "")
31 self_name = options.get("name", self.name)
32 name = f"{name_prefix}.{self_name}".lstrip(".")
33
34 if name in app.blueprints:
35 bp_desc = "this" if app.blueprints[name] is self else "a different"
36 existing_at = f" '{name}'" if self_name != name else ""
37
38 raise ValueError(
39 f"The name '{self_name}' is already registered for"
40 f" {bp_desc} blueprint{existing_at}. Use 'name=' to"
41 f" provide a unique name."
42 )
43
44 first_bp_registration = not any(bp is self for bp in app.blueprints.values())
45 first_name_registration = name not in app.blueprints
46
47 app.blueprints[name] = self
48 self._got_registered_once = True
49 state = self.make_setup_state(app, options, first_bp_registration)
50
51 if self.has_static_folder:
52 state.add_url_rule(
53 f"{self.static_url_path}/<path:filename>",
54 view_func=self.send_static_file,
55 endpoint="static",
56 )
57
58 # Merge blueprint data into parent.
59 if first_bp_registration or first_name_registration:
60
61 def extend(bp_dict, parent_dict):
62 for key, values in bp_dict.items():
63 key = name if key is None else f"{name}.{key}"
64 parent_dict[key].extend(values)
65
66 for key, value in self.error_handler_spec.items():
67 key = name if key is None else f"{name}.{key}"
68 value = defaultdict(
69 dict,
70 {
71 code: {
72 exc_class: func for exc_class, func in code_values.items()
73 }
74 for code, code_values in value.items()
75 },
76 )
77 app.error_handler_spec[key] = value
78
79 for endpoint, func in self.view_functions.items():
80 app.view_functions[endpoint] = func
81
82 extend(self.before_request_funcs, app.before_request_funcs)
83 extend(self.after_request_funcs, app.after_request_funcs)
84 extend(
85 self.teardown_request_funcs,
86 app.teardown_request_funcs,
87 )
88 extend(self.url_default_functions, app.url_default_functions)
89 extend(self.url_value_preprocessors, app.url_value_preprocessors)
90 extend(self.template_context_processors, app.template_context_processors)
91
92 for deferred in self.deferred_functions:
93 deferred(state)
94
95 cli_resolved_group = options.get("cli_group", self.cli_group)
96
97 if self.cli.commands:
98 if cli_resolved_group is None:
99 app.cli.commands.update(self.cli.commands)
100 elif cli_resolved_group is _sentinel:
101 self.cli.name = name
102 app.cli.add_command(self.cli)
103 else:
104 self.cli.name = cli_resolved_group
105 app.cli.add_command(self.cli)
106
107 for blueprint, bp_options in self._blueprints:
108 bp_options = bp_options.copy()
109 bp_url_prefix = bp_options.get("url_prefix")
110 bp_subdomain = bp_options.get("subdomain")
111
112 if bp_subdomain is None:
113 bp_subdomain = blueprint.subdomain
114
115 if state.subdomain is not None and bp_subdomain is not None:
116 bp_options["subdomain"] = bp_subdomain + "." + state.subdomain
117 elif bp_subdomain is not None:
118 bp_options["subdomain"] = bp_subdomain
119 elif state.subdomain is not None:
120 bp_options["subdomain"] = state.subdomain
121
122 if bp_url_prefix is None:
123 bp_url_prefix = blueprint.url_prefix
124
125 if state.url_prefix is not None and bp_url_prefix is not None:
126 bp_options["url_prefix"] = (
127 state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/")
128 )
129 elif bp_url_prefix is not None:
130 bp_options["url_prefix"] = bp_url_prefix
131 elif state.url_prefix is not None:
132 bp_options["url_prefix"] = state.url_prefix
133
134 bp_options["name_prefix"] = name
135 blueprint.register(app, bp_options)
Path 16: 1 calls (0.01)
Flask (1)
{} (1)
1def register(self, app: Flask, options: dict) -> None:
2 """Called by :meth:`Flask.register_blueprint` to register all
3 views and callbacks registered on the blueprint with the
4 application. Creates a :class:`.BlueprintSetupState` and calls
5 each :meth:`record` callback with it.
6
7 :param app: The application this blueprint is being registered
8 with.
9 :param options: Keyword arguments forwarded from
10 :meth:`~Flask.register_blueprint`.
11
12 .. versionchanged:: 2.3
13 Nested blueprints now correctly apply subdomains.
14
15 .. versionchanged:: 2.1
16 Registering the same blueprint with the same name multiple
17 times is an error.
18
19 .. versionchanged:: 2.0.1
20 Nested blueprints are registered with their dotted name.
21 This allows different blueprints with the same name to be
22 nested at different locations.
23
24 .. versionchanged:: 2.0.1
25 The ``name`` option can be used to change the (pre-dotted)
26 name the blueprint is registered with. This allows the same
27 blueprint to be registered multiple times with unique names
28 for ``url_for``.
29 """
30 name_prefix = options.get("name_prefix", "")
31 self_name = options.get("name", self.name)
32 name = f"{name_prefix}.{self_name}".lstrip(".")
33
34 if name in app.blueprints:
35 bp_desc = "this" if app.blueprints[name] is self else "a different"
36 existing_at = f" '{name}'" if self_name != name else ""
37
38 raise ValueError(
39 f"The name '{self_name}' is already registered for"
40 f" {bp_desc} blueprint{existing_at}. Use 'name=' to"
41 f" provide a unique name."
42 )
43
44 first_bp_registration = not any(bp is self for bp in app.blueprints.values())
45 first_name_registration = name not in app.blueprints
46
47 app.blueprints[name] = self
48 self._got_registered_once = True
49 state = self.make_setup_state(app, options, first_bp_registration)
50
51 if self.has_static_folder:
52 state.add_url_rule(
53 f"{self.static_url_path}/<path:filename>",
54 view_func=self.send_static_file,
55 endpoint="static",
56 )
57
58 # Merge blueprint data into parent.
59 if first_bp_registration or first_name_registration:
60
61 def extend(bp_dict, parent_dict):
62 for key, values in bp_dict.items():
63 key = name if key is None else f"{name}.{key}"
64 parent_dict[key].extend(values)
65
66 for key, value in self.error_handler_spec.items():
67 key = name if key is None else f"{name}.{key}"
68 value = defaultdict(
69 dict,
70 {
71 code: {
72 exc_class: func for exc_class, func in code_values.items()
73 }
74 for code, code_values in value.items()
75 },
76 )
77 app.error_handler_spec[key] = value
78
79 for endpoint, func in self.view_functions.items():
80 app.view_functions[endpoint] = func
81
82 extend(self.before_request_funcs, app.before_request_funcs)
83 extend(self.after_request_funcs, app.after_request_funcs)
84 extend(
85 self.teardown_request_funcs,
86 app.teardown_request_funcs,
87 )
88 extend(self.url_default_functions, app.url_default_functions)
89 extend(self.url_value_preprocessors, app.url_value_preprocessors)
90 extend(self.template_context_processors, app.template_context_processors)
91
92 for deferred in self.deferred_functions:
93 deferred(state)
94
95 cli_resolved_group = options.get("cli_group", self.cli_group)
96
97 if self.cli.commands:
98 if cli_resolved_group is None:
99 app.cli.commands.update(self.cli.commands)
100 elif cli_resolved_group is _sentinel:
101 self.cli.name = name
102 app.cli.add_command(self.cli)
103 else:
104 self.cli.name = cli_resolved_group
105 app.cli.add_command(self.cli)
106
107 for blueprint, bp_options in self._blueprints:
108 bp_options = bp_options.copy()
109 bp_url_prefix = bp_options.get("url_prefix")
110 bp_subdomain = bp_options.get("subdomain")
111
112 if bp_subdomain is None:
113 bp_subdomain = blueprint.subdomain
114
115 if state.subdomain is not None and bp_subdomain is not None:
116 bp_options["subdomain"] = bp_subdomain + "." + state.subdomain
117 elif bp_subdomain is not None:
118 bp_options["subdomain"] = bp_subdomain
119 elif state.subdomain is not None:
120 bp_options["subdomain"] = state.subdomain
121
122 if bp_url_prefix is None:
123 bp_url_prefix = blueprint.url_prefix
124
125 if state.url_prefix is not None and bp_url_prefix is not None:
126 bp_options["url_prefix"] = (
127 state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/")
128 )
129 elif bp_url_prefix is not None:
130 bp_options["url_prefix"] = bp_url_prefix
131 elif state.url_prefix is not None:
132 bp_options["url_prefix"] = state.url_prefix
133
134 bp_options["name_prefix"] = name
135 blueprint.register(app, bp_options)