Skip to content

Commit

Permalink
Merge pull request #530 from minrk/revert-514-pytest-asyncio
Browse files Browse the repository at this point in the history
require Python 3.9, jupyterhub 4, unpin pytest-asyncio
  • Loading branch information
minrk authored Feb 12, 2025
2 parents 0a14f78 + 72c5580 commit ad0f724
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 24 deletions.
9 changes: 5 additions & 4 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ jobs:
fail-fast: false
matrix:
include:
- python-version: "3.8"
pip-install-spec: "jupyterhub==2.3.1 sqlalchemy==1.*"
# jupyterhub 4 works with pytest-asyncio 0.25
# but requires some deprecated features,
# so don't let it upgrade further
- python-version: "3.9"
pip-install-spec: "jupyterhub==3.*"
pip-install-spec: "jupyterhub==4.* sqlalchemy==1.* pytest-asyncio==0.25.*"
- python-version: "3.11"
pip-install-spec: "jupyterhub==4.*"
pip-install-spec: "jupyterhub==4.* pytest-asyncio==0.25.*"
test-variation: podman
- python-version: "3.12"
pip-install-spec: "jupyterhub==5.*"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ for more information about features and usage.

## Prerequisites

Python 3.8 or above and JupyterHub 2.3.1 or above is required.
Python 3.9 or above and JupyterHub 4 or above is required.

## Installation

Expand Down
3 changes: 1 addition & 2 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
netifaces
notebook<7
pytest>=3.6
# FIXME: unpin pytest-asyncio
pytest-asyncio>=0.17,<0.23
pytest-asyncio>=0.25
pytest-cov
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ profile = "black"
[tool.black]
skip-string-normalization = true
target_version = [
"py38",
"py39",
"py310",
"py311",
Expand All @@ -38,6 +37,7 @@ target_version = [
[tool.pytest.ini_options]
addopts = "--verbose --color=yes --durations=10 --maxfail=1"
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "module"
testpaths = ["tests"]
# These markers are registered to avoid warnings triggered by importing from
# jupyterhub.tests.test_api.
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
docker
escapism
jupyterhub>=2.3.1
jupyterhub>=4
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def run(self):
'docker-swarm = dockerspawner:SwarmSpawner',
],
},
python_requires=">=3.8",
python_requires=">=3.9",
cmdclass={
'bdist_egg': bdist_egg if 'bdist_egg' in sys.argv else bdist_egg_disabled,
},
Expand Down
36 changes: 22 additions & 14 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,20 @@
import jupyterhub
import netifaces
import pytest
import pytest_asyncio
from docker import from_env as docker_from_env
from docker.errors import APIError
from jupyterhub import version_info as jh_version_info
from jupyterhub.tests.conftest import app as jupyterhub_app # noqa: F401
from jupyterhub.tests.conftest import event_loop # noqa: F401
from jupyterhub.tests.conftest import io_loop # noqa: F401
from jupyterhub.tests.conftest import ssl_tmpdir # noqa: F401
from jupyterhub.tests.conftest import user # noqa: F401
from jupyterhub.tests.mocking import MockHub

if 'event_loop' in inspect.signature(io_loop).parameters:
# older JupyterHub (< 5.x), io_loop requires deprecated event_loop
from jupyterhub.tests.conftest import event_loop # noqa: F401

from dockerspawner import DockerSpawner, SwarmSpawner, SystemUserSpawner

# import base jupyterhub fixtures
Expand Down Expand Up @@ -46,16 +50,19 @@


def pytest_collection_modifyitems(items):
"""This function is automatically run by pytest passing all collected test
functions.
We use it to add asyncio marker to all async tests and assert we don't use
test functions that are async generators which wouldn't make sense.
"""
for item in items:
if inspect.iscoroutinefunction(item.obj):
item.add_marker('asyncio')
assert not inspect.isasyncgenfunction(item.obj)
# apply loop_scope="module" to all async tests by default
# this can be hopefully be removed in favor of config if
# https://github.com/pytest-dev/pytest-asyncio/issues/793
# is addressed
pytest_asyncio_tests = (
item for item in items if pytest_asyncio.is_async_test(item)
)
asyncio_scope_marker = pytest.mark.asyncio(loop_scope="module")
for async_test in pytest_asyncio_tests:
# add asyncio marker _if_ not already present
asyncio_marker = async_test.get_closest_marker('asyncio')
if not asyncio_marker or not asyncio_marker.kwargs:
async_test.add_marker(asyncio_scope_marker, append=False)


@pytest.fixture
Expand Down Expand Up @@ -89,9 +96,10 @@ def dockerspawner_configured_app(app, named_servers):
@pytest.fixture
def swarmspawner_configured_app(app, named_servers):
"""Configure JupyterHub to use DockerSpawner"""
with mock.patch.dict(
app.tornado_settings, {"spawner_class": SwarmSpawner}
), mock.patch.dict(app.config.SwarmSpawner, {"network_name": "bridge"}):
with (
mock.patch.dict(app.tornado_settings, {"spawner_class": SwarmSpawner}),
mock.patch.dict(app.config.SwarmSpawner, {"network_name": "bridge"}),
):
yield app


Expand Down

0 comments on commit ad0f724

Please sign in to comment.