warn when registering same blueprint with same name

This commit is contained in:
David Lord 2021-05-20 13:08:28 -07:00 committed by pgjones
parent 63b306743f
commit 9409be6e34
3 changed files with 34 additions and 17 deletions

View file

@ -33,7 +33,8 @@ Unreleased
- ``register_blueprint`` takes a ``name`` option to change the - ``register_blueprint`` takes a ``name`` option to change the
(pre-dotted) name the blueprint is registered with. This allows the (pre-dotted) name the blueprint is registered with. This allows the
same blueprint to be registered multiple times with unique names for 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 Version 2.0.0

View file

@ -283,22 +283,34 @@ class Blueprint(Scaffold):
name the blueprint is registered with. This allows the same name the blueprint is registered with. This allows the same
blueprint to be registered multiple times with unique names blueprint to be registered multiple times with unique names
for ``url_for``. for ``url_for``.
.. 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 = True first_registration = not any(bp is self for bp in app.blueprints.values())
for blueprint in app.blueprints.values():
if blueprint is self:
first_registration = False
name_prefix = options.get("name_prefix", "") name_prefix = options.get("name_prefix", "")
self_name = options.get("name", self.name) self_name = options.get("name", self.name)
name = f"{name_prefix}.{self_name}".lstrip(".") name = f"{name_prefix}.{self_name}".lstrip(".")
if name in app.blueprints and app.blueprints[name] is not self: if name in app.blueprints:
existing_at = f" '{name}'" if self_name != name else ""
if app.blueprints[name] is not self:
raise ValueError( raise ValueError(
f"Blueprint name '{self.name}' " f"The name '{self_name}' is already registered for"
f"is already registered by {app.blueprints[self.name]}. " f" a different blueprint{existing_at}. Use 'name='"
"Blueprints must have unique names." " 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 app.blueprints[name] = self

View file

@ -140,7 +140,7 @@ def test_blueprint_url_defaults(app, client):
return str(bar) return str(bar)
app.register_blueprint(bp, url_prefix="/1", url_defaults={"bar": 23}) 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("/1/foo").data == b"23/42"
assert client.get("/2/foo").data == b"19/42" assert client.get("/2/foo").data == b"19/42"
@ -873,9 +873,13 @@ def test_unique_blueprint_names(app, client) -> None:
bp2 = flask.Blueprint("bp", __name__) bp2 = flask.Blueprint("bp", __name__)
app.register_blueprint(bp) 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): 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