Skip to content

quart-flask-patch fails on Python 3.14 #7

@EricZhang456

Description

@EricZhang456

Here's a simple test script

import quart_flask_patch
from quart import Quart

app = Quart(__name__)

@app.route("/")
async def hello_world():
    return "Hello, World"

app.run()

In Python 3.13 the script above works fine, in Python 3.14 I get the following exception

$ python test.py
 * Serving Quart app 'test'
 * Debug mode: False
 * Please use an ASGI server (e.g. Hypercorn) directly in production
 * Running on http://127.0.0.1:5000 (CTRL + C to quit)
Traceback (most recent call last):
  File "/Users/eric/Documents/blah/test.py", line 10, in <module>
    app.run()
    ~~~~~~~^^
  File "/Users/eric/Documents/blah/.venv/lib/python3.14/site-packages/quart/app.py", line 878, in run
    loop.run_until_complete(asyncio.gather(*tasks))
    ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.14.2/Frameworks/Python.framework/Versions/3.14/lib/python3.14/asyncio/base_events.py", line 719, in run_until_complete
    return future.result()
           ~~~~~~~~~~~~~^^
  File "/opt/homebrew/Cellar/[email protected]/3.14.2/Frameworks/Python.framework/Versions/3.14/lib/python3.14/asyncio/tasks.py", line 289, in __step_run_and_handle_result
    result = coro.send(None)
  File "/Users/eric/Documents/blah/.venv/lib/python3.14/site-packages/hypercorn/asyncio/__init__.py", line 45, in serve
    await worker_serve(
        wrap_app(app, config.wsgi_max_body_size, mode), config, shutdown_trigger=shutdown_trigger
    )
  File "/Users/eric/Documents/blah/.venv/lib/python3.14/site-packages/hypercorn/asyncio/run.py", line 85, in worker_serve
    await lifespan.wait_for_startup()
  File "/Users/eric/Documents/blah/.venv/lib/python3.14/site-packages/hypercorn/asyncio/lifespan.py", line 93, in wait_for_startup
    await asyncio.wait_for(self.startup.wait(), timeout=self.config.startup_timeout)
  File "/opt/homebrew/Cellar/[email protected]/3.14.2/Frameworks/Python.framework/Versions/3.14/lib/python3.14/asyncio/tasks.py", line 487, in wait_for
    async with timeouts.timeout(timeout):
               ~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.14.2/Frameworks/Python.framework/Versions/3.14/lib/python3.14/asyncio/timeouts.py", line 88, in __aenter__
    raise RuntimeError("Timeout should be used inside a task")
RuntimeError: Timeout should be used inside a task
Task was destroyed but it is pending!
task: <Task pending name='Task-2' coro=<observe_changes() running at /Users/eric/Documents/blah/.venv/lib/python3.14/site-packages/quart/utils.py:120> wait_for=<Future pending cb=[Task.__wakeup()]> cb=[gather.<locals>._done_callback() at /opt/homebrew/Cellar/[email protected]/3.14.2/Frameworks/Python.framework/Versions/3.14/lib/python3.14/asyncio/tasks.py:810]>
Task was destroyed but it is pending!
task: <Task pending name='Task-3' coro=<Lifespan.handle_lifespan() running at /Users/eric/Documents/blah/.venv/lib/python3.14/site-packages/hypercorn/asyncio/lifespan.py:56> wait_for=<Future pending cb=[Task.__wakeup()]>>
[2025-12-12 00:35:01 +0800] [4476] [ERROR] ASGI Framework Lifespan error, shutdown without Lifespan support
Traceback (most recent call last):
  File "/opt/homebrew/Cellar/[email protected]/3.14.2/Frameworks/Python.framework/Versions/3.14/lib/python3.14/asyncio/queues.py", line 186, in get
GeneratorExit

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/eric/Documents/blah/.venv/lib/python3.14/site-packages/hypercorn/asyncio/lifespan.py", line 56, in handle_lifespan
    await self.app(
    ...<5 lines>...
    )
  File "/Users/eric/Documents/blah/.venv/lib/python3.14/site-packages/hypercorn/app_wrappers.py", line 34, in __call__
  File "/Users/eric/Documents/blah/.venv/lib/python3.14/site-packages/quart/app.py", line 1735, in __call__
    await self.asgi_app(scope, receive, send)
  File "/Users/eric/Documents/blah/.venv/lib/python3.14/site-packages/quart/app.py", line 1761, in asgi_app
    await asgi_handler(receive, send)
  File "/Users/eric/Documents/blah/.venv/lib/python3.14/site-packages/quart/asgi.py", line 362, in __call__
  File "/Users/eric/Documents/blah/.venv/lib/python3.14/site-packages/hypercorn/asyncio/lifespan.py", line 109, in asgi_receive
    return await self.app_queue.get()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.14.2/Frameworks/Python.framework/Versions/3.14/lib/python3.14/asyncio/queues.py", line 188, in get
  File "/opt/homebrew/Cellar/[email protected]/3.14.2/Frameworks/Python.framework/Versions/3.14/lib/python3.14/asyncio/futures.py", line 164, in cancel
  File "/opt/homebrew/Cellar/[email protected]/3.14.2/Frameworks/Python.framework/Versions/3.14/lib/python3.14/asyncio/futures.py", line 179, in __schedule_callbacks
  File "/opt/homebrew/Cellar/[email protected]/3.14.2/Frameworks/Python.framework/Versions/3.14/lib/python3.14/asyncio/base_events.py", line 827, in call_soon
    self._check_closed()
  File "/opt/homebrew/Cellar/[email protected]/3.14.2/Frameworks/Python.framework/Versions/3.14/lib/python3.14/asyncio/base_events.py", line 550, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
<sys>:0: RuntimeWarning: coroutine 'Event.wait' was never awaited

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions