diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4a80f5e55..82d0c7896 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -128,6 +128,7 @@ repos: - lxml # dep of `--txt-report`, `--cobertura-xml-report` & `--html-report` - pytest >= 8.4.0 - pytest_codspeed + - pytest-harvest >= 1.10.5 - Sphinx >= 5.3.0 - sphinxcontrib-spelling - types-psutil @@ -145,6 +146,7 @@ repos: - types-docutils - lxml # dep of `--txt-report`, `--cobertura-xml-report` & `--html-report` - pytest >= 8.4.0 + - pytest-harvest >= 1.10.5 - pytest_codspeed - Sphinx >= 5.3.0 - sphinxcontrib-spelling diff --git a/CHANGES/1270.feature.rst b/CHANGES/1270.feature.rst new file mode 100644 index 000000000..7d25bc4ee --- /dev/null +++ b/CHANGES/1270.feature.rst @@ -0,0 +1,2 @@ +Started using pytest-harvest for caching pickles instead of loading them from a file +-- by :user:`Vizonex` \ No newline at end of file diff --git a/requirements/pytest.txt b/requirements/pytest.txt index 82d3741ad..e7cfb056c 100644 --- a/requirements/pytest.txt +++ b/requirements/pytest.txt @@ -3,4 +3,5 @@ objgraph==3.6.2 pytest==8.4.2 pytest-codspeed==4.2.0 pytest-cov==6.1.0 -psutil==7.1.3 +psutil==7.1.1 +pytest-harvest==1.10.5 \ No newline at end of file diff --git a/tests/conftest.py b/tests/conftest.py index dfc1a6703..8e2410e47 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -9,6 +9,7 @@ from typing import Callable, Type, Union import pytest +from pytest_harvest import saved_fixture from multidict import ( CIMultiDict, @@ -16,6 +17,7 @@ MultiDictProxy, MultiMapping, MutableMultiMapping, + istr, ) C_EXT_MARK = pytest.mark.c_extension @@ -156,6 +158,33 @@ def multidict_getversion_callable( return multidict_module.getversion # type: ignore[no-any-return] +@pytest.fixture(scope="session", params=range(pickle.HIGHEST_PROTOCOL + 1), ids=str) +def pickle_protocol(request: pytest.FixtureRequest) -> int: + return request.param # type: ignore[no-any-return] + + +@pytest.fixture(scope="session") +@saved_fixture +def pickle_protocol_multidict( + pickle_protocol: int, + any_multidict_class: type[MultiDict[int]], +) -> tuple[bytes, type[MultiDict[int]]]: + return pickle.dumps( + any_multidict_class([("a", 1), ("a", 2)]), pickle_protocol + ), any_multidict_class + + +@pytest.fixture(scope="session") +@saved_fixture +def pickle_protocol_istr( + pickle_protocol: int, + case_insensitive_str_class: type[istr], +) -> tuple[bytes, type[istr]]: + return pickle.dumps( + case_insensitive_str_class("str"), pickle_protocol + ), case_insensitive_str_class + + def pytest_addoption( parser: pytest.Parser, pluginmanager: pytest.PytestPluginManager, @@ -206,10 +235,3 @@ def pytest_configure(config: pytest.Config) -> None: "markers", f"{C_EXT_MARK.name}: tests running against the C-extension implementation.", ) - - -def pytest_generate_tests(metafunc: pytest.Metafunc) -> None: - if "pickle_protocol" in metafunc.fixturenames: - metafunc.parametrize( - "pickle_protocol", list(range(pickle.HIGHEST_PROTOCOL + 1)), scope="session" - ) diff --git a/tests/test_pickle.py b/tests/test_pickle.py index e955d2f3f..77ce4ec14 100644 --- a/tests/test_pickle.py +++ b/tests/test_pickle.py @@ -1,14 +1,9 @@ import pickle from pathlib import Path -from typing import TYPE_CHECKING - import pytest from multidict import MultiDict, MultiDictProxy, istr -if TYPE_CHECKING: - from conftest import MultidictImplementation - here = Path(__file__).resolve().parent @@ -43,42 +38,21 @@ def test_pickle_istr( def test_load_from_file( - any_multidict_class: type[MultiDict[int]], - multidict_implementation: "MultidictImplementation", - pickle_protocol: int, + # any_multidict_class: type[MultiDict[int]], + # multidict_implementation: "MultidictImplementation", + # pickle_protocol: int, + pickle_protocol_multidict: tuple[bytes, type[MultiDict[int]]], ) -> None: - multidict_class_name = any_multidict_class.__name__ - pickle_file_basename = "-".join( - ( - multidict_class_name.lower(), - multidict_implementation.tag, - ) - ) + buf, any_multidict_class = pickle_protocol_multidict d = any_multidict_class([("a", 1), ("a", 2)]) - fname = f"{pickle_file_basename}.pickle.{pickle_protocol}" - p = here / fname - with p.open("rb") as f: - obj = pickle.load(f) + obj = pickle.loads(buf) assert d == obj assert isinstance(obj, any_multidict_class) -def test_load_istr_from_file( - case_insensitive_str_class: type[istr], - multidict_implementation: "MultidictImplementation", - pickle_protocol: int, -) -> None: - istr_class_name = case_insensitive_str_class.__name__ - pickle_file_basename = "-".join( - ( - istr_class_name.lower(), - multidict_implementation.tag, - ) - ) - s = case_insensitive_str_class("str") - fname = f"{pickle_file_basename}.pickle.{pickle_protocol}" - p = here / fname - with p.open("rb") as f: - obj = pickle.load(f) - assert s == obj - assert isinstance(obj, case_insensitive_str_class) +def test_load_istr_from_file(pickle_protocol_istr: tuple[bytes, type[istr]]) -> None: + buf, case_incasive_str = pickle_protocol_istr + d = case_incasive_str("str") + obj = pickle.loads(buf) + assert d == obj + assert isinstance(obj, case_incasive_str)