summaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/numpy/conftest.py
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/numpy/conftest.py')
-rw-r--r--.venv/lib/python3.12/site-packages/numpy/conftest.py258
1 files changed, 258 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/numpy/conftest.py b/.venv/lib/python3.12/site-packages/numpy/conftest.py
new file mode 100644
index 0000000..fde4def
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/numpy/conftest.py
@@ -0,0 +1,258 @@
+"""
+Pytest configuration and fixtures for the Numpy test suite.
+"""
+import os
+import string
+import sys
+import tempfile
+import warnings
+from contextlib import contextmanager
+
+import hypothesis
+import pytest
+
+import numpy
+import numpy as np
+from numpy._core._multiarray_tests import get_fpu_mode
+from numpy._core.tests._natype import get_stringdtype_dtype, pd_NA
+from numpy.testing._private.utils import NOGIL_BUILD
+
+try:
+ from scipy_doctest.conftest import dt_config
+ HAVE_SCPDT = True
+except ModuleNotFoundError:
+ HAVE_SCPDT = False
+
+
+_old_fpu_mode = None
+_collect_results = {}
+
+# Use a known and persistent tmpdir for hypothesis' caches, which
+# can be automatically cleared by the OS or user.
+hypothesis.configuration.set_hypothesis_home_dir(
+ os.path.join(tempfile.gettempdir(), ".hypothesis")
+)
+
+# We register two custom profiles for Numpy - for details see
+# https://hypothesis.readthedocs.io/en/latest/settings.html
+# The first is designed for our own CI runs; the latter also
+# forces determinism and is designed for use via np.test()
+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),
+)
+# Note that the default profile is chosen based on the presence
+# of pytest.ini, but can be overridden by passing the
+# --hypothesis-profile=NAME argument to pytest.
+_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"
+)
+
+# The experimentalAPI is used in _umath_tests
+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."))
+
+
+gil_enabled_at_start = True
+if NOGIL_BUILD:
+ gil_enabled_at_start = sys._is_gil_enabled()
+
+
+def pytest_sessionstart(session):
+ available_mem = session.config.getoption('available_memory')
+ if available_mem is not None:
+ os.environ['NPY_AVAILABLE_MEM'] = available_mem
+
+
+def pytest_terminal_summary(terminalreporter, exitstatus, config):
+ if NOGIL_BUILD and not gil_enabled_at_start and sys._is_gil_enabled():
+ tr = terminalreporter
+ tr.ensure_newline()
+ tr.section("GIL re-enabled", sep="=", red=True, bold=True)
+ tr.line("The GIL was re-enabled at runtime during the tests.")
+ tr.line("This can happen with no test failures if the RuntimeWarning")
+ tr.line("raised by Python when this happens is filtered by a test.")
+ tr.line("")
+ tr.line("Please ensure all new C modules declare support for running")
+ tr.line("without the GIL. Any new tests that intentionally imports ")
+ tr.line("code that re-enables the GIL should do so in a subprocess.")
+ pytest.exit("GIL re-enabled during tests", returncode=1)
+
+# FIXME when yield tests are gone.
+@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(f"FPU precision mode changed from {old_mode:#x} to "
+ f"{new_mode:#x} during the test")
+
+ collect_result = _collect_results.get(request.node)
+ if collect_result is not None:
+ old_mode, new_mode = collect_result
+ raise AssertionError(f"FPU precision mode changed from {old_mode:#x} to "
+ f"{new_mode:#x} when collecting the test")
+
+
+@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')
+
+
+if HAVE_SCPDT:
+
+ @contextmanager
+ def warnings_errors_and_rng(test=None):
+ """Filter out the wall of DeprecationWarnings.
+ """
+ msgs = ["The numpy.linalg.linalg",
+ "The numpy.fft.helper",
+ "dep_util",
+ "pkg_resources",
+ "numpy.core.umath",
+ "msvccompiler",
+ "Deprecated call",
+ "numpy.core",
+ "Importing from numpy.matlib",
+ "This function is deprecated.", # random_integers
+ "Data type alias 'a'", # numpy.rec.fromfile
+ "Arrays of 2-dimensional vectors", # matlib.cross
+ "`in1d` is deprecated", ]
+ msg = "|".join(msgs)
+
+ msgs_r = [
+ "invalid value encountered",
+ "divide by zero encountered"
+ ]
+ msg_r = "|".join(msgs_r)
+
+ with warnings.catch_warnings():
+ warnings.filterwarnings(
+ 'ignore', category=DeprecationWarning, message=msg
+ )
+ warnings.filterwarnings(
+ 'ignore', category=RuntimeWarning, message=msg_r
+ )
+ yield
+
+ # find and check doctests under this context manager
+ dt_config.user_context_mgr = warnings_errors_and_rng
+
+ # numpy specific tweaks from refguide-check
+ dt_config.rndm_markers.add('#uninitialized')
+ dt_config.rndm_markers.add('# uninitialized')
+
+ # make the checker pick on mismatched dtypes
+ dt_config.strict_check = True
+
+ import doctest
+ dt_config.optionflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
+
+ # recognize the StringDType repr
+ dt_config.check_namespace['StringDType'] = numpy.dtypes.StringDType
+
+ # temporary skips
+ dt_config.skiplist = {
+ 'numpy.savez', # unclosed file
+ 'numpy.matlib.savez',
+ 'numpy.__array_namespace_info__',
+ 'numpy.matlib.__array_namespace_info__',
+ }
+
+ # xfail problematic tutorials
+ dt_config.pytest_extra_xfail = {
+ 'how-to-verify-bug.rst': '',
+ 'c-info.ufunc-tutorial.rst': '',
+ 'basics.interoperability.rst': 'needs pandas',
+ 'basics.dispatch.rst': 'errors out in /testing/overrides.py',
+ 'basics.subclassing.rst': '.. testcode:: admonitions not understood',
+ 'misc.rst': 'manipulates warnings',
+ }
+
+ # ignores are for things fail doctest collection (optionals etc)
+ dt_config.pytest_extra_ignore = [
+ 'numpy/distutils',
+ 'numpy/_core/cversions.py',
+ 'numpy/_pyinstaller',
+ 'numpy/random/_examples',
+ 'numpy/f2py/_backends/_distutils.py',
+ ]
+
+
+@pytest.fixture
+def random_string_list():
+ chars = list(string.ascii_letters + string.digits)
+ chars = np.array(chars, dtype="U1")
+ ret = np.random.choice(chars, size=100 * 10, replace=True)
+ return ret.view("U100")
+
+
+@pytest.fixture(params=[True, False])
+def coerce(request):
+ return request.param
+
+
+@pytest.fixture(
+ params=["unset", None, pd_NA, np.nan, float("nan"), "__nan__"],
+ ids=["unset", "None", "pandas.NA", "np.nan", "float('nan')", "string nan"],
+)
+def na_object(request):
+ return request.param
+
+
+@pytest.fixture()
+def dtype(na_object, coerce):
+ return get_stringdtype_dtype(na_object, coerce)