Fix wrapped view function comparison

Wrapped functions are not comparable, see
https://bugs.python.org/issue3564, therefore a marker is used to note
when the function has been sync wrapped to allow comparison with the
wrapped function instead.

This ensures that multiple route decorators work without raising
exceptions i.e.,

    @app.route("/")
    @app.route("/a")
    async def index():
        ...

works.
This commit is contained in:
pgjones 2021-04-16 12:34:51 +01:00
parent fab26dcbe9
commit 5c6a0f0c12
3 changed files with 5 additions and 1 deletions

View file

@ -1048,6 +1048,8 @@ class Flask(Scaffold):
self.url_map.add(rule)
if view_func is not None:
old_func = self.view_functions.get(endpoint)
if getattr(old_func, "_flask_sync_wrapper", False):
old_func = old_func.__wrapped__
if old_func is not None and old_func != view_func:
raise AssertionError(
"View function mapping is overwriting an existing"

View file

@ -780,4 +780,5 @@ def run_async(func):
return async_to_sync(inner)(*args, **kwargs)
outer._flask_sync_wrapper = True
return outer

View file

@ -24,6 +24,7 @@ def _async_app():
app = Flask(__name__)
@app.route("/", methods=["GET", "POST"])
@app.route("/home", methods=["GET", "POST"])
async def index():
await asyncio.sleep(0)
return request.method
@ -57,7 +58,7 @@ def _async_app():
@pytest.mark.skipif(sys.version_info < (3, 7), reason="requires Python >= 3.7")
@pytest.mark.parametrize("path", ["/", "/bp/"])
@pytest.mark.parametrize("path", ["/", "/home", "/bp/"])
def test_async_route(path, async_app):
test_client = async_app.test_client()
response = test_client.get(path)