|
7 | 7 | from __future__ import annotations
|
8 | 8 |
|
9 | 9 | import dataclasses
|
| 10 | +import os |
| 11 | +import re |
10 | 12 | from importlib.util import find_spec
|
11 | 13 | from typing import TYPE_CHECKING, cast
|
12 | 14 |
|
@@ -93,8 +95,8 @@ def _skip_if_unimportable(array_type: ArrayType) -> pytest.MarkDecorator:
|
93 | 95 | ]
|
94 | 96 |
|
95 | 97 |
|
96 |
| -@pytest.fixture(params=SUPPORTED_TYPE_PARAMS) |
97 |
| -def array_type(request: pytest.FixtureRequest, tmp_path: Path) -> Generator[ArrayType, None, None]: |
| 98 | +@pytest.fixture(scope="session", params=SUPPORTED_TYPE_PARAMS) |
| 99 | +def array_type(request: pytest.FixtureRequest) -> ArrayType: |
98 | 100 | """Fixture for a supported :class:`~testing.fast_array_utils.ArrayType`.
|
99 | 101 |
|
100 | 102 | Use :class:`testing.fast_array_utils.Flags` to select or skip array types:
|
@@ -131,13 +133,42 @@ def test_something(array_type: ArrayType) -> None:
|
131 | 133 | ...
|
132 | 134 | """
|
133 | 135 | at = cast("ArrayType", request.param)
|
134 |
| - f: h5py.File | None = None |
135 | 136 | if at.cls is types.H5Dataset or (at.inner and at.inner.cls is types.H5Dataset):
|
| 137 | + at = dataclasses.replace(at, conversion_context=CC(request)) |
| 138 | + return at |
| 139 | + |
| 140 | + |
| 141 | +try: # get the exception type |
| 142 | + pytest.fail("x") |
| 143 | +except BaseException as e: # noqa: BLE001 |
| 144 | + Failed = type(e) |
| 145 | +else: |
| 146 | + raise AssertionError |
| 147 | + |
| 148 | + |
| 149 | +class CC(ConversionContext): |
| 150 | + def __init__(self, request: pytest.FixtureRequest) -> None: |
| 151 | + self._request = request |
| 152 | + |
| 153 | + @property # This is intentionally not cached and creates a new file on each access |
| 154 | + def hdf5_file(self) -> h5py.File: # type: ignore[override] |
136 | 155 | import h5py
|
137 | 156 |
|
138 |
| - f = h5py.File(tmp_path / f"{request.fixturename}.h5", "w") |
139 |
| - ctx = ConversionContext(hdf5_file=f) |
140 |
| - at = dataclasses.replace(at, conversion_context=ctx) |
141 |
| - yield at |
142 |
| - if f: |
143 |
| - f.close() |
| 157 | + try: # If we’re being called in a test or function-scoped fixture, use the test `tmp_path` |
| 158 | + return cast("h5py.File", self._request.getfixturevalue("tmp_hdf5_file")) |
| 159 | + except Failed: # We’re being called from a session-scoped fixture or so |
| 160 | + factory = cast( |
| 161 | + "pytest.TempPathFactory", self._request.getfixturevalue("tmp_path_factory") |
| 162 | + ) |
| 163 | + name = re.sub(r"[^\w_. -()\[\]{}]", "_", os.environ["PYTEST_CURRENT_TEST"]) |
| 164 | + f = h5py.File(factory.mktemp(name) / "test.h5", "w") |
| 165 | + self._request.addfinalizer(f.close) |
| 166 | + return f |
| 167 | + |
| 168 | + |
| 169 | +@pytest.fixture |
| 170 | +def tmp_hdf5_file(tmp_path: Path) -> Generator[h5py.File, None, None]: |
| 171 | + import h5py |
| 172 | + |
| 173 | + with h5py.File(tmp_path / "test.h5", "w") as f: |
| 174 | + yield f |
0 commit comments