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,23 +283,35 @@ 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:
raise ValueError( existing_at = f" '{name}'" if self_name != name else ""
f"Blueprint name '{self.name}' "
f"is already registered by {app.blueprints[self.name]}. " if app.blueprints[name] is not self:
"Blueprints must have unique names." 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 app.blueprints[name] = self
self._got_registered_once = True self._got_registered_once = True

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