|
""" |
|
Pytest configuration and fixtures for the Numpy test suite. |
|
""" |
|
import os |
|
import tempfile |
|
|
|
import hypothesis |
|
import pytest |
|
import numpy |
|
|
|
from numpy.core._multiarray_tests import get_fpu_mode |
|
|
|
|
|
_old_fpu_mode = None |
|
_collect_results = {} |
|
|
|
|
|
|
|
hypothesis.configuration.set_hypothesis_home_dir( |
|
os.path.join(tempfile.gettempdir(), ".hypothesis") |
|
) |
|
|
|
|
|
|
|
|
|
|
|
hypothesis.settings.register_profile( |
|
name="numpy-profile", deadline=None, print_blob=True, |
|
) |
|
hypothesis.settings.register_profile( |
|
name="np.test() profile", |
|
deadline=None, print_blob=True, database=None, derandomize=True, |
|
suppress_health_check=list(hypothesis.HealthCheck), |
|
) |
|
|
|
|
|
|
|
_pytest_ini = os.path.join(os.path.dirname(__file__), "..", "pytest.ini") |
|
hypothesis.settings.load_profile( |
|
"numpy-profile" if os.path.isfile(_pytest_ini) else "np.test() profile" |
|
) |
|
|
|
|
|
os.environ["NUMPY_EXPERIMENTAL_DTYPE_API"] = "1" |
|
|
|
def pytest_configure(config): |
|
config.addinivalue_line("markers", |
|
"valgrind_error: Tests that are known to error under valgrind.") |
|
config.addinivalue_line("markers", |
|
"leaks_references: Tests that are known to leak references.") |
|
config.addinivalue_line("markers", |
|
"slow: Tests that are very slow.") |
|
config.addinivalue_line("markers", |
|
"slow_pypy: Tests that are very slow on pypy.") |
|
|
|
|
|
def pytest_addoption(parser): |
|
parser.addoption("--available-memory", action="store", default=None, |
|
help=("Set amount of memory available for running the " |
|
"test suite. This can result to tests requiring " |
|
"especially large amounts of memory to be skipped. " |
|
"Equivalent to setting environment variable " |
|
"NPY_AVAILABLE_MEM. Default: determined" |
|
"automatically.")) |
|
|
|
|
|
def pytest_sessionstart(session): |
|
available_mem = session.config.getoption('available_memory') |
|
if available_mem is not None: |
|
os.environ['NPY_AVAILABLE_MEM'] = available_mem |
|
|
|
|
|
|
|
@pytest.hookimpl() |
|
def pytest_itemcollected(item): |
|
""" |
|
Check FPU precision mode was not changed during test collection. |
|
|
|
The clumsy way we do it here is mainly necessary because numpy |
|
still uses yield tests, which can execute code at test collection |
|
time. |
|
""" |
|
global _old_fpu_mode |
|
|
|
mode = get_fpu_mode() |
|
|
|
if _old_fpu_mode is None: |
|
_old_fpu_mode = mode |
|
elif mode != _old_fpu_mode: |
|
_collect_results[item] = (_old_fpu_mode, mode) |
|
_old_fpu_mode = mode |
|
|
|
|
|
@pytest.fixture(scope="function", autouse=True) |
|
def check_fpu_mode(request): |
|
""" |
|
Check FPU precision mode was not changed during the test. |
|
""" |
|
old_mode = get_fpu_mode() |
|
yield |
|
new_mode = get_fpu_mode() |
|
|
|
if old_mode != new_mode: |
|
raise AssertionError("FPU precision mode changed from {0:#x} to {1:#x}" |
|
" during the test".format(old_mode, new_mode)) |
|
|
|
collect_result = _collect_results.get(request.node) |
|
if collect_result is not None: |
|
old_mode, new_mode = collect_result |
|
raise AssertionError("FPU precision mode changed from {0:#x} to {1:#x}" |
|
" when collecting the test".format(old_mode, |
|
new_mode)) |
|
|
|
|
|
@pytest.fixture(autouse=True) |
|
def add_np(doctest_namespace): |
|
doctest_namespace['np'] = numpy |
|
|
|
@pytest.fixture(autouse=True) |
|
def env_setup(monkeypatch): |
|
monkeypatch.setenv('PYTHONHASHSEED', '0') |
|
|
|
|
|
@pytest.fixture(params=[True, False]) |
|
def weak_promotion(request): |
|
""" |
|
Fixture to ensure "legacy" promotion state or change it to use the new |
|
weak promotion (plus warning). `old_promotion` should be used as a |
|
parameter in the function. |
|
""" |
|
state = numpy._get_promotion_state() |
|
if request.param: |
|
numpy._set_promotion_state("weak_and_warn") |
|
else: |
|
numpy._set_promotion_state("legacy") |
|
|
|
yield request.param |
|
numpy._set_promotion_state(state) |
|
|