Skip to content

Commit

Permalink
warn when registering same blueprint with same name
Browse files Browse the repository at this point in the history
  • Loading branch information
davidism authored and pgjones committed May 21, 2021
1 parent 63b3067 commit 9409be6
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 17 deletions.
3 changes: 2 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ Unreleased
- ``register_blueprint`` takes a ``name`` option to change the
(pre-dotted) name the blueprint is registered with. This allows the
same blueprint to be registered multiple times with unique names for
``url_for``. :issue:`1091`
``url_for``. Registering the same blueprint with the same name
multiple times is deprecated. :issue:`1091`


Version 2.0.0
Expand Down
36 changes: 24 additions & 12 deletions src/flask/blueprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,23 +283,35 @@ def register(self, app: "Flask", options: dict) -> None:
name the blueprint is registered with. This allows the same
blueprint to be registered multiple times with unique names
for ``url_for``.
"""
first_registration = True

for blueprint in app.blueprints.values():
if blueprint is self:
first_registration = False
.. versionchanged:: 2.0.1
Registering the same blueprint with the same name multiple
times is deprecated and will become an error in Flask 2.1.
"""
first_registration = not any(bp is self for bp in app.blueprints.values())
name_prefix = options.get("name_prefix", "")
self_name = options.get("name", self.name)
name = f"{name_prefix}.{self_name}".lstrip(".")

if name in app.blueprints and app.blueprints[name] is not self:
raise ValueError(
f"Blueprint name '{self.name}' "
f"is already registered by {app.blueprints[self.name]}. "
"Blueprints must have unique names."
)
if name in app.blueprints:
existing_at = f" '{name}'" if self_name != name else ""

if app.blueprints[name] is not self:
raise ValueError(
f"The name '{self_name}' is already registered for"
f" a different blueprint{existing_at}. Use 'name='"
" to provide a unique name."
)
else:
import warnings

warnings.warn(
f"The name '{self_name}' is already registered for"
f" this blueprint{existing_at}. Use 'name=' to"
" provide a unique name. This will become an error"
" in Flask 2.1.",
stacklevel=4,
)

app.blueprints[name] = self
self._got_registered_once = True
Expand Down
12 changes: 8 additions & 4 deletions tests/test_blueprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def bar(bar):
return str(bar)

app.register_blueprint(bp, url_prefix="/1", url_defaults={"bar": 23})
app.register_blueprint(bp, url_prefix="/2", url_defaults={"bar": 19})
app.register_blueprint(bp, name="test2", url_prefix="/2", url_defaults={"bar": 19})

assert client.get("/1/foo").data == b"23/42"
assert client.get("/2/foo").data == b"19/42"
Expand Down Expand Up @@ -873,9 +873,13 @@ def test_unique_blueprint_names(app, client) -> None:
bp2 = flask.Blueprint("bp", __name__)

app.register_blueprint(bp)
app.register_blueprint(bp) # same name, same object, no error

with pytest.warns(UserWarning):
app.register_blueprint(bp) # same bp, same name, warning

app.register_blueprint(bp, name="again") # same bp, different name, ok

with pytest.raises(ValueError):
app.register_blueprint(bp2) # same name, different object
app.register_blueprint(bp2) # different bp, same name, error

app.register_blueprint(bp2, name="alt") # different name
app.register_blueprint(bp2, name="alt") # different bp, different name, ok

0 comments on commit 9409be6

Please sign in to comment.