Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MAINT: Deal with pytest 8.0 #12376

Merged
merged 10 commits into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/changes/devel/12376.dependency.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
For developers, ``pytest>=8.0`` is now required for running unit tests, by `Eric Larson`_.
2 changes: 1 addition & 1 deletion environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ dependencies:
- pip
- numpy
- scipy
- openblas!=0.3.26 # until https://github.com/conda-forge/scipy-feedstock/pull/268 lands
- openblas
- matplotlib
- tqdm
- pooch>=1.5
Expand Down
7 changes: 4 additions & 3 deletions mne/_fiff/tests/test_meas_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,9 +350,10 @@ def test_read_write_info(tmp_path):
@testing.requires_testing_data
def test_dir_warning():
"""Test that trying to read a bad filename emits a warning before an error."""
with pytest.raises(OSError, match="directory"):
with pytest.warns(RuntimeWarning, match="foo"):
read_info(ctf_fname)
with pytest.raises(OSError, match="directory"), pytest.warns(
RuntimeWarning, match="does not conform"
):
read_info(ctf_fname)


def test_io_dig_points(tmp_path):
Expand Down
27 changes: 14 additions & 13 deletions mne/beamformer/tests/test_lcmv.py
Original file line number Diff line number Diff line change
Expand Up @@ -589,19 +589,20 @@ def test_make_lcmv_sphere(pick_ori, weight_norm):
fwd_sphere = mne.make_forward_solution(evoked.info, None, src, sphere)

# Test that we get an error if not reducing rank
with pytest.raises(ValueError, match="Singular matrix detected"):
with pytest.warns(RuntimeWarning, match="positive semidefinite"):
make_lcmv(
evoked.info,
fwd_sphere,
data_cov,
reg=0.1,
noise_cov=noise_cov,
weight_norm=weight_norm,
pick_ori=pick_ori,
reduce_rank=False,
rank="full",
)
with pytest.raises(
ValueError, match="Singular matrix detected"
), _record_warnings(), pytest.warns(RuntimeWarning, match="positive semidefinite"):
make_lcmv(
evoked.info,
fwd_sphere,
data_cov,
reg=0.1,
noise_cov=noise_cov,
weight_norm=weight_norm,
pick_ori=pick_ori,
reduce_rank=False,
rank="full",
)

# Now let's reduce it
filters = make_lcmv(
Expand Down
5 changes: 4 additions & 1 deletion mne/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
_assert_no_instances,
_check_qt_version,
_pl,
_record_warnings,
_TempDir,
numerics,
)
Expand Down Expand Up @@ -801,7 +802,9 @@ def src_volume_labels():
"""Create a 7mm source space with labels."""
pytest.importorskip("nibabel")
volume_labels = mne.get_volume_labels_from_aseg(fname_aseg)
with pytest.warns(RuntimeWarning, match="Found no usable.*t-vessel.*"):
with _record_warnings(), pytest.warns(
RuntimeWarning, match="Found no usable.*t-vessel.*"
):
src = mne.setup_volume_source_space(
"sample",
7.0,
Expand Down
8 changes: 6 additions & 2 deletions mne/export/tests/test_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ def test_export_raw_pybv(tmp_path, meas_date, orig_time, ext):
raw.set_annotations(annots)

temp_fname = tmp_path / ("test" + ext)
with pytest.warns(RuntimeWarning, match="'short' format. Converting"):
with _record_warnings(), pytest.warns(
RuntimeWarning, match="'short' format. Converting"
):
raw.export(temp_fname)
raw_read = read_raw_brainvision(str(temp_fname).replace(".eeg", ".vhdr"))
assert raw.ch_names == raw_read.ch_names
Expand Down Expand Up @@ -301,7 +303,9 @@ def test_export_edf_signal_clipping(tmp_path, physical_range, exceeded_bound):
raw = read_raw_fif(fname_raw)
raw.pick(picks=["eeg", "ecog", "seeg"]).load_data()
temp_fname = tmp_path / "test.edf"
with pytest.warns(RuntimeWarning, match=f"The {exceeded_bound}"):
with _record_warnings(), pytest.warns(
RuntimeWarning, match=f"The {exceeded_bound}"
):
raw.export(temp_fname, physical_range=physical_range)
raw_read = read_raw_edf(temp_fname, preload=True)
assert raw_read.get_data().min() >= physical_range[0]
Expand Down
11 changes: 7 additions & 4 deletions mne/forward/tests/test_forward.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
)
from mne.io import read_info
from mne.label import read_label
from mne.utils import requires_mne, run_subprocess
from mne.utils import _record_warnings, requires_mne, run_subprocess

data_path = testing.data_path(download=False)
fname_meeg = data_path / "MEG" / "sample" / "sample_audvis_trunc-meg-eeg-oct-4-fwd.fif"
Expand Down Expand Up @@ -230,7 +230,9 @@ def test_apply_forward():
# Evoked
evoked = read_evokeds(fname_evoked, condition=0)
evoked.pick(picks="meg")
with pytest.warns(RuntimeWarning, match="only .* positive values"):
with _record_warnings(), pytest.warns(
RuntimeWarning, match="only .* positive values"
):
evoked = apply_forward(fwd, stc, evoked.info, start=start, stop=stop)
data = evoked.data
times = evoked.times
Expand All @@ -248,13 +250,14 @@ def test_apply_forward():
stc.tmin,
stc.tstep,
)
with pytest.warns(RuntimeWarning, match="very large"):
large_ctx = pytest.warns(RuntimeWarning, match="very large")
with large_ctx:
evoked_2 = apply_forward(fwd, stc_vec, evoked.info)
assert np.abs(evoked_2.data).mean() > 1e-5
assert_allclose(evoked.data, evoked_2.data, atol=1e-10)

# Raw
with pytest.warns(RuntimeWarning, match="only .* positive values"):
with large_ctx, pytest.warns(RuntimeWarning, match="only .* positive values"):
raw_proj = apply_forward_raw(fwd, stc, evoked.info, start=start, stop=stop)
data, times = raw_proj[:, :]

Expand Down
3 changes: 2 additions & 1 deletion mne/forward/tests/test_make_forward.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
from mne.surface import _get_ico_surface
from mne.transforms import Transform
from mne.utils import (
_record_warnings,
catch_logging,
requires_mne,
requires_mne_mark,
Expand Down Expand Up @@ -198,7 +199,7 @@ def test_magnetic_dipole():
r0 = coils[0]["rmag"][[0]]
with pytest.raises(RuntimeError, match="Coil too close"):
_magnetic_dipole_field_vec(r0, coils[:1])
with pytest.warns(RuntimeWarning, match="Coil too close"):
with _record_warnings(), pytest.warns(RuntimeWarning, match="Coil too close"):
fwd = _magnetic_dipole_field_vec(r0, coils[:1], too_close="warning")
assert not np.isfinite(fwd).any()
with np.errstate(invalid="ignore"):
Expand Down
4 changes: 3 additions & 1 deletion mne/io/artemis123/tests/test_artemis123.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ def test_dev_head_t():
assert_equal(raw.info["sfreq"], 5000.0)

# test with head loc and digitization
with pytest.warns(RuntimeWarning, match="Large difference"):
with pytest.warns(RuntimeWarning, match="consistency"), pytest.warns(
RuntimeWarning, match="Large difference"
):
raw = read_raw_artemis123(
short_HPI_dip_fname, add_head_trans=True, pos_fname=dig_fname
)
Expand Down
14 changes: 8 additions & 6 deletions mne/io/brainvision/brainvision.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,9 +344,10 @@ def _read_annotations_brainvision(fname, sfreq="auto"):

def _check_bv_version(header, kind):
"""Check the header version."""
_data_err = """\
MNE-Python currently only supports %s versions 1.0 and 2.0, got unparsable\
%r. Contact MNE-Python developers for support."""
_data_err = (
"MNE-Python currently only supports %s versions 1.0 and 2.0, got unparsable "
"%r. Contact MNE-Python developers for support."
)
# optional space, optional Core or V-Amp, optional Exchange,
# Version/Header, optional comma, 1/2
_data_re = (
Expand All @@ -355,14 +356,15 @@ def _check_bv_version(header, kind):

assert kind in ("header", "marker")

if header == "":
warn(f"Missing header in {kind} file.")
for version in range(1, 3):
this_re = _data_re % (kind.capitalize(), version)
if re.search(this_re, header) is not None:
return version
else:
warn(_data_err % (kind, header))
if header == "":
warn(f"Missing header in {kind} file.")
else:
warn(_data_err % (kind, header))


_orientation_dict = dict(MULTIPLEXED="F", VECTORIZED="C")
Expand Down
14 changes: 9 additions & 5 deletions mne/io/brainvision/tests/test_brainvision.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from mne.datasets import testing
from mne.io import read_raw_brainvision, read_raw_fif
from mne.io.tests.test_raw import _test_raw_reader
from mne.utils import _stamp_to_dt, object_diff
from mne.utils import _record_warnings, _stamp_to_dt, object_diff

data_dir = Path(__file__).parent / "data"
vhdr_path = data_dir / "test.vhdr"
Expand Down Expand Up @@ -72,6 +72,8 @@
# This should be amend in its own PR.
montage = data_dir / "test.hpts"

_no_dig = pytest.warns(RuntimeWarning, match="No info on DataPoints")


def test_orig_units(recwarn):
"""Test exposure of original channel units."""
Expand Down Expand Up @@ -473,7 +475,7 @@ def test_brainvision_data_partially_disabled_hw_filters():

def test_brainvision_data_software_filters_latin1_global_units():
"""Test reading raw Brain Vision files."""
with pytest.warns(RuntimeWarning, match="software filter"):
with _no_dig, pytest.warns(RuntimeWarning, match="software filter"):
raw = _test_raw_reader(
read_raw_brainvision,
vhdr_fname=vhdr_old_path,
Expand All @@ -485,7 +487,7 @@ def test_brainvision_data_software_filters_latin1_global_units():
assert raw.info["lowpass"] == 50.0

# test sensor name with spaces (#9299)
with pytest.warns(RuntimeWarning, match="software filter"):
with _no_dig, pytest.warns(RuntimeWarning, match="software filter"):
raw = _test_raw_reader(
read_raw_brainvision,
vhdr_fname=vhdr_old_longname_path,
Expand Down Expand Up @@ -566,7 +568,7 @@ def test_brainvision_data():

def test_brainvision_vectorized_data():
"""Test reading BrainVision data files with vectorized data."""
with pytest.warns(RuntimeWarning, match="software filter"):
with _no_dig, pytest.warns(RuntimeWarning, match="software filter"):
raw = read_raw_brainvision(vhdr_old_path, preload=True)

assert_array_equal(raw._data.shape, (29, 251))
Expand Down Expand Up @@ -611,7 +613,9 @@ def test_brainvision_vectorized_data():
def test_coodinates_extraction():
"""Test reading of [Coordinates] section if present."""
# vhdr 2 has a Coordinates section
with pytest.warns(RuntimeWarning, match="coordinate information"):
with _record_warnings(), pytest.warns(
RuntimeWarning, match="coordinate information"
):
raw = read_raw_brainvision(vhdr_v2_path)

# Basic check of extracted coordinates
Expand Down
11 changes: 7 additions & 4 deletions mne/io/cnt/tests/test_cnt.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@
fname_bad_spans = data_path / "CNT" / "test_CNT_events_mne_JWoess_clipped.cnt"


_no_parse = pytest.warns(RuntimeWarning, match="Could not parse")


@testing.requires_testing_data
def test_old_data():
"""Test reading raw cnt files."""
with pytest.warns(RuntimeWarning, match="number of bytes"):
with _no_parse, pytest.warns(RuntimeWarning, match="number of bytes"):
raw = _test_raw_reader(
read_raw_cnt, input_fname=fname, eog="auto", misc=["NA1", "LEFT_EAR"]
)
Expand Down Expand Up @@ -50,12 +53,12 @@ def test_new_data():
@testing.requires_testing_data
def test_auto_data():
"""Test reading raw cnt files with automatic header."""
with pytest.warns(RuntimeWarning):
with pytest.warns(RuntimeWarning, match="Omitted 6 annot"):
raw = read_raw_cnt(input_fname=fname_bad_spans)

assert raw.info["bads"] == ["F8"]

with pytest.warns(RuntimeWarning, match="number of bytes"):
with _no_parse, pytest.warns(RuntimeWarning, match="number of bytes"):
raw = _test_raw_reader(
read_raw_cnt, input_fname=fname, eog="auto", misc=["NA1", "LEFT_EAR"]
)
Expand All @@ -74,7 +77,7 @@ def test_auto_data():
@testing.requires_testing_data
def test_compare_events_and_annotations():
"""Test comparing annotations and events."""
with pytest.warns(RuntimeWarning, match="Could not parse meas date"):
with _no_parse, pytest.warns(RuntimeWarning, match="Could not define the num"):
raw = read_raw_cnt(fname)
events = np.array(
[[333, 0, 7], [1010, 0, 7], [1664, 0, 109], [2324, 0, 7], [2984, 0, 109]]
Expand Down
2 changes: 1 addition & 1 deletion mne/io/ctf/tests/test_ctf.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def test_read_ctf(tmp_path):
shutil.copytree(ctf_eeg_fname, ctf_no_hc_fname)
remove_base = op.join(ctf_no_hc_fname, op.basename(ctf_fname_catch[:-3]))
os.remove(remove_base + ".hc")
with pytest.warns(RuntimeWarning, match="MISC channel"):
with _record_warnings(), pytest.warns(RuntimeWarning, match="MISC channel"):
pytest.raises(RuntimeError, read_raw_ctf, ctf_no_hc_fname)
os.remove(remove_base + ".eeg")
shutil.copy(
Expand Down
3 changes: 2 additions & 1 deletion mne/io/edf/tests/test_edf.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
)
from mne.io.tests.test_raw import _test_raw_reader
from mne.tests.test_annotations import _assert_annotations_equal
from mne.utils import _record_warnings

td_mark = testing._pytest_mark()

Expand Down Expand Up @@ -408,7 +409,7 @@ def test_no_data_channels():
annot_2 = raw.annotations
_assert_annotations_equal(annot, annot_2)
# only annotations (should warn)
with pytest.warns(RuntimeWarning, match="read_annotations"):
with _record_warnings(), pytest.warns(RuntimeWarning, match="read_annotations"):
read_raw_edf(edf_annot_only)


Expand Down
2 changes: 1 addition & 1 deletion mne/io/edf/tests/test_gdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def test_gdf2_data():
@testing.requires_testing_data
def test_one_channel_gdf():
"""Test a one-channel GDF file."""
with pytest.warns(RuntimeWarning, match="different highpass"):
with pytest.warns(RuntimeWarning, match="contain different"):
ecg = read_raw_gdf(gdf_1ch_path, preload=True)
assert ecg["ECG"][0].shape == (1, 4500)
assert 150.0 == ecg.info["sfreq"]
Expand Down
12 changes: 7 additions & 5 deletions mne/io/eeglab/tests/test_eeglab.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from mne.io.eeglab._eeglab import _readmat
from mne.io.eeglab.eeglab import _dol_to_lod, _get_montage_information
from mne.io.tests.test_raw import _test_raw_reader
from mne.utils import Bunch, _check_pymatreader_installed
from mne.utils import Bunch, _check_pymatreader_installed, _record_warnings

base_dir = testing.data_path(download=False) / "EEGLAB"
raw_fname_mat = base_dir / "test_raw.set"
Expand Down Expand Up @@ -140,7 +140,9 @@ def test_io_set_raw_more(tmp_path):
shutil.copyfile(
base_dir / "test_raw.fdt", negative_latency_fname.with_suffix(".fdt")
)
with pytest.warns(RuntimeWarning, match="has a sample index of -1."):
with _record_warnings(), pytest.warns(
RuntimeWarning, match="has a sample index of -1."
):
read_raw_eeglab(input_fname=negative_latency_fname, preload=True)

# test negative event latencies
Expand All @@ -163,7 +165,7 @@ def test_io_set_raw_more(tmp_path):
oned_as="row",
)
with pytest.raises(ValueError, match="event sample index is negative"):
with pytest.warns(RuntimeWarning, match="has a sample index of -1."):
with _record_warnings():
read_raw_eeglab(input_fname=negative_latency_fname, preload=True)

# test overlapping events
Expand Down Expand Up @@ -350,9 +352,9 @@ def test_io_set_raw_more(tmp_path):
def test_io_set_epochs(fnames):
"""Test importing EEGLAB .set epochs files."""
epochs_fname, epochs_fname_onefile = fnames
with pytest.warns(RuntimeWarning, match="multiple events"):
with _record_warnings(), pytest.warns(RuntimeWarning, match="multiple events"):
epochs = read_epochs_eeglab(epochs_fname)
with pytest.warns(RuntimeWarning, match="multiple events"):
with _record_warnings(), pytest.warns(RuntimeWarning, match="multiple events"):
epochs2 = read_epochs_eeglab(epochs_fname_onefile)
# one warning for each read_epochs_eeglab because both files have epochs
# associated with multiple events
Expand Down
5 changes: 4 additions & 1 deletion mne/io/eyelink/tests/test_eyelink.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from mne.io import read_raw_eyelink
from mne.io.eyelink._utils import _adjust_times, _find_overlaps
from mne.io.tests.test_raw import _test_raw_reader
from mne.utils import _record_warnings

pd = pytest.importorskip("pandas")

Expand Down Expand Up @@ -255,7 +256,9 @@ def test_multi_block_misc_channels(fname, tmp_path):
out_file = tmp_path / "tmp_eyelink.asc"
_simulate_eye_tracking_data(fname, out_file)

with pytest.warns(RuntimeWarning, match="Raw eyegaze coordinates"):
with _record_warnings(), pytest.warns(
RuntimeWarning, match="Raw eyegaze coordinates"
):
raw = read_raw_eyelink(out_file, apply_offsets=True)

chs_in_file = [
Expand Down
Loading