8000 MAINT: Update some testing files from main · numpy/numpy@48515a3 · GitHub
[go: up one dir, main page]

Skip to content

Commit 48515a3

Browse files
committed
MAINT: Update some testing files from main
- Checkout numpy/testing/_private/utils.py - Checkout numpy/_core/tests/test_multithreading.py - Checkout conftest.py - Update test_requirements.txt
1 parent 96ca7e3 commit 48515a3

File tree

4 files changed

+91
-23
lines changed

4 files changed

+91
-23
lines changed

numpy/_core/tests/test_multithreading.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import concurrent.futures
12
import threading
3+
import string
24

35
import numpy as np
46
import pytest

numpy/conftest.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
Pytest configuration and fixtures for the Numpy test suite.
33
"""
44
import os
5+
import string
56
import sys
67
import tempfile
78
from contextlib import contextmanager
@@ -10,9 +11,11 @@
1011
import hypothesis
1112
import pytest
1213
import numpy
14+
import numpy as np
1315

1416
from numpy._core._multiarray_tests import get_fpu_mode
15-
from numpy.testing._private.utils import NOGIL_BUILD
17+
from numpy._core.tests._natype import pd_NA
18+
from numpy.testing._private.utils import NOGIL_BUILD, get_stringdtype_dtype
1619

1720
try:
1821
from scipy_doctest.conftest import dt_config
@@ -204,12 +207,12 @@ def warnings_errors_and_rng(test=None):
204207
dt_config.check_namespace['StringDType'] = numpy.dtypes.StringDType
205208

206209
# temporary skips
207-
dt_config.skiplist = set([
210+
dt_config.skiplist = {
208211
'numpy.savez', # unclosed file
209212
'numpy.matlib.savez',
210213
'numpy.__array_namespace_info__',
211214
'numpy.matlib.__array_namespace_info__',
212-
])
215+
}
213216

214217
# xfail problematic tutorials
215218
dt_config.pytest_extra_xfail = {
@@ -231,3 +234,28 @@ def warnings_errors_and_rng(test=None):
231234
'numpy/f2py/_backends/_distutils.py',
232235
]
233236

237+
238+
@pytest.fixture
239+
def random_string_list():
240+
chars = list(string.ascii_letters + string.digits)
241+
chars = np.array(chars, dtype="U1")
242+
ret = np.random.choice(chars, size=100 * 10, replace=True)
243+
return ret.view("U100")
244+
245+
246+
@pytest.fixture(params=[True, False])
247+
def coerce(request):
248+
return request.param
249+
250+
251+
@pytest.fixture(
252+
params=["unset", None, pd_NA, np.nan, float("nan"), "__nan__"],
253+
ids=["unset", "None", "pandas.NA", "np.nan", "float('nan')", "string nan"],
254+
)
255+
def na_object(request):
256+
return request.param
257+
258+
259+
@pytest.fixture()
260+
def dtype(na_object, coerce):
261+
return get_stringdtype_dtype(na_object, coerce)

numpy/testing/_private/utils.py

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"""
55
import os
66
import sys
7+
import pathlib
78
import platform
89
import re
910
import gc
@@ -19,16 +20,19 @@
1920
import sysconfig
2021
import concurrent.futures
2122
import threading
23+
import importlib.metadata
2224

2325
import numpy as np
2426
from numpy._core import (
2527
intp, float32, empty, arange, array_repr, ndarray, isnat, array)
2628
from numpy import isfinite, isnan, isinf
2729
import numpy.linalg._umath_linalg
2830
from numpy._utils import _rename_parameter
31+
from numpy._core.tests._natype import pd_NA
2932

3033
from io import StringIO
3134

35+
3236
__all__ = [
3337
'assert_equal', 'assert_almost_equal', 'assert_approx_equal',
3438
'assert_array_equal', 'assert_array_less', 'assert_string_equal',
@@ -42,7 +46,7 @@
4246
'HAS_REFCOUNT', "IS_WASM", 'suppress_warnings', 'assert_array_compare',
4347
'assert_no_gc_cycles', 'break_cycles', 'HAS_LAPACK64', 'IS_PYSTON',
4448
'IS_MUSL', 'check_support_sve', 'NOGIL_BUILD',
45-
'IS_EDITABLE', 'run_threaded',
49+
'IS_EDITABLE', 'IS_INSTALLED', 'NUMPY_ROOT', 'run_threaded',
4650
]
4751

4852

@@ -54,10 +58,40 @@ class KnownFailureException(Exception):
5458
KnownFailureTest = KnownFailureException # backwards compat
5559
verbose = 0
5660

61+
NUMPY_ROOT = pathlib.Path(np.__file__).parent
62+
63+
try:
64+
np_dist = importlib.metadata.distribution('numpy')
65+
except importlib.metadata.PackageNotFoundError:
66+
IS_INSTALLED = IS_EDITABLE = False
67+
else:
68+
IS_INSTALLED = True
69+
try:
70+
if sys.version_info >= (3, 13):
71+
IS_EDITABLE = np_dist.origin.dir_info.editable
72+
else:
73+
# Backport importlib.metadata.Distribution.origin
74+
import json, types # noqa: E401
75+
origin = json.loads(
76+
np_dist.read_text('direct_url.json') or '{}',
77+
object_hook=lambda data: types.SimpleNamespace(**data),
78+
)
79+
IS_EDITABLE = origin.dir_info.editable
80+
except AttributeError:
81+
IS_EDITABLE = False
82+
83 10000 +
# spin installs numpy directly via meson, instead of using meson-python, and
84+
# runs the module by setting PYTHONPATH. This is problematic because the
85+
# resulting installation lacks the Python metadata (.dist-info), and numpy
86+
# might already be installed on the environment, causing us to find its
87+
# metadata, even though we are not actually loading that package.
88+
# Work around this issue by checking if the numpy root matches.
89+
if not IS_EDITABLE and np_dist.locate_file('numpy') != NUMPY_ROOT:
90+
IS_INSTALLED = False
91+
5792
IS_WASM = platform.machine() in ["wasm32", "wasm64"]
5893
IS_PYPY = sys.implementation.name == 'pypy'
5994
IS_PYSTON = hasattr(sys, "pyston_version_info")
60-
IS_EDITABLE = not bool(np.__path__) or 'editable' in np.__path__[0]
6195
HAS_REFCOUNT = getattr(sys, 'getrefcount', None) is not None and not IS_PYSTON
6296
HAS_LAPACK64 = numpy.linalg._umath_linalg._ilp64
6397

@@ -101,14 +135,15 @@ def GetPerformanceAttributes(object, counter, instance=None,
101135
# thread's CPU usage is either 0 or 100). To read counters like this,
102136
# you should copy this function, but keep the counter open, and call
103137
# CollectQueryData() each time you need to know.
104-
# See http://msdn.microsoft.com/library/en-us/dnperfmo/html/perfmonpt2.asp (dead link)
138+
# See http://msdn.microsoft.com/library/en-us/dnperfmo/html/perfmonpt2.asp
139+
#(dead link)
105140
# My older explanation for this was that the "AddCounter" process
106141
# forced the CPU to 100%, but the above makes more sense :)
107142
import win32pdh
108143
if format is None:
109144
format = win32pdh.PDH_FMT_LONG
110-
path = win32pdh.MakeCounterPath( (machine, object, instance, None,
111-
inum, counter))
145+
path = win32pdh.MakeCounterPath((machine, object, instance, None,
146+
inum, counter))
112147
hq = win32pdh.OpenQuery()
113148
try:
114149
hc = win32pdh.AddCounter(hq, path)
@@ -166,7 +201,7 @@ def jiffies(_proc_pid_stat=f'/proc/{os.getpid()}/stat', _load_time=[]):
166201
l = f.readline().split(' ')
167202
return int(l[13])
168203
except Exception:
169-
return int(100*(time.time()-_load_time[0]))
204+
return int(100 * (time.time() - _load_time[0]))
170205
else:
171206
# os.getpid is not in all platforms available.
172207
# Using time is safe but inaccurate, especially when process
@@ -182,15 +217,15 @@ def jiffies(_load_time=[]):
182217
import time
183218
if not _load_time:
184219
_load_time.append(time.time())
185-
return int(100*(time.time()-_load_time[0]))
220+
return int(100 * (time.time() - _load_time[0]))
186221

187222

188223
def build_err_msg(arrays, err_msg, header='Items are not equal:',
189224
verbose=True, names=('ACTUAL', 'DESIRED'), precision=8):
190225
msg = ['\n' + header]
191226
err_msg = str(err_msg)
192227
if err_msg:
193-
if err_msg.find('\n') == -1 and len(err_msg) < 79-len(header):
228+
if err_msg.find('\n') == -1 and len(err_msg) < 79 - len(header):
194229
msg = [msg[0] + ' ' + err_msg]
195230
else:
196231
msg.append(err_msg)
@@ -659,14 +694,14 @@ def assert_approx_equal(actual, desired, significant=7, err_msg='',
659694
# Normalized the numbers to be in range (-10.0,10.0)
660695
# scale = float(pow(10,math.floor(math.log10(0.5*(abs(desired)+abs(actual))))))
661696
with np.errstate(invalid='ignore'):
662-
scale = 0.5*(np.abs(desired) + np.abs(actual))
697+
scale = 0.5 * (np.abs(desired) + np.abs(actual))
663698
scale = np.power(10, np.floor(np.log10(scale)))
664699
try:
665-
sc_desired = desired/scale
700+
sc_desired = desired / scale
666701
except ZeroDivisionError:
667702
sc_desired = 0.0
668703
try:
669-
sc_actual = actual/scale
704+
sc_actual = actual / scale
670705
except ZeroDivisionError:
671706
sc_actual = 0.0
672707
msg = build_err_msg(
@@ -687,7 +722,7 @@ def assert_approx_equal(actual, desired, significant=7, err_msg='',
687722
return
688723
except (TypeError, NotImplementedError):
689724
pass
690-
if np.abs(sc_desired - sc_actual) >= np.power(10., -(significant-1)):
725+
if np.abs(sc_desired - sc_actual) >= np.power(10., -(significant - 1)):
691726
raise AssertionError(msg)
692727

693728

@@ -1379,10 +1414,10 @@ def check_support_sve(__cache=[]):
13791414
"""
13801415
gh-22982
13811416
"""
1382-
1417+
13831418
if __cache:
13841419
return __cache[0]
1385-
1420+
13861421
import subprocess
13871422
cmd = 'lscpu'
13881423
try:
@@ -1543,7 +1578,7 @@ def measure(code_str, times=1, label=None):
15431578
i += 1
15441579
exec(code, globs, locs)
15451580
elapsed = jiffies() - elapsed
1546-
return 0.01*elapsed
1581+
return 0.01 * elapsed
15471582

15481583

15491584
def _assert_valid_refcount(op):
@@ -1557,7 +1592,7 @@ def _assert_valid_refcount(op):
15571592
import gc
15581593
import numpy as np
15591594

1560-
b = np.arange(100*100).reshape(100, 100)
1595+
b = np.arange(100 * 100).reshape(100, 100)
15611596
c = b
15621597
i = 1
15631598

@@ -1735,7 +1770,7 @@ def assert_array_almost_equal_nulp(x, y, nulp=1):
17351770
ax = np.abs(x)
17361771
ay = np.abs(y)
17371772
ref = nulp * np.spacing(np.where(ax > ay, ax, ay))
1738-
if not np.all(np.abs(x-y) <= ref):
1773+
if not np.all(np.abs(x - y) <= ref):
17391774
if np.iscomplexobj(x) or np.iscomplexobj(y):
17401775
msg = f"Arrays are not equal to {nulp} ULP"
17411776
else:
@@ -1851,7 +1886,7 @@ def nulp_diff(x, y, dtype=None):
18511886
(x.shape, y.shape))
18521887

18531888
def _diff(rx, ry, vdt):
1854-
diff = np.asarray(rx-ry, dtype=vdt)
1889+
diff = np.asarray(rx - ry, dtype=vdt)
18551890
return np.abs(diff)
18561891

18571892
rx = integer_repr(x)
@@ -2596,7 +2631,7 @@ def check_free_memory(free_bytes):
25962631
except ValueError as exc:
25972632
raise ValueError(f'Invalid environment variable {env_var}: {exc}')
25982633

2599-
msg = (f'{free_bytes/1e9} GB memory required, but environment variable '
2634+
msg = (f'{free_bytes / 1e9} GB memory required, but environment variable '
26002635
f'NPY_AVAILABLE_MEM={env_value} set')
26012636
else:
26022637
mem_free = _get_mem_available()
@@ -2607,7 +2642,9 @@ def check_free_memory(free_bytes):
26072642
"the test.")
26082643
mem_free = -1
26092644
else:
2610-
msg = f'{free_bytes/1e9} GB memory required, but {mem_free/1e9} GB available'
2645+
free_bytes_gb = free_bytes / 1e9
2646+
mem_free_gb = mem_free / 1e9
2647+
msg = f'{free_bytes_gb} GB memory required, but {mem_free_gb} GB available'
26112648

26122649
return msg if mem_free < free_bytes else None
26132650

requirements/test_requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pytest-cov==4.1.0
99
meson
1010
ninja; sys_platform != "emscripten"
1111
pytest-xdist
12+
pytest-timeout
1213
# for numpy.random.test.test_extending
1314
cffi; python_version < '3.10'
1415
# For testing types. Notes on the restrictions:

0 commit comments

Comments
 (0)
0