Skip to content

Commit 05c7a21

Browse files
dependabot[bot]Mateo Lostanlen
andauthored
build(deps): bump pytest-asyncio from 0.21.2 to 1.3.0 (#597)
* build(deps): bump pytest-asyncio from 0.21.2 to 1.3.0 Bumps [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) from 0.21.2 to 1.3.0. - [Release notes](https://github.com/pytest-dev/pytest-asyncio/releases) - [Commits](pytest-dev/pytest-asyncio@v0.21.2...v1.3.0) --- updated-dependencies: - dependency-name: pytest-asyncio dependency-version: 1.3.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * fix: adapt async fixtures to pytest-asyncio 1.x pytest-asyncio 1.0 removed support for the session-scoped 'event_loop' fixture that this repo defined in src/tests/conftest.py. With that fixture gone, function-scoped async fixtures get a fresh event loop per test, while the module-level SQLAlchemy async engine is bound to whichever loop imported it — so asyncpg raises 'Future attached to a different loop' the moment a fixture tries to use the engine. Migration: - Drop the custom 'event_loop' fixture entirely; pytest-asyncio 1.x manages the loop itself. - Add asyncio_default_fixture_loop_scope = 'session' and asyncio_default_test_loop_scope = 'session' under [tool.pytest.ini_options] so all async fixtures and tests share one loop for the whole session — same behaviour as the old custom fixture, just expressed through the supported config knobs. - Add an explicit loop_scope='session' on every @pytest_asyncio.fixture for belt-and-braces (in case fixture defaults aren't applied to decorators with explicit scope=). Also pin the pyro-camera-api-client git dep via [tool.uv.sources] so 'uv sync --locked' doesn't re-resolve the moving 'main' branch during Docker build. --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Mateo Lostanlen <mateo@pyronear.org>
1 parent 05eec31 commit 05c7a21

4 files changed

Lines changed: 21 additions & 24 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ quality = [
5151
]
5252
test = [
5353
"pytest==9.0.3",
54-
"pytest-asyncio==0.21.2",
54+
"pytest-asyncio==1.3.0",
5555
"pytest-cov>=4.0.0,<5.0.0",
5656
"pytest-pretty>=1.0.0,<2.0.0",
5757
"httpx>=0.23.0",

src/pytest.ini

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[pytest]
2+
asyncio_mode = strict
3+
asyncio_default_fixture_loop_scope = session
4+
asyncio_default_test_loop_scope = session

src/tests/conftest.py

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import asyncio
21
import io
32
import os
43
from datetime import datetime
5-
from typing import AsyncGenerator, Dict, Generator
4+
from typing import AsyncGenerator, Dict
65

76
import pytest
87
import pytest_asyncio
@@ -227,14 +226,7 @@
227226
]
228227

229228

230-
@pytest.fixture(scope="session")
231-
def event_loop(request) -> Generator:
232-
loop = asyncio.get_event_loop_policy().new_event_loop()
233-
yield loop
234-
loop.close()
235-
236-
237-
@pytest_asyncio.fixture(scope="function")
229+
@pytest_asyncio.fixture(scope="function", loop_scope="session")
238230
async def async_client() -> AsyncGenerator[AsyncClient, None]:
239231
transport = ASGITransport(app=app)
240232
async with AsyncClient(
@@ -246,7 +238,7 @@ async def async_client() -> AsyncGenerator[AsyncClient, None]:
246238
yield client
247239

248240

249-
@pytest_asyncio.fixture(scope="function")
241+
@pytest_asyncio.fixture(scope="function", loop_scope="session")
250242
async def async_session() -> AsyncSession:
251243
async with engine.begin() as conn:
252244
await conn.run_sync(SQLModel.metadata.create_all)
@@ -278,7 +270,7 @@ def mock_img():
278270
return requests.get("https://avatars.githubusercontent.com/u/61667887?s=200&v=4", timeout=5).content
279271

280272

281-
@pytest_asyncio.fixture(scope="function")
273+
@pytest_asyncio.fixture(scope="function", loop_scope="session")
282274
async def organization_session(async_session: AsyncSession):
283275
for entry in ORGANIZATION_TABLE:
284276
async_session.add(Organization(**entry))
@@ -302,7 +294,7 @@ async def organization_session(async_session: AsyncSession):
302294
pass
303295

304296

305-
@pytest_asyncio.fixture(scope="function")
297+
@pytest_asyncio.fixture(scope="function", loop_scope="session")
306298
async def webhook_session(async_session: AsyncSession):
307299
for entry in WEBHOOK_TABLE:
308300
async_session.add(Webhook(**entry))
@@ -317,7 +309,7 @@ async def webhook_session(async_session: AsyncSession):
317309
await async_session.rollback()
318310

319311

320-
@pytest_asyncio.fixture(scope="function")
312+
@pytest_asyncio.fixture(scope="function", loop_scope="session")
321313
async def user_session(organization_session: AsyncSession, monkeypatch):
322314
monkeypatch.setattr(users, "hash_password", mock_hash_password)
323315
monkeypatch.setattr(login, "verify_password", mock_verify_password)
@@ -332,7 +324,7 @@ async def user_session(organization_session: AsyncSession, monkeypatch):
332324
await organization_session.rollback()
333325

334326

335-
@pytest_asyncio.fixture(scope="function")
327+
@pytest_asyncio.fixture(scope="function", loop_scope="session")
336328
async def camera_session(user_session: AsyncSession, organization_session: AsyncSession):
337329
for entry in CAM_TABLE:
338330
user_session.add(Camera(**entry))
@@ -345,7 +337,7 @@ async def camera_session(user_session: AsyncSession, organization_session: Async
345337
await user_session.rollback()
346338

347339

348-
@pytest_asyncio.fixture(scope="function")
340+
@pytest_asyncio.fixture(scope="function", loop_scope="session")
349341
async def pose_session(camera_session: AsyncSession):
350342
for entry in POSE_TABLE:
351343
camera_session.add(Pose(**entry))
@@ -358,7 +350,7 @@ async def pose_session(camera_session: AsyncSession):
358350
await camera_session.rollback()
359351

360352

361-
@pytest_asyncio.fixture(scope="function")
353+
@pytest_asyncio.fixture(scope="function", loop_scope="session")
362354
async def occlusion_mask_session(pose_session: AsyncSession):
363355
for entry in OCCLUSION_MASK_TABLE:
364356
pose_session.add(OcclusionMask(**entry))
@@ -373,7 +365,7 @@ async def occlusion_mask_session(pose_session: AsyncSession):
373365
await pose_session.rollback()
374366

375367

376-
@pytest_asyncio.fixture(scope="function")
368+
@pytest_asyncio.fixture(scope="function", loop_scope="session")
377369
async def sequence_session(pose_session: AsyncSession):
378370
for entry in SEQ_TABLE:
379371
pose_session.add(Sequence(**entry))
@@ -388,7 +380,7 @@ async def sequence_session(pose_session: AsyncSession):
388380
await pose_session.rollback()
389381

390382

391-
@pytest_asyncio.fixture(scope="function")
383+
@pytest_asyncio.fixture(scope="function", loop_scope="session")
392384
async def detection_session(pose_session: AsyncSession, sequence_session: AsyncSession):
393385
for entry in DET_TABLE:
394386
sequence_session.add(Detection(**entry))

uv.lock

Lines changed: 5 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)