diff --git a/mne/_fiff/tests/test_meas_info.py b/mne/_fiff/tests/test_meas_info.py index 9038c71a382..3cf1f79cceb 100644 --- a/mne/_fiff/tests/test_meas_info.py +++ b/mne/_fiff/tests/test_meas_info.py @@ -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): diff --git a/mne/beamformer/tests/test_lcmv.py b/mne/beamformer/tests/test_lcmv.py index 15c1a2ba5eb..f6c7ef20492 100644 --- a/mne/beamformer/tests/test_lcmv.py +++ b/mne/beamformer/tests/test_lcmv.py @@ -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( diff --git a/mne/conftest.py b/mne/conftest.py index 42f1e26c1e7..4bab9dc1186 100644 --- a/mne/conftest.py +++ b/mne/conftest.py @@ -32,6 +32,7 @@ _assert_no_instances, _check_qt_version, _pl, + _record_warnings, _TempDir, numerics, ) @@ -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, diff --git a/mne/export/tests/test_export.py b/mne/export/tests/test_export.py index e55647d54e6..fc5e68c9225 100644 --- a/mne/export/tests/test_export.py +++ b/mne/export/tests/test_export.py @@ -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 @@ -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] diff --git a/mne/forward/tests/test_forward.py b/mne/forward/tests/test_forward.py index 9020f7c9a26..dd73d1099f1 100644 --- a/mne/forward/tests/test_forward.py +++ b/mne/forward/tests/test_forward.py @@ -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" @@ -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 @@ -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[:, :] diff --git a/mne/forward/tests/test_make_forward.py b/mne/forward/tests/test_make_forward.py index 7965ae2343c..4e52b9a50b0 100644 --- a/mne/forward/tests/test_make_forward.py +++ b/mne/forward/tests/test_make_forward.py @@ -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, @@ -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"): diff --git a/mne/io/artemis123/tests/test_artemis123.py b/mne/io/artemis123/tests/test_artemis123.py index 9a1cdb36eec..2dac9645c33 100644 --- a/mne/io/artemis123/tests/test_artemis123.py +++ b/mne/io/artemis123/tests/test_artemis123.py @@ -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 ) diff --git a/mne/io/brainvision/brainvision.py b/mne/io/brainvision/brainvision.py index 5dea11dd35d..5aabdbb626c 100644 --- a/mne/io/brainvision/brainvision.py +++ b/mne/io/brainvision/brainvision.py @@ -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 = ( @@ -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") diff --git a/mne/io/brainvision/tests/test_brainvision.py b/mne/io/brainvision/tests/test_brainvision.py index 9c48be78a23..166c3564fae 100644 --- a/mne/io/brainvision/tests/test_brainvision.py +++ b/mne/io/brainvision/tests/test_brainvision.py @@ -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" @@ -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.""" @@ -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, @@ -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, @@ -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)) @@ -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 diff --git a/mne/io/cnt/tests/test_cnt.py b/mne/io/cnt/tests/test_cnt.py index 526cc893e69..50724d1818a 100644 --- a/mne/io/cnt/tests/test_cnt.py +++ b/mne/io/cnt/tests/test_cnt.py @@ -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"] ) @@ -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"] ) @@ -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]] diff --git a/mne/io/ctf/tests/test_ctf.py b/mne/io/ctf/tests/test_ctf.py index 20fdf2e0127..bf4415d90b8 100644 --- a/mne/io/ctf/tests/test_ctf.py +++ b/mne/io/ctf/tests/test_ctf.py @@ -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( diff --git a/mne/io/edf/tests/test_edf.py b/mne/io/edf/tests/test_edf.py index 38532e062c1..bc6250e28a6 100644 --- a/mne/io/edf/tests/test_edf.py +++ b/mne/io/edf/tests/test_edf.py @@ -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() @@ -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) diff --git a/mne/io/edf/tests/test_gdf.py b/mne/io/edf/tests/test_gdf.py index 70801a22cce..9ae33ee2feb 100644 --- a/mne/io/edf/tests/test_gdf.py +++ b/mne/io/edf/tests/test_gdf.py @@ -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"] diff --git a/mne/io/eeglab/tests/test_eeglab.py b/mne/io/eeglab/tests/test_eeglab.py index 35f9fea741b..88c18d2aab0 100644 --- a/mne/io/eeglab/tests/test_eeglab.py +++ b/mne/io/eeglab/tests/test_eeglab.py @@ -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" @@ -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 @@ -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 @@ -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 diff --git a/mne/io/eyelink/tests/test_eyelink.py b/mne/io/eyelink/tests/test_eyelink.py index 653be12564b..953fde5b67d 100644 --- a/mne/io/eyelink/tests/test_eyelink.py +++ b/mne/io/eyelink/tests/test_eyelink.py @@ -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") @@ -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 = [ diff --git a/mne/io/fieldtrip/tests/test_fieldtrip.py b/mne/io/fieldtrip/tests/test_fieldtrip.py index f7faac045ee..11546e82607 100644 --- a/mne/io/fieldtrip/tests/test_fieldtrip.py +++ b/mne/io/fieldtrip/tests/test_fieldtrip.py @@ -68,16 +68,14 @@ def test_read_evoked(cur_system, version, use_info): """Test comparing reading an Evoked object and the FieldTrip version.""" test_data_folder_ft = get_data_paths(cur_system) mne_avg = get_evoked(cur_system) + cur_fname = test_data_folder_ft / f"averaged_{version}.mat" if use_info: info = get_raw_info(cur_system) - ctx = nullcontext() + avg_ft = mne.io.read_evoked_fieldtrip(cur_fname, info) else: info = None - ctx = pytest.warns(**no_info_warning) - - cur_fname = test_data_folder_ft / f"averaged_{version}.mat" - with ctx: - avg_ft = mne.io.read_evoked_fieldtrip(cur_fname, info) + with _record_warnings(), pytest.warns(**no_info_warning): + avg_ft = mne.io.read_evoked_fieldtrip(cur_fname, info) mne_data = mne_avg.data[:, :-1] ft_data = avg_ft.data @@ -98,6 +96,7 @@ def test_read_epochs(cur_system, version, use_info, monkeypatch): has_pandas = pandas is not False test_data_folder_ft = get_data_paths(cur_system) mne_epoched = get_epochs(cur_system) + cur_fname = test_data_folder_ft / f"epoched_{version}.mat" if use_info: info = get_raw_info(cur_system) ctx = nullcontext() @@ -105,9 +104,8 @@ def test_read_epochs(cur_system, version, use_info, monkeypatch): info = None ctx = pytest.warns(**no_info_warning) - cur_fname = test_data_folder_ft / f"epoched_{version}.mat" if has_pandas: - with ctx: + with _record_warnings(), ctx: epoched_ft = mne.io.read_epochs_fieldtrip(cur_fname, info) assert isinstance(epoched_ft.metadata, pandas.DataFrame) else: @@ -133,7 +131,7 @@ def modify_mat(fname, variable_names=None, ignore_fields=None): return out monkeypatch.setattr(pymatreader, "read_mat", modify_mat) - with pytest.warns(RuntimeWarning, match="multiple"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="multiple"): mne.io.read_epochs_fieldtrip(cur_fname, info) @@ -160,7 +158,7 @@ def test_read_raw_fieldtrip(cur_system, version, use_info): cur_fname = test_data_folder_ft / f"raw_{version}.mat" - with ctx: + with _record_warnings(), ctx: raw_fiff_ft = mne.io.read_raw_fieldtrip(cur_fname, info) if cur_system == "BTI" and not use_info: diff --git a/mne/io/fiff/tests/test_raw_fiff.py b/mne/io/fiff/tests/test_raw_fiff.py index f2269b0cb51..46cfbce56a1 100644 --- a/mne/io/fiff/tests/test_raw_fiff.py +++ b/mne/io/fiff/tests/test_raw_fiff.py @@ -2098,7 +2098,9 @@ def test_corrupted(tmp_path, offset): bad_fname = tmp_path / "test_raw.fif" with open(bad_fname, "wb") as fid: fid.write(data) - with pytest.warns(RuntimeWarning, match=".*tag directory.*corrupt.*"): + with _record_warnings(), pytest.warns( + RuntimeWarning, match=".*tag directory.*corrupt.*" + ): raw_bad = read_raw_fif(bad_fname) assert_allclose(raw.get_data(), raw_bad.get_data()) diff --git a/mne/preprocessing/tests/test_ica.py b/mne/preprocessing/tests/test_ica.py index 184f7aeefdf..67aabf14b12 100644 --- a/mne/preprocessing/tests/test_ica.py +++ b/mne/preprocessing/tests/test_ica.py @@ -78,6 +78,8 @@ ) pytest.importorskip("sklearn") +_baseline_corrected = pytest.warns(RuntimeWarning, match="were baseline-corrected") + def ICA(*args, **kwargs): """Fix the random state in tests.""" @@ -171,7 +173,9 @@ def test_ica_simple(method): info = create_info(data.shape[-2], 1000.0, "eeg") cov = make_ad_hoc_cov(info) ica = ICA(n_components=n_components, method=method, random_state=0, noise_cov=cov) - with pytest.warns(RuntimeWarning, match="No average EEG.*"): + with pytest.warns(RuntimeWarning, match="high-pass filtered"), pytest.warns( + RuntimeWarning, match="No average EEG.*" + ): ica.fit(RawArray(data, info)) transform = ica.unmixing_matrix_ @ ica.pca_components_ @ A amari_distance = np.mean( @@ -649,7 +653,7 @@ def test_ica_additional(method, tmp_path, short_raw_epochs): # test if n_components=None works ica = ICA(n_components=None, method=method, max_iter=1) - with pytest.warns(UserWarning, match="did not converge"): + with _baseline_corrected, pytest.warns(UserWarning, match="did not converge"): ica.fit(epochs) _assert_ica_attributes(ica, epochs.get_data("data"), limits=(0.05, 20)) @@ -1032,7 +1036,7 @@ def test_get_explained_variance_ratio(tmp_path, short_raw_epochs): with pytest.raises(ValueError, match="ICA must be fitted first"): ica.get_explained_variance_ratio(epochs) - with pytest.warns(RuntimeWarning, match="were baseline-corrected"): + with _record_warnings(), _baseline_corrected: ica.fit(epochs) # components = int, ch_type = None @@ -1255,7 +1259,9 @@ def test_fit_params_epochs_vs_raw(param_name, param_val, tmp_path): ica = ICA(n_components=n_components, max_iter=max_iter, method=method) fit_params = {param_name: param_val} - with pytest.warns(RuntimeWarning, match="parameters.*will be ignored"): + with _record_warnings(), pytest.warns( + RuntimeWarning, match="parameters.*will be ignored" + ): ica.fit(inst=epochs, **fit_params) assert ica.reject_ == reject _assert_ica_attributes(ica) @@ -1448,7 +1454,7 @@ def test_ica_labels(): assert key in raw.ch_names raw.set_channel_types(rename) ica = ICA(n_components=4, max_iter=2, method="fastica", allow_ref_meg=True) - with pytest.warns(UserWarning, match="did not converge"): + with _record_warnings(), pytest.warns(UserWarning, match="did not converge"): ica.fit(raw) _assert_ica_attributes(ica) @@ -1473,7 +1479,7 @@ def test_ica_labels(): # derive reference ICA components and append them to raw ica_rf = ICA(n_components=2, max_iter=2, allow_ref_meg=True) - with pytest.warns(UserWarning, match="did not converge"): + with _record_warnings(), pytest.warns(UserWarning, match="did not converge"): ica_rf.fit(raw.copy().pick("ref_meg")) icacomps = ica_rf.get_sources(raw) # rename components so they are auto-detected by find_bads_ref @@ -1509,7 +1515,7 @@ def test_ica_labels(): assert_allclose(scores, [0.81, 0.14, 0.37, 0.05], atol=0.03) ica = ICA(n_components=4, max_iter=2, method="fastica", allow_ref_meg=True) - with pytest.warns(UserWarning, match="did not converge"): + with _record_warnings(), pytest.warns(UserWarning, match="did not converge"): ica.fit(raw, picks="eeg") ica.find_bads_muscle(raw) assert "muscle" in ica.labels_ diff --git a/mne/preprocessing/tests/test_ssp.py b/mne/preprocessing/tests/test_ssp.py index b7565a6c5ce..27de960ab6b 100644 --- a/mne/preprocessing/tests/test_ssp.py +++ b/mne/preprocessing/tests/test_ssp.py @@ -11,6 +11,7 @@ from mne.datasets import testing from mne.io import read_raw_ctf, read_raw_fif from mne.preprocessing.ssp import compute_proj_ecg, compute_proj_eog +from mne.utils import _record_warnings data_path = Path(__file__).parents[2] / "io" / "tests" / "data" raw_fname = data_path / "test_raw.fif" @@ -72,7 +73,7 @@ def test_compute_proj_ecg(short_raw, average): # (first with a call that makes sure we copy the mutable default "reject") with pytest.warns(RuntimeWarning, match="longer than the signal"): compute_proj_ecg(raw.copy().pick("mag"), l_freq=None, h_freq=None) - with pytest.warns(RuntimeWarning, match="No good epochs found"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="No good epochs found"): projs, events, drop_log = compute_proj_ecg( raw, n_mag=2, @@ -133,7 +134,7 @@ def test_compute_proj_eog(average, short_raw): assert proj["explained_var"] > thresh_eeg # XXX: better tests - with pytest.warns(RuntimeWarning, match="longer"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="longer"): projs, events = compute_proj_eog( raw, n_mag=2, @@ -150,7 +151,9 @@ def test_compute_proj_eog(average, short_raw): assert projs == [] raw._data[raw.ch_names.index("EOG 061"), :] = 1.0 - with pytest.warns(RuntimeWarning, match="filter.*longer than the signal"): + with _record_warnings(), pytest.warns( + RuntimeWarning, match="filter.*longer than the signal" + ): projs, events = compute_proj_eog(raw=raw, tmax=dur_use, ch_name="EOG 061") diff --git a/mne/report/tests/test_report.py b/mne/report/tests/test_report.py index 0e74201c1cb..e8695253cbe 100644 --- a/mne/report/tests/test_report.py +++ b/mne/report/tests/test_report.py @@ -38,7 +38,7 @@ CONTENT_ORDER, _webp_supported, ) -from mne.utils import Bunch +from mne.utils import Bunch, _record_warnings from mne.utils._testing import assert_object_equal from mne.viz import plot_alignment @@ -1053,7 +1053,9 @@ def test_manual_report_3d(tmp_path, renderer): add_kwargs = dict( trans=trans_fname, info=info, subject="sample", subjects_dir=subjects_dir ) - with pytest.warns(RuntimeWarning, match="could not be calculated"): + with _record_warnings(), pytest.warns( + RuntimeWarning, match="could not be calculated" + ): r.add_trans(title="coreg no dig", **add_kwargs) with info._unlock(): info["dig"] = dig diff --git a/mne/source_space/tests/test_source_space.py b/mne/source_space/tests/test_source_space.py index 2389e59cb5b..4a1e20eef9b 100644 --- a/mne/source_space/tests/test_source_space.py +++ b/mne/source_space/tests/test_source_space.py @@ -699,7 +699,9 @@ def test_source_space_exclusive_complete(src_volume_labels): for si, s in enumerate(src): assert_allclose(src_full[0]["rr"], s["rr"], atol=1e-6) # also check single_volume=True -- should be the same result - with pytest.warns(RuntimeWarning, match="Found no usable.*Left-vessel.*"): + with _record_warnings(), pytest.warns( + RuntimeWarning, match="Found no usable.*Left-vessel.*" + ): src_single = setup_volume_source_space( src[0]["subject_his_id"], 7.0, diff --git a/mne/stats/tests/test_cluster_level.py b/mne/stats/tests/test_cluster_level.py index c1c4ba40851..59bb0611aeb 100644 --- a/mne/stats/tests/test_cluster_level.py +++ b/mne/stats/tests/test_cluster_level.py @@ -96,7 +96,9 @@ def test_thresholds(numba_conditional): # nan handling in TFCE X = np.repeat(X[0], 2, axis=1) X[:, 1] = 0 - with pytest.warns(RuntimeWarning, match="invalid value"): # NumPy + with _record_warnings(), pytest.warns( + RuntimeWarning, match="invalid value" + ): # NumPy out = permutation_cluster_1samp_test( X, seed=0, threshold=dict(start=0, step=0.1), out_type="mask" ) @@ -140,7 +142,7 @@ def test_cache_dir(tmp_path, numba_conditional): # ensure that non-independence yields warning stat_fun = partial(ttest_1samp_no_p, sigma=1e-3) random_state = np.random.default_rng(0) - with pytest.warns(RuntimeWarning, match="independently"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="independently"): permutation_cluster_1samp_test( X, buffer_size=10, @@ -509,7 +511,7 @@ def test_cluster_permutation_with_adjacency(numba_conditional, monkeypatch): assert np.min(out_adjacency_6[2]) < 0.05 with pytest.raises(ValueError, match="not compatible"): - with pytest.warns(RuntimeWarning, match="No clusters"): + with _record_warnings(): spatio_temporal_func( X1d_3, n_permutations=50, diff --git a/mne/tests/test_bem.py b/mne/tests/test_bem.py index d2ee3fe9f93..261fd9efe55 100644 --- a/mne/tests/test_bem.py +++ b/mne/tests/test_bem.py @@ -44,7 +44,7 @@ from mne.io import read_info from mne.surface import _get_ico_surface, read_surface from mne.transforms import translation -from mne.utils import catch_logging, check_version +from mne.utils import _record_warnings, catch_logging, check_version fname_raw = Path(__file__).parents[1] / "io" / "tests" / "data" / "test_raw.fif" subjects_dir = testing.data_path(download=False) / "subjects" @@ -54,6 +54,8 @@ fname_bem_sol_1 = subjects_dir / "sample" / "bem" / "sample-320-bem-sol.fif" fname_dense_head = subjects_dir / "sample" / "bem" / "sample-head-dense.fif" +_few_points = pytest.warns(RuntimeWarning, match="Only .* head digitization") + def _compare_bem_surfaces(surfs_1, surfs_2): """Compare BEM surfaces.""" @@ -414,7 +416,7 @@ def test_fit_sphere_to_headshape(): # # Test with 4 points that match a perfect sphere dig_kinds = (FIFF.FIFFV_POINT_CARDINAL, FIFF.FIFFV_POINT_EXTRA) - with pytest.warns(RuntimeWarning, match="Only .* head digitization"): + with _few_points: r, oh, od = fit_sphere_to_headshape(info, dig_kinds=dig_kinds, units="m") kwargs = dict(rtol=1e-3, atol=1e-5) assert_allclose(r, rad, **kwargs) @@ -424,7 +426,7 @@ def test_fit_sphere_to_headshape(): # Test with all points dig_kinds = ("cardinal", FIFF.FIFFV_POINT_EXTRA, "eeg") kwargs = dict(rtol=1e-3, atol=1e-3) - with pytest.warns(RuntimeWarning, match="Only .* head digitization"): + with _few_points: r, oh, od = fit_sphere_to_headshape(info, dig_kinds=dig_kinds, units="m") assert_allclose(r, rad, **kwargs) assert_allclose(oh, center, **kwargs) @@ -432,7 +434,7 @@ def test_fit_sphere_to_headshape(): # Test with some noisy EEG points only. dig_kinds = "eeg" - with pytest.warns(RuntimeWarning, match="Only .* head digitization"): + with _few_points: r, oh, od = fit_sphere_to_headshape(info, dig_kinds=dig_kinds, units="m") kwargs = dict(rtol=1e-3, atol=1e-2) assert_allclose(r, rad, **kwargs) @@ -446,7 +448,7 @@ def test_fit_sphere_to_headshape(): d["r"] -= center d["r"] *= big_rad / rad d["r"] += center - with pytest.warns(RuntimeWarning, match="Estimated head radius"): + with _few_points, pytest.warns(RuntimeWarning, match="Estimated head radius"): r, oh, od = fit_sphere_to_headshape(info_big, dig_kinds=dig_kinds, units="mm") assert_allclose(oh, center * 1000, atol=1e-3) assert_allclose(r, big_rad * 1000, atol=1e-3) @@ -459,27 +461,31 @@ def test_fit_sphere_to_headshape(): for d in info_shift["dig"]: d["r"] -= center d["r"] += shift_center - with pytest.warns(RuntimeWarning, match="from head frame origin"): + with _record_warnings(), pytest.warns( + RuntimeWarning, match="from head frame origin" + ): r, oh, od = fit_sphere_to_headshape(info_shift, dig_kinds=dig_kinds, units="m") assert_allclose(oh, shift_center, atol=1e-6) assert_allclose(r, rad, atol=1e-6) # Test "auto" mode (default) # Should try "extra", fail, and go on to EEG - with pytest.warns(RuntimeWarning, match="Only .* head digitization"): + with _few_points: r, oh, od = fit_sphere_to_headshape(info, units="m") kwargs = dict(rtol=1e-3, atol=1e-3) assert_allclose(r, rad, **kwargs) assert_allclose(oh, center, **kwargs) assert_allclose(od, dev_center, **kwargs) - with pytest.warns(RuntimeWarning, match="Only .* head digitization"): + with _few_points: r2, oh2, od2 = fit_sphere_to_headshape(info, units="m") assert_allclose(r, r2, atol=1e-7) assert_allclose(oh, oh2, atol=1e-7) assert_allclose(od, od2, atol=1e-7) # this one should pass, 1 EXTRA point and 3 EEG (but the fit is terrible) info = Info(dig=dig[:7], dev_head_t=dev_head_t) - with pytest.warns(RuntimeWarning, match="Only .* head digitization"): + with _record_warnings(), pytest.warns( + RuntimeWarning, match="Estimated head radius" + ): r, oh, od = fit_sphere_to_headshape(info, units="m") # this one should fail, 1 EXTRA point and 3 EEG (but the fit is terrible) info = Info(dig=dig[:6], dev_head_t=dev_head_t) @@ -499,12 +505,12 @@ def test_io_head_bem(tmp_path): with pytest.raises(ValueError, match="topological defects:"): write_head_bem(fname_defect, head["rr"], head["tris"]) - with pytest.warns(RuntimeWarning, match="topological defects:"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="topological defects:"): write_head_bem(fname_defect, head["rr"], head["tris"], on_defects="warn") # test on_defects in read_bem_surfaces with pytest.raises(ValueError, match="topological defects:"): read_bem_surfaces(fname_defect) - with pytest.warns(RuntimeWarning, match="topological defects:"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="topological defects:"): head_defect = read_bem_surfaces(fname_defect, on_defects="warn")[0] assert head["id"] == head_defect["id"] == FIFF.FIFFV_BEM_SURF_ID_HEAD @@ -550,12 +556,14 @@ def _decimate_surface(points, triangles, n_triangles): # These are ignorable monkeypatch.setattr(mne.bem, "_tri_levels", dict(sparse=315)) - with pytest.warns(RuntimeWarning, match=".*have fewer than three.*"): + with _record_warnings(), pytest.warns( + RuntimeWarning, match=".*have fewer than three.*" + ): make_scalp_surfaces(subject, subjects_dir, force=True, overwrite=True) (surf,) = read_bem_surfaces(sparse_path, on_defects="ignore") assert len(surf["tris"]) == 315 monkeypatch.setattr(mne.bem, "_tri_levels", dict(sparse=319)) - with pytest.warns(RuntimeWarning, match=".*is not complete.*"): + with _record_warnings(), pytest.warns(RuntimeWarning, match=".*is not complete.*"): make_scalp_surfaces(subject, subjects_dir, force=True, overwrite=True) (surf,) = read_bem_surfaces(sparse_path, on_defects="ignore") assert len(surf["tris"]) == 319 diff --git a/mne/tests/test_chpi.py b/mne/tests/test_chpi.py index 35b4dd00794..5801e374b3b 100644 --- a/mne/tests/test_chpi.py +++ b/mne/tests/test_chpi.py @@ -43,7 +43,13 @@ ) from mne.simulation import add_chpi from mne.transforms import _angle_between_quats, rot_to_quat -from mne.utils import assert_meg_snr, catch_logging, object_diff, verbose +from mne.utils import ( + _record_warnings, + assert_meg_snr, + catch_logging, + object_diff, + verbose, +) from mne.viz import plot_head_positions base_dir = Path(__file__).parents[1] / "io" / "tests" / "data" @@ -366,7 +372,7 @@ def test_calculate_chpi_positions_vv(): ] ) raw_bad.pick([raw_bad.ch_names[pick] for pick in picks]) - with pytest.warns(RuntimeWarning, match="Discrepancy"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="Discrepancy"): with catch_logging() as log_file: _calculate_chpi_positions(raw_bad, t_step_min=1.0, verbose=True) # ignore HPI info header and [done] footer diff --git a/mne/tests/test_cov.py b/mne/tests/test_cov.py index 2b7570d127c..cd817dcfceb 100644 --- a/mne/tests/test_cov.py +++ b/mne/tests/test_cov.py @@ -352,7 +352,7 @@ def test_cov_estimation_on_raw(method, tmp_path): assert_snr(cov.data, cov_mne.data[:5, :5], 90) # cutoff samps # make sure we get a warning with too short a segment raw_2 = read_raw_fif(raw_fname).crop(0, 1) - with pytest.warns(RuntimeWarning, match="Too few samples"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="Too few samples"): cov = compute_raw_covariance(raw_2, method=method, method_params=method_params) # no epochs found due to rejection pytest.raises( @@ -384,7 +384,7 @@ def test_cov_estimation_on_raw_reg(): raw.info["sfreq"] /= 10.0 raw = RawArray(raw._data[:, ::10].copy(), raw.info) # decimate for speed cov_mne = read_cov(erm_cov_fname) - with pytest.warns(RuntimeWarning, match="Too few samples"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="Too few samples"): # "diagonal_fixed" is much faster. Use long epochs for speed. cov = compute_raw_covariance(raw, tstep=5.0, method="diagonal_fixed") assert_snr(cov.data, cov_mne.data, 5) @@ -891,13 +891,13 @@ def test_cov_ctf(): for comp in [0, 1]: raw.apply_gradient_compensation(comp) epochs = Epochs(raw, events, None, -0.2, 0.2, preload=True) - with pytest.warns(RuntimeWarning, match="Too few samples"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="Too few samples"): noise_cov = compute_covariance(epochs, tmax=0.0, method=["empirical"]) prepare_noise_cov(noise_cov, raw.info, ch_names) raw.apply_gradient_compensation(0) epochs = Epochs(raw, events, None, -0.2, 0.2, preload=True) - with pytest.warns(RuntimeWarning, match="Too few samples"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="Too few samples"): noise_cov = compute_covariance(epochs, tmax=0.0, method=["empirical"]) raw.apply_gradient_compensation(1) diff --git a/mne/tests/test_epochs.py b/mne/tests/test_epochs.py index 76172982da7..2b67dd9dbd6 100644 --- a/mne/tests/test_epochs.py +++ b/mne/tests/test_epochs.py @@ -64,6 +64,7 @@ from mne.preprocessing import maxwell_filter from mne.utils import ( _dt_to_stamp, + _record_warnings, assert_meg_snr, catch_logging, object_diff, @@ -2291,7 +2292,7 @@ def test_crop(tmp_path): reject=reject, flat=flat, ) - with pytest.warns(RuntimeWarning, match="tmax is set to"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="tmax is set to"): epochs2.crop(-20, 200) # indices for slicing @@ -3610,7 +3611,7 @@ def test_concatenate_epochs(): # check concatenating epochs where one of the objects is empty epochs2 = epochs.copy()[:0] - with pytest.warns(RuntimeWarning, match="was empty"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="was empty"): concatenate_epochs([epochs, epochs2]) # check concatenating epochs results are chronologically ordered @@ -4221,7 +4222,7 @@ def test_no_epochs(tmp_path): # and with no epochs remaining raw.info["bads"] = [] epochs = mne.Epochs(raw, events, reject=reject) - with pytest.warns(RuntimeWarning, match="no data"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="no data"): epochs.save(tmp_path / "sample-epo.fif", overwrite=True) assert len(epochs) == 0 # all dropped diff --git a/mne/tests/test_evoked.py b/mne/tests/test_evoked.py index 2c5f064606d..8aa781eefec 100644 --- a/mne/tests/test_evoked.py +++ b/mne/tests/test_evoked.py @@ -34,7 +34,7 @@ from mne._fiff.constants import FIFF from mne.evoked import Evoked, EvokedArray, _get_peak from mne.io import read_raw_fif -from mne.utils import grand_average +from mne.utils import _record_warnings, grand_average base_dir = Path(__file__).parents[1] / "io" / "tests" / "data" fname = base_dir / "test-ave.fif" @@ -799,7 +799,7 @@ def test_time_as_index_and_crop(): ) evoked.crop(evoked.tmin, evoked.tmax, include_tmax=False) n_times = len(evoked.times) - with pytest.warns(RuntimeWarning, match="tmax is set to"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="tmax is set to"): evoked.crop(tmin, tmax, include_tmax=False) assert len(evoked.times) == n_times assert_allclose(evoked.times[[0, -1]], [tmin, tmax - delta], atol=atol) diff --git a/mne/tests/test_source_estimate.py b/mne/tests/test_source_estimate.py index ebe1a369e4d..dff220d9752 100644 --- a/mne/tests/test_source_estimate.py +++ b/mne/tests/test_source_estimate.py @@ -399,7 +399,7 @@ def test_stc_snr(): assert (stc.data < 0).any() with pytest.warns(RuntimeWarning, match="nAm"): stc.estimate_snr(evoked.info, fwd, cov) # dSPM - with pytest.warns(RuntimeWarning, match="free ori"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="free ori"): abs(stc).estimate_snr(evoked.info, fwd, cov) stc = apply_inverse(evoked, inv, method="MNE") snr = stc.estimate_snr(evoked.info, fwd, cov) diff --git a/mne/time_frequency/tests/test_spectrum.py b/mne/time_frequency/tests/test_spectrum.py index 26c18529143..18fbf4da483 100644 --- a/mne/time_frequency/tests/test_spectrum.py +++ b/mne/time_frequency/tests/test_spectrum.py @@ -11,6 +11,7 @@ from mne import Annotations from mne.time_frequency import read_spectrum from mne.time_frequency.spectrum import EpochsSpectrumArray, SpectrumArray +from mne.utils import _record_warnings def test_compute_psd_errors(raw): @@ -273,7 +274,7 @@ def test_spectrum_kwarg_triaging(raw): regex = r"legacy plot_psd\(\) method.*unexpected keyword.*'axes'.*Try rewriting" _, axes = plt.subplots(1, 2) # `axes` is the new param name: technically only valid for Spectrum.plot() - with pytest.warns(RuntimeWarning, match=regex): + with _record_warnings(), pytest.warns(RuntimeWarning, match=regex): raw.plot_psd(axes=axes) # `ax` is the correct legacy param name with pytest.warns(FutureWarning, match="amplitude='auto'"): diff --git a/mne/utils/tests/test_check.py b/mne/utils/tests/test_check.py index 48017b79ae2..4ec7450df99 100644 --- a/mne/utils/tests/test_check.py +++ b/mne/utils/tests/test_check.py @@ -27,6 +27,7 @@ _check_subject, _on_missing, _path_like, + _record_warnings, _safe_input, _suggest, _validate_type, @@ -368,7 +369,7 @@ def test_check_sphere_verbose(): info = mne.io.read_info(fname_raw) with info._unlock(): info["dig"] = info["dig"][:20] - with pytest.warns(RuntimeWarning, match="may be inaccurate"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="may be inaccurate"): _check_sphere("auto", info) with mne.use_log_level("error"): _check_sphere("auto", info) diff --git a/mne/utils/tests/test_logging.py b/mne/utils/tests/test_logging.py index 02a5a7363d0..25668a1de37 100644 --- a/mne/utils/tests/test_logging.py +++ b/mne/utils/tests/test_logging.py @@ -63,7 +63,7 @@ def test_frame_info(capsys, monkeypatch): def test_how_to_deal_with_warnings(): """Test filter some messages out of warning records.""" - with pytest.warns(UserWarning, match="bb") as w: + with pytest.warns(Warning, match="(bb|aa) warning") as w: warnings.warn("aa warning", UserWarning) warnings.warn("bb warning", UserWarning) warnings.warn("bb warning", RuntimeWarning) diff --git a/mne/viz/tests/test_epochs.py b/mne/viz/tests/test_epochs.py index 6dcfdb57bdf..1eccf64bbc2 100644 --- a/mne/viz/tests/test_epochs.py +++ b/mne/viz/tests/test_epochs.py @@ -17,6 +17,7 @@ from mne import Epochs, EpochsArray, create_info from mne.datasets import testing from mne.event import make_fixed_length_events +from mne.utils import _record_warnings from mne.viz import plot_drop_log @@ -52,13 +53,13 @@ def test_plot_epochs_basic(epochs, epochs_full, noise_cov_io, capsys, browser_ba browser_backend._close_all() # add a channel to cov['bads'] noise_cov_io["bads"] = [epochs.ch_names[1]] - with pytest.warns(RuntimeWarning, match="projection"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="projection"): epochs.plot(noise_cov=noise_cov_io) browser_backend._close_all() # have a data channel missing from the covariance noise_cov_io["names"] = noise_cov_io["names"][:306] noise_cov_io["data"] = noise_cov_io["data"][:306][:306] - with pytest.warns(RuntimeWarning, match="projection"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="projection"): epochs.plot(noise_cov=noise_cov_io) browser_backend._close_all() # other options @@ -300,7 +301,9 @@ def test_plot_epochs_image(epochs): picks=[0, 1], order=lambda times, data: np.arange(len(data))[::-1] ) # test warning - with pytest.warns(RuntimeWarning, match="Only one channel in group"): + with _record_warnings(), pytest.warns( + RuntimeWarning, match="Only one channel in group" + ): epochs.plot_image(picks=[1], combine="mean") # group_by should be a dict with pytest.raises(TypeError, match="dict or None"): @@ -418,7 +421,7 @@ def test_plot_psd_epochs(epochs): err_str = "for channel %s" % epochs.ch_names[2] epochs.get_data(copy=False)[0, 2, :] = 0 for dB in [True, False]: - with pytest.warns(UserWarning, match=err_str): + with _record_warnings(), pytest.warns(UserWarning, match=err_str): epochs.compute_psd().plot(dB=dB) @@ -492,7 +495,7 @@ def test_plot_psd_epochs_ctf(raw_ctf): epochs = Epochs(raw_ctf, evts, preload=True) old_defaults = dict(picks="data", exclude="bads") # EEG060 is flat in this dataset - with pytest.warns(UserWarning, match="for channel EEG060"): + with _record_warnings(), pytest.warns(UserWarning, match="for channel EEG060"): spectrum = epochs.compute_psd() for dB in [True, False]: spectrum.plot(dB=dB) diff --git a/mne/viz/tests/test_evoked.py b/mne/viz/tests/test_evoked.py index 999260465fd..66609839df8 100644 --- a/mne/viz/tests/test_evoked.py +++ b/mne/viz/tests/test_evoked.py @@ -34,7 +34,7 @@ from mne.datasets import testing from mne.io import read_raw_fif from mne.stats.parametric import _parametric_ci -from mne.utils import catch_logging +from mne.utils import _record_warnings, catch_logging from mne.viz import plot_compare_evokeds, plot_evoked_white from mne.viz.utils import _fake_click, _get_cmap @@ -119,7 +119,7 @@ def test_plot_evoked_cov(): epochs = Epochs(raw, events, picks=default_picks) cov = compute_covariance(epochs) evoked_sss = epochs.average() - with pytest.warns(RuntimeWarning, match="relative scaling"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="relative scaling"): evoked_sss.plot(noise_cov=cov, time_unit="s") plt.close("all") @@ -333,7 +333,7 @@ def test_plot_evoked_image(): mask=np.ones(evoked.data.shape).astype(bool), time_unit="s", ) - with pytest.warns(RuntimeWarning, match="not adding contour"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="not adding contour"): evoked.plot_image(picks=[1, 2], mask=None, mask_style="both", time_unit="s") with pytest.raises(ValueError, match="must have the same shape"): evoked.plot_image(mask=evoked.data[1:, 1:] > 0, time_unit="s") diff --git a/mne/viz/tests/test_ica.py b/mne/viz/tests/test_ica.py index 35903a5f802..7972e4d36b6 100644 --- a/mne/viz/tests/test_ica.py +++ b/mne/viz/tests/test_ica.py @@ -157,7 +157,7 @@ def test_plot_ica_properties(): ) ica = ICA(noise_cov=read_cov(cov_fname), n_components=2, max_iter=1, random_state=0) - with pytest.warns(RuntimeWarning, match="projection"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="projection"): ica.fit(raw) # test _create_properties_layout @@ -240,7 +240,7 @@ def test_plot_ica_properties(): # Test handling of zeros ica = ICA(random_state=0, max_iter=1) epochs.pick(pick_names) - with pytest.warns(UserWarning, match="did not converge"): + with _record_warnings(), pytest.warns(UserWarning, match="did not converge"): ica.fit(epochs) epochs._data[0] = 0 # Usually UserWarning: Infinite value .* for epo @@ -254,7 +254,7 @@ def test_plot_ica_properties(): raw_annot.pick(np.arange(10)) raw_annot.del_proj() - with pytest.warns(UserWarning, match="did not converge"): + with _record_warnings(), pytest.warns(UserWarning, match="did not converge"): ica.fit(raw_annot) # drop bad data segments fig = ica.plot_properties(raw_annot, picks=[0, 1], **topoargs) diff --git a/mne/viz/tests/test_raw.py b/mne/viz/tests/test_raw.py index 619c79a7111..14233a4c98b 100644 --- a/mne/viz/tests/test_raw.py +++ b/mne/viz/tests/test_raw.py @@ -973,7 +973,9 @@ def test_plot_raw_psd(raw, raw_orig): # with channel information not available for idx in range(len(raw.info["chs"])): raw.info["chs"][idx]["loc"] = np.zeros(12) - with pytest.warns(RuntimeWarning, match="locations not available"): + with _record_warnings(), pytest.warns( + RuntimeWarning, match="locations not available" + ): raw.compute_psd().plot(spatial_colors=True, average=False) # with a flat channel raw[5, :] = 0 diff --git a/mne/viz/tests/test_topo.py b/mne/viz/tests/test_topo.py index 12c345e6623..5830c647edb 100644 --- a/mne/viz/tests/test_topo.py +++ b/mne/viz/tests/test_topo.py @@ -325,7 +325,7 @@ def test_plot_tfr_topo(): # test opening tfr by clicking num_figures_before = len(plt.get_fignums()) # could use np.reshape(fig.axes[-1].images[0].get_extent(), (2, 2)).mean(1) - with pytest.warns(RuntimeWarning, match="not masking"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="not masking"): _fake_click(fig, fig.axes[0], (0.08, 0.65)) assert num_figures_before + 1 == len(plt.get_fignums()) plt.close("all") @@ -349,7 +349,7 @@ def test_plot_tfr_topo(): vmin, vmax = 0.0, 2.0 fig, ax = plt.subplots() tmin, tmax = epochs.times[0], epochs.times[-1] - with pytest.warns(RuntimeWarning, match="not masking"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="not masking"): _imshow_tfr( ax, 3, @@ -372,7 +372,7 @@ def test_plot_tfr_topo(): # ValueError when freq[0] == 0 and yscale == 'log' these_freqs = freqs[:3].copy() these_freqs[0] = 0 - with pytest.warns(RuntimeWarning, match="not masking"): + with _record_warnings(), pytest.warns(RuntimeWarning, match="not masking"): pytest.raises( ValueError, _imshow_tfr, diff --git a/pyproject.toml b/pyproject.toml index 18153fa1557..62cd1914318 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -110,7 +110,7 @@ full = [ # Dependencies for running the test infrastructure test = [ - "pytest!=8.0.0rc1", + "pytest>=8.0.0rc2", "pytest-cov", "pytest-timeout", "pytest-harvest",