Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

blueprints are registered with nested names, can change registered name #4074

Merged
merged 8 commits into from
May 21, 2021

Conversation

pgjones
Copy link
Member

@pgjones pgjones commented May 18, 2021

@pgjones pgjones changed the base branch from main to 2.0.x May 18, 2021 12:40
src/flask/blueprints.py Outdated Show resolved Hide resolved
src/flask/blueprints.py Outdated Show resolved Hide resolved
src/flask/app.py Outdated Show resolved Hide resolved
src/flask/blueprints.py Outdated Show resolved Hide resolved
@davidism
Copy link
Member

I've added a _split_blueprint_path helper function that uses functools.lru_cache. I figured that splitting the blueprint path over and over again across requests would be wasteful, so this will cache as long as a WSGI worker is still active. @pgjones do you think this is worth it? We can remove it if not.

I also think we should start issuing a deprecation warning if the same blueprint was registered with the same name, and eventually show the error for any name collisions, not just for different blueprints with the same name.

@davidism davidism changed the title Blueprint fixes blueprints are registered with nested names, can change registered name May 20, 2021
src/flask/wrappers.py Outdated Show resolved Hide resolved
@davidism
Copy link
Member

davidism commented May 20, 2021

from flask import Blueprint
from flask import Flask
from flask import url_for

app = Flask(__name__)
bp = Blueprint("user", __name__)


@bp.get("/")
def index():
    return url_for(".index")


app.register_blueprint(bp, url_prefix="/a")
app.register_blueprint(bp, name="user_b", url_prefix="/b")

Navigating to both /a/ and /b/ outputs /a/, so #1091 isn't solved yet. It seems request.blueprint is "user" instead of "user_b" when navigating to /b/.

Looking at app.url_map shows that both were registered with the same endpoint still:

Map([<Rule '/a/' (GET, HEAD, OPTIONS) -> user.index>,
 <Rule '/b/' (GET, HEAD, OPTIONS) -> user.index>,
 <Rule '/static/<filename>' (GET, HEAD, OPTIONS) -> static>])

app.blueprints shows the two names, so there's something going wrong with registration.

pgjones and others added 8 commits May 21, 2021 15:04
This ensures that the url_prefix is correctly applied, no matter if
set during the registration override or when constructing the
blueprint.
Following discussions for Flask we've decided to name blueprints based
on how they are registered. This allows for two different blueprints
to have the same self-name as long as they are registered in different
nested positions. This helps users choose better blueprint names.
This allows the same blueprint to be registered multiple times at the
same level, but with differing url_prefixes and names.
By raising a ValueError if attempted. I don't see a use case that
makes this worth supporting.
This ensures that if a blueprint is renamed at the time of
registration that name is used when constructing endpoints, as
expected.
@davidism davidism merged commit 255461d into pallets:2.0.x May 21, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 5, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Nested blueprint should be able to have same name url_for can't distinguish a blueprint mounted two times
2 participants