Skip to content
5 changes: 5 additions & 0 deletions starlette/routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,11 @@ def __init__(
"See more about it on https://www.starlette.io/lifespan/.",
DeprecationWarning,
)
if lifespan:
warnings.warn(
"The `lifespan` parameter cannot be used with `on_startup` or `on_shutdown`. "
"Both `on_startup` and `on_shutdown` will be ignored."
Comment thread
Kludex marked this conversation as resolved.
Outdated
)

if lifespan is None:
self.lifespan_context: Lifespan = _DefaultLifespan(self)
Expand Down
25 changes: 25 additions & 0 deletions tests/test_routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,31 @@ async def run_shutdown():
assert shutdown_complete


def test_lifespan_with_on_events():
@contextlib.asynccontextmanager
async def lifespan(app):
yield {"foo": "bar"}

def run_startup():
pass

def run_shutdown():
pass

def hello_world(request):
return PlainTextResponse("hello, world")

with pytest.warns(
UserWarning, match="The `lifespan` parameter cannot be used with `on_startup` or `on_shutdown`."
Comment thread
Kludex marked this conversation as resolved.
Outdated
):
Router(
on_startup=[run_startup],
on_shutdown=[run_shutdown],
lifespan=lifespan,
routes=[Route("/", hello_world)],
)


def test_lifespan_sync(test_client_factory):
startup_complete = False
shutdown_complete = False
Expand Down