From 605c177a32bc4a7e4ec78f72bde5a381ebde93ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= Date: Fri, 29 Mar 2024 15:40:31 +0100 Subject: [PATCH 1/2] Ensure that type imports come from _pytest The types have only been recently exposed via the main pytest namespace and older pytest release do not yet support it. This fixes https://github.com/dcermak/pytest_container/issues/202 --- pytest_container/container.py | 34 +++++++++++++++++----------------- pytest_container/plugin.py | 15 ++++++++------- pytest_container/runtime.py | 4 ++-- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/pytest_container/container.py b/pytest_container/container.py index 9ab7f2d..58e0726 100644 --- a/pytest_container/container.py +++ b/pytest_container/container.py @@ -40,11 +40,13 @@ from uuid import uuid4 import deprecation -import pytest import testinfra +from _pytest.mark import Mark +from _pytest.mark import MarkDecorator from _pytest.mark import ParameterSet from filelock import BaseFileLock from filelock import FileLock +from pytest import param from pytest_container.helpers import get_always_pull_option from pytest_container.inspect import ContainerHealth from pytest_container.inspect import ContainerInspect @@ -896,9 +898,7 @@ def inspect(self) -> ContainerInspect: def container_to_pytest_param( container: ContainerBase, - marks: Optional[ - Union[Collection[pytest.MarkDecorator], pytest.MarkDecorator] - ] = None, + marks: Optional[Union[Collection[MarkDecorator], MarkDecorator]] = None, ) -> ParameterSet: """Converts a subclass of :py:class:`~pytest_container.container.ContainerBase` (:py:class:`~pytest_container.container.Container` or @@ -911,38 +911,38 @@ def container_to_pytest_param( :py:attr:`~pytest_container.container.ContainerBase.container_id`) """ - return pytest.param(container, marks=marks or [], id=str(container)) + return param(container, marks=marks or [], id=str(container)) @overload def container_and_marks_from_pytest_param( - param: Container, + ctr_or_param: Container, ) -> Tuple[Container, Literal[None]]: ... @overload def container_and_marks_from_pytest_param( - param: DerivedContainer, + ctr_or_param: DerivedContainer, ) -> Tuple[DerivedContainer, Literal[None]]: ... @overload def container_and_marks_from_pytest_param( - param: ParameterSet, + ctr_or_param: ParameterSet, ) -> Tuple[ Union[Container, DerivedContainer], - Optional[Collection[Union[pytest.MarkDecorator, pytest.Mark]]], + Optional[Collection[Union[MarkDecorator, Mark]]], ]: ... def container_and_marks_from_pytest_param( - param: Union[ParameterSet, Container, DerivedContainer], + ctr_or_param: Union[ParameterSet, Container, DerivedContainer], ) -> Tuple[ Union[Container, DerivedContainer], - Optional[Collection[Union[pytest.MarkDecorator, pytest.Mark]]], + Optional[Collection[Union[MarkDecorator, Mark]]], ]: """Extracts the :py:class:`~pytest_container.container.Container` or :py:class:`~pytest_container.container.DerivedContainer` and the @@ -955,15 +955,15 @@ def container_and_marks_from_pytest_param( returned directly and the second return value is ``None``. """ - if isinstance(param, (Container, DerivedContainer)): - return param, None + if isinstance(ctr_or_param, (Container, DerivedContainer)): + return ctr_or_param, None - if len(param.values) > 0 and isinstance( - param.values[0], (Container, DerivedContainer) + if len(ctr_or_param.values) > 0 and isinstance( + ctr_or_param.values[0], (Container, DerivedContainer) ): - return param.values[0], param.marks + return ctr_or_param.values[0], ctr_or_param.marks - raise ValueError(f"Invalid pytest.param values: {param.values}") + raise ValueError(f"Invalid pytest.param values: {ctr_or_param.values}") @deprecation.deprecated( diff --git a/pytest_container/plugin.py b/pytest_container/plugin.py index ef2775b..47e947f 100644 --- a/pytest_container/plugin.py +++ b/pytest_container/plugin.py @@ -26,12 +26,13 @@ else: from typing_extensions import Literal -import pytest +from pytest import fixture +from pytest import skip from _pytest.config import Config from _pytest.fixtures import SubRequest -@pytest.fixture(scope="session") +@fixture(scope="session") def container_runtime() -> OciRuntimeBase: """pytest fixture that returns the currently selected container runtime according to the rules outlined :ref:`here `. @@ -63,7 +64,7 @@ def _create_auto_container_fixture( ) -> Callable[ [SubRequest, OciRuntimeBase, Config], Generator[ContainerData, None, None] ]: - def fixture( + def fixture_funct( request: SubRequest, # we must call this parameter container runtime, so that pytest will # treat it as a fixture, but that causes pylint to complain… @@ -125,7 +126,7 @@ def fixture( launcher._container_id, container_runtime ) - return pytest.fixture(scope=scope)(fixture) + return fixture(scope=scope)(fixture_funct) def _create_auto_pod_fixture( @@ -133,7 +134,7 @@ def _create_auto_pod_fixture( ) -> Callable[ [SubRequest, OciRuntimeBase, Config], Generator[PodData, None, None] ]: - def fixture( + def fixture_funct( request: SubRequest, # we must call this parameter container runtime, so that pytest will # treat it as a fixture, but that causes pylint to complain… @@ -142,7 +143,7 @@ def fixture( pytestconfig: Config, ) -> Generator[PodData, None, None]: if "podman" not in container_runtime.runner_binary: - pytest.skip("Pods are only supported in podman") + skip("Pods are only supported in podman") pod = pod_from_pytest_param(request.param) with PodLauncher( @@ -163,7 +164,7 @@ def fixture( ctr_launcher._container_id, container_runtime ) - return pytest.fixture(scope=scope)(fixture) + return fixture(scope=scope)(fixture_funct) #: This fixture parametrizes the test function once for each container image diff --git a/pytest_container/runtime.py b/pytest_container/runtime.py index 668fc68..338fdf1 100644 --- a/pytest_container/runtime.py +++ b/pytest_container/runtime.py @@ -19,9 +19,9 @@ from typing import TYPE_CHECKING from typing import Union -import pytest import testinfra from _pytest.mark.structures import ParameterSet +from pytest import param from pytest_container.inspect import BindMount from pytest_container.inspect import Config from pytest_container.inspect import ContainerHealth @@ -65,7 +65,7 @@ class ToParamMixin: def to_pytest_param(self) -> ParameterSet: """Convert this class into a ``pytest.param``""" - return pytest.param(self, id=str(self), marks=self.marks or ()) + return param(self, id=str(self), marks=self.marks or ()) @dataclass(frozen=True) From 9f14b090d9beae9a5cc7b85f38bfea959a99a77b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= Date: Fri, 29 Mar 2024 15:44:40 +0100 Subject: [PATCH 2/2] Bump version to 0.4.1 --- CHANGELOG.rst | 17 +++++++++++++++++ pyproject.toml | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 95b4e1a..534ec91 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -13,6 +13,23 @@ Documentation: Internal changes: +0.4.1 (2 April 2024) +-------------------- + +Breaking changes: + + +Improvements and new features: + + +Documentation: + + +Internal changes: + +- fix imports for older pytest releases + + 0.4.0 (27 March 2024) --------------------- diff --git a/pyproject.toml b/pyproject.toml index 458b817..f7dddc0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pytest_container" -version = "0.4.0" +version = "0.4.1" description = "Pytest fixtures for writing container based tests" authors = ["Dan Čermák "] homepage = "https://dcermak.github.io/pytest_container/"