Skip to content
New issue

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

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

Already on GitHub? # to your account

Improve warning handling #243

Merged
merged 14 commits into from
Apr 3, 2024
Merged
2 changes: 1 addition & 1 deletion doc/changes/latest.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@
Version 1.4
===========

- xxx
- Fix handling of warnings through the logger (:pr:`243` by `Mathieu Scheltienne`_)
12 changes: 4 additions & 8 deletions mne_lsl/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
from . import datasets # noqa: F401
from . import lsl # noqa: F401
from . import player # noqa: F401
from . import stream # noqa: F401
from . import utils # noqa: F401
from ._version import __version__ # noqa: F401
from .utils.config import sys_info # noqa: F401
from .utils.logs import add_file_handler, logger, set_log_level # noqa: F401
from . import datasets, lsl, player, stream, utils
from ._version import __version__
from .utils.config import sys_info
from .utils.logs import add_file_handler, set_log_level
3 changes: 2 additions & 1 deletion mne_lsl/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
from mne.io import read_raw_fif
from pytest import fixture

from mne_lsl import logger, set_log_level
from mne_lsl import set_log_level
from mne_lsl.datasets import testing
from mne_lsl.lsl import StreamInlet, StreamOutlet
from mne_lsl.utils.logs import logger

if TYPE_CHECKING:
from pathlib import Path
Expand Down
3 changes: 1 addition & 2 deletions mne_lsl/datasets/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
from . import sample # noqa: F401
from . import testing # noqa: F401
from . import sample, testing
13 changes: 4 additions & 9 deletions mne_lsl/lsl/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
from .functions import ( # noqa: F401
library_version,
local_clock,
protocol_version,
resolve_streams,
)
from .stream_info import StreamInfo # noqa: F401
from .stream_inlet import StreamInlet # noqa: F401
from .stream_outlet import StreamOutlet # noqa: F401
from .functions import library_version, local_clock, protocol_version, resolve_streams
from .stream_info import StreamInfo
from .stream_inlet import StreamInlet
from .stream_outlet import StreamOutlet
33 changes: 6 additions & 27 deletions mne_lsl/lsl/load_liblsl.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,14 @@
from pathlib import Path
from shutil import move, rmtree
from typing import TYPE_CHECKING
from warnings import warn

import pooch
import requests

from .._version import __version__
from ..utils._checks import ensure_path
from ..utils._path import walk
from ..utils.logs import logger
from ..utils.logs import logger, warn

if TYPE_CHECKING:
from typing import Optional, Union
Expand Down Expand Up @@ -152,8 +151,6 @@ def _load_liblsl_mne_lsl(*, folder: Path = _LIB_FOLDER) -> Optional[str]:
warn(
f"The previously downloaded LIBLSL '{libpath.name}' in "
f"'{libpath.parent}' could not be loaded. It will be removed.",
RuntimeWarning,
stacklevel=2,
)
libpath.unlink(missing_ok=False)
continue
Expand All @@ -169,8 +166,6 @@ def _load_liblsl_mne_lsl(*, folder: Path = _LIB_FOLDER) -> Optional[str]:
f"is outdated. The version is {version // 100}.{version % 100} while the "
"minimum version required by MNE-LSL is "
f"{_VERSION_MIN // 100}.{_VERSION_MIN % 100}. It will be removed.",
RuntimeWarning,
stacklevel=2,
)
libpath.unlink(missing_ok=False)
return None
Expand Down Expand Up @@ -353,11 +348,7 @@ def _pooch_processor_liblsl(fname: str, action: str, pooch: Pooch) -> str:
if line.startswith("Depends:")
]
if len(lines) != 1: # pragma: no cover
warn(
"Dependencies from debian liblsl package could not be parsed.",
RuntimeWarning,
stacklevel=2,
)
warn("Dependencies from debian liblsl package could not be parsed.")
else:
logger.info(
"Attempting to retrieve liblsl from the release page. It requires %s.",
Expand Down Expand Up @@ -419,17 +410,11 @@ def _is_valid_libpath(libpath: str) -> bool:
warn(
f"The LIBLSL '{libpath}' ends with '{libpath.suffix}' which is "
f"different from the expected extension '{_PLATFORM_SUFFIXES[_PLATFORM]}' "
f"for {_PLATFORM} based OS.",
RuntimeWarning,
stacklevel=2,
f"for {_PLATFORM} based OS."
)
return False
if not libpath.exists():
warn(
f"The LIBLSL '{libpath}' does not exist.",
RuntimeWarning,
stacklevel=2,
)
warn(f"The LIBLSL '{libpath}' does not exist.")
return False
return True

Expand Down Expand Up @@ -463,11 +448,7 @@ def _attempt_load_liblsl(
except OSError:
version = None
if issue_warning:
warn(
f"The LIBLSL '{libpath}' can not be loaded.",
RuntimeWarning,
stacklevel=2,
)
warn(f"The LIBLSL '{libpath}' can not be loaded.")
return libpath, version


Expand Down Expand Up @@ -499,9 +480,7 @@ def _is_valid_version(
warn(
f"The LIBLSL '{libpath}' is outdated. The version is "
f"{version // 100}.{version % 100} while the minimum version required "
f"by MNE-LSL is {_VERSION_MIN // 100}.{_VERSION_MIN % 100}.",
RuntimeWarning,
stacklevel=2,
f"by MNE-LSL is {_VERSION_MIN // 100}.{_VERSION_MIN % 100}."
)
return False
return True
Expand Down
50 changes: 21 additions & 29 deletions mne_lsl/lsl/stream_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from mne.utils import check_version

from ..utils._checks import check_type, check_value, ensure_int
from ..utils.logs import logger
from ..utils.logs import warn
from ..utils.meas_info import create_info
from ._utils import XMLElement
from .constants import fmt2idx, fmt2numpy, idx2fmt, numpy2fmt, string2fmt
Expand Down Expand Up @@ -372,9 +372,9 @@ def get_channel_info(self) -> Info:
info["chs"][k]["range"] = 1.0
info["chs"][k]["cal"] = float(range_cal)
except ValueError:
logger.warning(
"Could not cast 'range_cal' factor %s to float.",
range_cal,
warn(
f"Could not cast 'range_cal' factor {range_cal} to "
"float.",
)
for k, loc in enumerate(locs):
info["chs"][k]["loc"] = loc
Expand All @@ -390,11 +390,9 @@ def get_channel_info(self) -> Info:
try:
info[name] = float(value)
except ValueError:
logger.warning(
"Could not cast '%s' %s to float.", name, value
)
warn(f"Could not cast '{name}' {value} to float.")
elif not filters.empty() and self.sfreq == 0:
logger.warning(
warn(
"Node 'filters' found in the description of an irregularly sampled "
"stream. This is inconsistent and will be skipped."
)
Expand Down Expand Up @@ -481,10 +479,9 @@ def _get_channel_info(self, name: str) -> Optional[list[str]]:
if all(ch_info is None for ch_info in ch_infos):
return None
if len(ch_infos) != self.n_channels:
logger.warning(
"The stream description contains %i elements for %i channels.",
len(ch_infos),
self.n_channels,
warn(
f"The stream description contains {len(ch_infos)} elements for "
f"{self.n_channels} channels."
)
return ch_infos

Expand All @@ -496,16 +493,14 @@ def _get_channel_projectors(self) -> list[Projection]:
while not projector.empty():
desc = projector.child("desc").first_child().value()
if len(desc) == 0:
logger.warning(
"An SSP projector without description was found. Skipping."
)
warn("An SSP projector without description was found. Skipping.")
projector = projector.next_sibling()
continue
kind = projector.child("kind").first_child().value()
try:
kind = int(kind)
except ValueError:
logger.warning("Could not cast the SSP kind %s to integer.", kind)
warn(f"Could not cast the SSP kind {kind} to integer.")
projector = projector.next_sibling()
continue

Expand All @@ -516,7 +511,7 @@ def _get_channel_projectors(self) -> list[Projection]:
while not ch.empty():
ch_name = ch.child("label").first_child().value()
if len(ch_name) == 0:
logger.warning(
warn(
"SSP projector has an empty-channel label. The channel will "
"be skipped."
)
Expand All @@ -526,10 +521,9 @@ def _get_channel_projectors(self) -> list[Projection]:
try:
ch_data = float(ch_data)
except ValueError:
logger.warning(
"Could not cast the SSP value %s for channel %s to float.",
ch_data,
ch_name,
warn(
f"Could not cast the SSP value {ch_data} for channel {ch_name} "
"to float.",
)
ch.next_sibling()
continue
Expand Down Expand Up @@ -573,7 +567,7 @@ def _get_digitization(self) -> list[DigPoint]:
try:
ident = int(ident)
except ValueError:
logger.warning("Could not cast 'ident' %s to integer.", ident)
warn(f"Could not cast 'ident' {ident} to integer.")
point = point.next_sibling()
continue
loc = point.child("loc")
Expand All @@ -584,7 +578,7 @@ def _get_digitization(self) -> list[DigPoint]:
try:
r = np.array([float(elt) for elt in r], dtype=np.float32)
except ValueError:
logger.warning("Could not cast dig point location %s to float.", r)
warn(f"Could not cast dig point location {r} to float.")
point = point.next_sibling()
continue
dig_points.append(
Expand Down Expand Up @@ -829,13 +823,11 @@ def _get_fiff_int_named(
value = mapping[idx]
return value
except ValueError:
logger.warning("Could not cast '%s' %s to integer.", name, value)
warn(f"Could not cast '{name}' {value} to integer.")
except KeyError:
logger.warning(
"Could not convert '%s' %i to a known FIFF code: %s.",
name,
int(value),
tuple(mapping.keys()),
warn(
f"Could not convert '{name}' {int(value)} to a known FIFF "
"code: {tuple(mapping.keys())}.",
)
return None

Expand Down
8 changes: 4 additions & 4 deletions mne_lsl/lsl/stream_inlet.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from ..utils._checks import check_type, check_value, ensure_int
from ..utils._docs import copy_doc
from ..utils.logs import logger
from ..utils.logs import warn
from ._utils import check_timeout, free_char_p_array_memory, handle_error
from .constants import fmt2numpy, fmt2pull_chunk, fmt2pull_sample, post_processing_flags
from .load_liblsl import lib
Expand Down Expand Up @@ -151,14 +151,14 @@ def __del__(self):
try:
self.close_stream()
except Exception as exc:
logger.warning("Error closing stream: %s", str(exc))
warn(f"Error closing stream: {str(exc)}")
self._stream_is_open = False
with self._lock:
obj, self._obj = self._obj, None
try:
lib.lsl_destroy_inlet(obj)
except Exception as exc:
logger.warning("Error destroying inlet: %s", str(exc))
warn(f"Error destroying inlet: {str(exc)}")

def open_stream(self, timeout: Optional[float] = None) -> None:
"""Subscribe to a data stream.
Expand Down Expand Up @@ -208,7 +208,7 @@ def close_stream(self) -> None:
not arrive at the inlet. c.f. this
`github issue <https://github.com/sccn/liblsl/issues/180>`_.
"""
if not self._stream_is_open:
if hasattr(self, "_stream_is_open") and not self._stream_is_open:
return
with self._lock:
lib.lsl_close_stream(self._obj)
Expand Down
15 changes: 4 additions & 11 deletions mne_lsl/lsl/stream_outlet.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@
from ctypes import c_char_p, c_double, c_int, c_long, c_void_p
from threading import Lock
from typing import TYPE_CHECKING
from warnings import warn

import numpy as np

from ..utils._checks import check_type, ensure_int
from ..utils._docs import copy_doc
from ..utils.logs import logger
from ..utils.logs import warn
from ._utils import check_timeout, handle_error
from .constants import fmt2numpy, fmt2push_chunk, fmt2push_chunk_n, fmt2push_sample
from .load_liblsl import lib
Expand Down Expand Up @@ -105,7 +104,7 @@ def __del__(self):
try:
lib.lsl_destroy_outlet(obj)
except Exception as exc:
logger.warning("Error destroying outlet: %s", str(exc))
warn("Error destroying outlet: %s", str(exc))

def push_sample(
self,
Expand Down Expand Up @@ -217,11 +216,7 @@ def push_chunk(
data_buffer = (self._dtype * n_elements).from_buffer(x)

if n_samples == 1:
warn(
"A single sample is pushed. Consider using push_sample().",
RuntimeWarning,
stacklevel=2,
)
warn("A single sample is pushed. Consider using push_sample().")

# convert timestamps to the corresponding ctype
if timestamp is None:
Expand Down Expand Up @@ -256,9 +251,7 @@ def push_chunk(
warn(
"The stream is irregularly sampled and timestamp is a float and "
"will be applied to all samples. Consider using an array of "
"timestamps to provide the individual timestamps for each sample.",
RuntimeWarning,
stacklevel=2,
"timestamps to provide the individual timestamps for each sample."
)
timestamp_c = c_double(timestamp)
liblsl_push_chunk_func = self._do_push_chunk
Expand Down
Loading
Loading