Skip to content

Commit

Permalink
[MRG] MAINT: get test suite ready for pytest >= 8 (#1252)
Browse files Browse the repository at this point in the history
* remove pytest<8 pin

* add fixes to tests

* try dealing with mpl deprecation warning
  • Loading branch information
sappelhoff authored May 23, 2024
1 parent 1350e02 commit 8e36555
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 55 deletions.
13 changes: 13 additions & 0 deletions mne_bids/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,16 @@ def _validate(bids_root):
run_subprocess(cmd, shell=shell)

return _validate


# Deal with:
# Auto-close()ing of figures upon backend switching is deprecated since 3.8 and will
# be removed in 3.10. To suppress this warning, explicitly call plt.close('all')
# first.
@pytest.fixture(autouse=True)
def close_all():
"""Close all matplotlib plots, regardless of test status."""
import matplotlib.pyplot as plt

yield
plt.close("all")
7 changes: 6 additions & 1 deletion mne_bids/tests/test_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -1337,7 +1337,12 @@ def test_find_emptyroom_no_meas_date(tmp_path):
write_raw_bids(raw, bids_path, overwrite=True)
os.remove(op.join(bids_root, "participants.tsv"))

with pytest.warns(RuntimeWarning, match="Could not retrieve .* date"):
with (
pytest.warns(RuntimeWarning, match="Could not retrieve .* date"),
pytest.warns(RuntimeWarning, match="participants.tsv file not found"),
pytest.warns(RuntimeWarning, match=r"Did not find any channels\.tsv"),
pytest.warns(RuntimeWarning, match=r"Did not find any meg\.json"),
):
bids_path.find_empty_room()


Expand Down
133 changes: 92 additions & 41 deletions mne_bids/tests/test_read.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,11 @@ def test_get_head_mri_trans(tmp_path):
t1_bids_path = _bids_path.copy().update(
root=tmp_path / "mri_root", task=None, run=None
)
with pytest.warns(RuntimeWarning, match="Did not find any channels.tsv"):
with (
pytest.warns(RuntimeWarning, match="Did not find any channels.tsv"),
pytest.warns(RuntimeWarning, match=r"Did not find any eeg\.json"),
pytest.warns(RuntimeWarning, match=r"participants\.tsv file not found"),
):
get_head_mri_trans(
bids_path=electrophys_bids_path,
t1_bids_path=t1_bids_path,
Expand All @@ -439,25 +443,31 @@ def test_get_head_mri_trans(tmp_path):

# bids_path without datatype is deprecated
bids_path = electrophys_bids_path.copy().update(datatype=None)
with pytest.raises(FileNotFoundError): # defaut location is all wrong!
with pytest.warns(DeprecationWarning, match="no datatype"):
get_head_mri_trans(
bids_path=bids_path,
t1_bids_path=t1_bids_path,
fs_subject="sample",
fs_subjects_dir=subjects_dir,
)
# defaut location is all wrong!
with (
pytest.raises(FileNotFoundError),
pytest.warns(DeprecationWarning, match="did not have a datatype"),
):
get_head_mri_trans(
bids_path=bids_path,
t1_bids_path=t1_bids_path,
fs_subject="sample",
fs_subjects_dir=subjects_dir,
)

# bids_path without suffix is deprecated
bids_path = electrophys_bids_path.copy().update(suffix=None)
with pytest.raises(FileNotFoundError): # defaut location is all wrong!
with pytest.warns(DeprecationWarning, match="no datatype"):
get_head_mri_trans(
bids_path=bids_path,
t1_bids_path=t1_bids_path,
fs_subject="sample",
fs_subjects_dir=subjects_dir,
)
# defaut location is all wrong!
with (
pytest.raises(FileNotFoundError),
pytest.warns(DeprecationWarning, match="did not have a suffix"),
):
get_head_mri_trans(
bids_path=bids_path,
t1_bids_path=t1_bids_path,
fs_subject="sample",
fs_subjects_dir=subjects_dir,
)

# Should fail for an unsupported coordinate frame
raw = _read_raw_fif(raw_fname)
Expand Down Expand Up @@ -791,7 +801,13 @@ def test_handle_chpi_reading(tmp_path):
meg_json_data_freq_mismatch["HeadCoilFrequency"][0] = 123
_write_json(meg_json_path, meg_json_data_freq_mismatch, overwrite=True)

with pytest.warns(RuntimeWarning, match="Defaulting to .* mne.Raw object"):
with (
pytest.warns(RuntimeWarning, match="Defaulting to .* mne.Raw object"),
pytest.warns(
RuntimeWarning, match="This file contains raw Internal Active Shielding"
),
pytest.warns(RuntimeWarning, match="The unit for channel"),
):
raw_read = read_raw_bids(bids_path)

# cHPI "off" according to sidecar, but present in the data
Expand Down Expand Up @@ -866,8 +882,11 @@ def test_handle_eeg_coords_reading(tmp_path):
bids_path, suffix="coordsystem", extension=".json"
)
_update_sidecar(coordsystem_fname, "EEGCoordinateSystem", "besa")
with pytest.warns(
RuntimeWarning, match="is not a BIDS-acceptable coordinate frame for EEG"
with (
pytest.warns(
RuntimeWarning, match="is not a BIDS-acceptable coordinate frame for EEG"
),
pytest.warns(RuntimeWarning, match="The unit for channel"),
):
raw_test = read_raw_bids(bids_path)
assert raw_test.info["dig"] is None
Expand Down Expand Up @@ -938,8 +957,11 @@ def test_handle_ieeg_coords_reading(bids_path, tmp_path):
for axis in ["x", "y", "z"]:
electrodes_dict[axis] = np.multiply(orig_electrodes_dict[axis], scaling)
_to_tsv(electrodes_dict, electrodes_fname)
with pytest.warns(
RuntimeWarning, match="Coordinate unit is not an accepted BIDS unit"
with (
pytest.warns(
RuntimeWarning, match="Coordinate unit is not an accepted BIDS unit"
),
pytest.warns(RuntimeWarning, match="The unit for channel"),
):
raw_test = read_raw_bids(bids_path=bids_fname, verbose=False)

Expand Down Expand Up @@ -967,7 +989,10 @@ def test_handle_ieeg_coords_reading(bids_path, tmp_path):
_update_sidecar(coordsystem_fname, "iEEGCoordinateSystem", coord_frame)
# read in raw file w/ updated coordinate frame
# and make sure all digpoints are MRI coordinate frame
with pytest.warns(RuntimeWarning, match="not an MNE-Python coordinate frame"):
with (
pytest.warns(RuntimeWarning, match="not an MNE-Python coordinate frame"),
pytest.warns(RuntimeWarning, match="The unit for channel"),
):
raw_test = read_raw_bids(bids_path=bids_fname, verbose=False)
assert raw_test.info["dig"] is not None

Expand All @@ -981,8 +1006,11 @@ def test_handle_ieeg_coords_reading(bids_path, tmp_path):
if coord_frame in BIDS_TO_MNE_FRAMES:
raw_test = read_raw_bids(bids_path=bids_fname, verbose=False)
else:
with pytest.warns(
RuntimeWarning, match="not an MNE-Python coordinate frame"
with (
pytest.warns(
RuntimeWarning, match="not an MNE-Python coordinate frame"
),
pytest.warns(RuntimeWarning, match="The unit for channel"),
):
raw_test = read_raw_bids(bids_path=bids_fname, verbose=False)
assert raw_test.info["dig"] is not None
Expand Down Expand Up @@ -1010,7 +1038,10 @@ def test_handle_ieeg_coords_reading(bids_path, tmp_path):
_to_tsv(electrodes_dict, electrodes_fname)
# popping off channels should not result in an error
# however, a warning will be raised through mne-python
with pytest.warns(RuntimeWarning, match="DigMontage is only a subset of info"):
with (
pytest.warns(RuntimeWarning, match="DigMontage is only a subset of info"),
pytest.warns(RuntimeWarning, match="The unit for channel"),
):
read_raw_bids(bids_path=bids_fname, verbose=False)

# make sure montage is set if there are coordinates w/ 'n/a'
Expand All @@ -1026,7 +1057,10 @@ def test_handle_ieeg_coords_reading(bids_path, tmp_path):
# electrode coordinates should be nan
# when coordinate is 'n/a'
nan_chs = [electrodes_dict["name"][i] for i in [0, 3]]
with pytest.warns(RuntimeWarning, match="There are channels without locations"):
with (
pytest.warns(RuntimeWarning, match="There are channels without locations"),
pytest.warns(RuntimeWarning, match="The unit for channel"),
):
raw = read_raw_bids(bids_path=bids_fname, verbose=False)
for idx, ch in enumerate(raw.info["chs"]):
if ch["ch_name"] in nan_chs:
Expand Down Expand Up @@ -1155,7 +1189,10 @@ def test_handle_non_mne_channel_type(tmp_path):
channels_data["type"][ch_idx] = "FOOBAR"
_to_tsv(data=channels_data, fname=channels_tsv_path)

with pytest.warns(RuntimeWarning, match='will be set to "misc"'):
with (
pytest.warns(RuntimeWarning, match='will be set to "misc"'),
pytest.warns(RuntimeWarning, match="The unit for channel"),
):
raw = read_raw_bids(bids_path)

# Should be a 'misc' channel.
Expand Down Expand Up @@ -1285,10 +1322,13 @@ def test_channels_tsv_raw_mismatch(tmp_path):
raw.load_data()
raw.save(raw_path, overwrite=True)

with pytest.warns(
RuntimeWarning,
match="number of channels in the channels.tsv sidecar .* "
"does not match the number of channels in the raw data",
with (
pytest.warns(
RuntimeWarning,
match="number of channels in the channels.tsv sidecar .* "
"does not match the number of channels in the raw data",
),
pytest.warns(RuntimeWarning, match="Cannot set channel type"),
):
read_raw_bids(bids_path)

Expand All @@ -1299,10 +1339,13 @@ def test_channels_tsv_raw_mismatch(tmp_path):
raw.rename_channels({ch_name_orig: ch_name_new})
raw.save(raw_path, overwrite=True)

with pytest.warns(
RuntimeWarning,
match=f"Cannot set channel type for the following channels, as they "
f"are missing in the raw data: {ch_name_orig}",
with (
pytest.warns(
RuntimeWarning,
match=f"Cannot set channel type for the following channels, as they "
f"are missing in the raw data: {ch_name_orig}",
),
pytest.warns(RuntimeWarning, match="The number of channels in the channels"),
):
read_raw_bids(bids_path)

Expand All @@ -1318,10 +1361,14 @@ def test_channels_tsv_raw_mismatch(tmp_path):
raw.rename_channels({ch_name_orig: ch_name_new})
raw.save(raw_path, overwrite=True)

with pytest.warns(
RuntimeWarning,
match=f'Cannot set "bad" status for the following channels, as '
f"they are missing in the raw data: {ch_name_orig}",
with (
pytest.warns(
RuntimeWarning,
match=f'Cannot set "bad" status for the following channels, as '
f"they are missing in the raw data: {ch_name_orig}",
),
pytest.warns(RuntimeWarning, match="The number of channels in the channels"),
pytest.warns(RuntimeWarning, match="Cannot set channel type"),
):
read_raw_bids(bids_path)

Expand Down Expand Up @@ -1362,7 +1409,11 @@ def test_file_not_found(tmp_path):

bp.update(extension=".fif")
_read_raw_fif(raw_fname, verbose=False).save(bp.fpath)
with pytest.warns(RuntimeWarning, match=r"channels\.tsv"):
with (
pytest.warns(RuntimeWarning, match=r"channels\.tsv"),
pytest.warns(RuntimeWarning, match=r"Did not find any eeg\.json"),
pytest.warns(RuntimeWarning, match=r"participants\.tsv file not found"),
):
read_raw_bids(bp) # smoke test

bp.update(task=None)
Expand Down
40 changes: 28 additions & 12 deletions mne_bids/tests/test_write.py
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,10 @@ def test_fif(_bids_validate, tmp_path):
assert op.isfile(op.join(bids_dir, sidecar_basename.basename))

bids_path.update(root=bids_root, datatype="eeg")
with pytest.warns(RuntimeWarning, match="Not setting position"):
with (
pytest.warns(RuntimeWarning, match="Not setting position"),
pytest.warns(RuntimeWarning, match="The unit for channel"),
):
raw2 = read_raw_bids(bids_path=bids_path)
os.remove(op.join(bids_root, "test-raw.fif"))

Expand Down Expand Up @@ -1174,7 +1177,10 @@ def test_ctf(_bids_validate, tmp_path):
write_raw_bids(raw, bids_path, overwrite=True) # test overwrite

_bids_validate(tmp_path)
with pytest.warns(RuntimeWarning, match="Did not find any events"):
with (
pytest.warns(RuntimeWarning, match="Did not find any events"),
pytest.warns(RuntimeWarning, match="The unit for channel"),
):
raw = read_raw_bids(bids_path=bids_path, extra_params=dict(clean_names=False))

# test to check that running again with overwrite == False raises an error
Expand Down Expand Up @@ -1503,11 +1509,7 @@ def test_eegieeg(dir_name, fname, reader, _bids_validate, tmp_path):
with pytest.raises(
RuntimeError, match="'head' coordinate frame must contain nasion"
):
if warning_to_catch[dir_name] is None:
write_raw_bids(**kwargs)
else:
with pytest.warns(RuntimeWarning, match=warning_to_catch[dir_name]):
write_raw_bids(**kwargs)
write_raw_bids(**kwargs)

electrodes_fpath = _find_matching_sidecar(
bids_path, suffix="electrodes", extension=".tsv", on_error="ignore"
Expand Down Expand Up @@ -1866,7 +1868,10 @@ def test_bdf(_bids_validate, tmp_path):
# Now read the raw data back from BIDS, with the tampered TSV, to show
# that the channels.tsv truly influences how read_raw_bids sets ch_types
# in the raw data object
with pytest.warns(RuntimeWarning, match="Fp1 has changed from V .*"):
with (
pytest.warns(RuntimeWarning, match=r"The unit for channel\(s\) Fp1"),
pytest.warns(RuntimeWarning, match=r"The unit for channel\(s\) Status"),
):
raw = read_raw_bids(bids_path=bids_path)
assert coil_type(raw.info, test_ch_idx) == "misc"
with pytest.raises(TypeError, match="unexpected keyword argument 'foo'"):
Expand Down Expand Up @@ -3366,10 +3371,21 @@ def test_convert_eeg_formats(dir_name, format, fname, reader, tmp_path):
):
bids_output_path = write_raw_bids(**kwargs)
else:
with pytest.warns(
RuntimeWarning, match=f"Converting data files to {format} format"
):
bids_output_path = write_raw_bids(**kwargs)
if dir_name in ["EEGLAB", "NihonKohden", "curry"]:
with pytest.warns(
RuntimeWarning, match=f"Converting data files to {format} format"
):
bids_output_path = write_raw_bids(**kwargs)
else:
with (
pytest.warns(
RuntimeWarning, match=f"Converting data files to {format} format"
),
pytest.warns(
RuntimeWarning, match="EDF format requires equal-length data blocks"
),
):
bids_output_path = write_raw_bids(**kwargs)

# channel units should stay the same
raw2 = read_raw_bids(bids_output_path, extra_params=dict(preload=True))
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ full = [
]

# Dependencies for running the test infrastructure
test = ["mne_bids[full]", "pytest < 8", "pytest-cov", "pytest-sugar", "ruff"]
test = ["mne_bids[full]", "pytest", "pytest-cov", "pytest-sugar", "ruff"]

# Dependencies for building the documentation
doc = [
Expand Down

0 comments on commit 8e36555

Please sign in to comment.