From 1fd4e1b860e29a28a63b3b8e610a00645526827a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 14:48:54 +0200 Subject: [PATCH] chore(deps): bump pytest from 7.1.2 to 8.3.1 (#368) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: dependabot[bot] Signed-off-by: Guilhem Barthés Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Guilhem Barthés --- changes/1509.removed | 1 + requirements.txt | 3 +- tests/conftest.py | 2 + tests/lazy_fixture.py | 89 +++++++++++++++++++++++++++++++++++++++ tests/test_permissions.py | 38 +++++++++-------- 5 files changed, 113 insertions(+), 20 deletions(-) create mode 100644 changes/1509.removed create mode 100644 tests/lazy_fixture.py diff --git a/changes/1509.removed b/changes/1509.removed new file mode 100644 index 00000000..24e85643 --- /dev/null +++ b/changes/1509.removed @@ -0,0 +1 @@ +Dependency `pytest-lazy-fixture` \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 1bd35bae..51ddfdb7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,8 @@ docker==7.1.0 -pytest==7.1.2 +pytest==8.3.1 dataclasses==0.7;python_version<"3.7" pydantic>=2.3.0, <3.0.0 pytest-xdist==3.6.1 -pytest-lazy-fixture==0.6.3 flake8==7.1.0 flake8-bugbear==24.4.26 isort==5.13.2 diff --git a/tests/conftest.py b/tests/conftest.py index bcd0b430..37015b44 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -10,6 +10,8 @@ from substratest.factory import AugmentedDataset from substratest.fl_interface import FunctionCategory +from .lazy_fixture import pytest_fixture_setup # noqa: F401, needed to set-up fixture + TESTS_RUN_UUID = uuid.uuid4().hex # unique uuid identifying the tests run pytest_plugins = ["pytest_skipuntil"] diff --git a/tests/lazy_fixture.py b/tests/lazy_fixture.py new file mode 100644 index 00000000..c0552216 --- /dev/null +++ b/tests/lazy_fixture.py @@ -0,0 +1,89 @@ +import dataclasses +import typing + +import pytest + + +@dataclasses.dataclass +class LazyFixture: + """Lazy fixture dataclass.""" + + name: str + + +def lazy_fixture(name: str) -> LazyFixture: + """Mark a fixture as lazy.""" + return LazyFixture(name) + + +def is_lazy_fixture(value: object) -> bool: + """Check whether a value is a lazy fixture.""" + return isinstance(value, LazyFixture) + + +def pytest_make_parametrize_id( + config: pytest.Config, + val: object, + argname: str, +) -> typing.Optional[str]: + """Inject lazy fixture parametrized id. + + Reference: + - https://docs.pytest.org/en/latest/reference/reference.html#pytest.hookspec.pytest_make_parametrize_id + + Args: + config (pytest.Config): pytest configuration. + value (object): fixture value. + argname (str): automatic parameter name. + + Returns: + typing.Optional[str]: new parameter id. + """ + if is_lazy_fixture(val): + return typing.cast(LazyFixture, val).name + return None + + +@pytest.hookimpl(tryfirst=True) +def pytest_fixture_setup( + fixturedef: pytest.FixtureDef, + request: pytest.FixtureRequest, +) -> typing.Optional[object]: + """Lazy fixture setup hook. + + This hook will never take over a fixture setup but just simply will + try to resolve recursively any lazy fixture found in request.param. + + Reference: + - https://docs.pytest.org/en/latest/reference/reference.html#pytest.hookspec.pytest_fixture_setup + + Args: + fixturedef (pytest.FixtureDef): fixture definition object. + request (pytest.FixtureRequest): fixture request object. + + Returns: + typing.Optional[object]: fixture value or None otherwise. + """ + if hasattr(request, "param") and request.param: + request.param = _resolve_lazy_fixture(request.param, request) + return None + + +def _resolve_lazy_fixture(__val: object, request: pytest.FixtureRequest) -> object: + """Lazy fixture resolver. + + Args: + __val (object): fixture value object. + request (pytest.FixtureRequest): pytest fixture request object. + + Returns: + object: resolved fixture value. + """ + if isinstance(__val, (list, tuple)): + return tuple(_resolve_lazy_fixture(v, request) for v in __val) + if isinstance(__val, typing.Mapping): + return {k: _resolve_lazy_fixture(v, request) for k, v in __val.items()} + if not is_lazy_fixture(__val): + return __val + lazy_obj = typing.cast(LazyFixture, __val) + return request.getfixturevalue(lazy_obj.name) diff --git a/tests/test_permissions.py b/tests/test_permissions.py index 02d0181f..c1f3c0c6 100644 --- a/tests/test_permissions.py +++ b/tests/test_permissions.py @@ -11,6 +11,8 @@ from substratest.fl_interface import FLTaskOutputGenerator from substratest.fl_interface import OutputIdentifiers +from .lazy_fixture import lazy_fixture + @pytest.fixture def public(): @@ -56,11 +58,11 @@ def test_permission_creation(is_public, factory, client): @pytest.mark.parametrize( "permissions", [ - pytest.lazy_fixture("public"), - pytest.lazy_fixture("private"), - pytest.lazy_fixture("all_organizations"), - pytest.lazy_fixture("organization_1_only"), - pytest.lazy_fixture("organization_2_only"), + lazy_fixture("public"), + lazy_fixture("private"), + lazy_fixture("all_organizations"), + lazy_fixture("organization_1_only"), + lazy_fixture("organization_2_only"), ], ) def test_get_metadata(permissions, factory, clients, channel): @@ -99,8 +101,8 @@ def test_permission_invalid_organization_id(factory, client): @pytest.mark.parametrize( "permissions", [ - pytest.lazy_fixture("public"), - pytest.lazy_fixture("organization_2_only"), + lazy_fixture("public"), + lazy_fixture("organization_2_only"), ], ) def test_download_asset_access_granted(permissions, factory, client_1, client_2, channel): @@ -136,14 +138,14 @@ def test_download_asset_access_restricted(factory, client_1, client_2, channel): "permissions_1,permissions_2,expected_permissions", [ ( - pytest.lazy_fixture("organization_2_only"), - pytest.lazy_fixture("organization_1_only"), - pytest.lazy_fixture("organizations_1_and_2_only"), + lazy_fixture("organization_2_only"), + lazy_fixture("organization_1_only"), + lazy_fixture("organizations_1_and_2_only"), ), ( - pytest.lazy_fixture("public"), - pytest.lazy_fixture("organization_1_only"), - pytest.lazy_fixture("organizations_1_and_2_only"), + lazy_fixture("public"), + lazy_fixture("organization_1_only"), + lazy_fixture("organizations_1_and_2_only"), ), ], ) @@ -227,11 +229,11 @@ def test_permissions_denied_process(factory, client_1, client_2, channel, worker "client_1_permissions,client_2_permissions,expectation", [ ( - pytest.lazy_fixture("private"), - pytest.lazy_fixture("private"), + lazy_fixture("private"), + lazy_fixture("private"), pytest.raises(substra.exceptions.AuthorizationError), ), - (pytest.lazy_fixture("organization_2_only"), pytest.lazy_fixture("private"), does_not_raise()), + (lazy_fixture("organization_2_only"), lazy_fixture("private"), does_not_raise()), ], ) def test_permissions_model_process( @@ -414,8 +416,8 @@ def test_permissions_denied_head_model_process(factory, client_1, client_2, chan @pytest.mark.parametrize( "permission_train_output, expectation", [ - (pytest.lazy_fixture("organization_1_only"), pytest.raises(substra.exceptions.AuthorizationError)), - (pytest.lazy_fixture("organization_2_only"), does_not_raise()), + (lazy_fixture("organization_1_only"), pytest.raises(substra.exceptions.AuthorizationError)), + (lazy_fixture("organization_2_only"), does_not_raise()), ], ) def test_permission_to_test_on_org_without_training(