Emit a warning with trace outside the mne namespace. This function takes arguments like warnings.warn, and sends messages using both ``warnings.warn`` and ``logger.warn``. Warnings can be generated deep within nested function calls. In order to provide a more helpful warning, this f
(message, category=RuntimeWarning, module="mne", ignore_namespaces=("mne",))
| 367 | |
| 368 | |
| 369 | def warn(message, category=RuntimeWarning, module="mne", ignore_namespaces=("mne",)): |
| 370 | """Emit a warning with trace outside the mne namespace. |
| 371 | |
| 372 | This function takes arguments like warnings.warn, and sends messages |
| 373 | using both ``warnings.warn`` and ``logger.warn``. Warnings can be |
| 374 | generated deep within nested function calls. In order to provide a |
| 375 | more helpful warning, this function traverses the stack until it |
| 376 | reaches a frame outside the ``mne`` namespace that caused the error. |
| 377 | |
| 378 | Parameters |
| 379 | ---------- |
| 380 | message : str |
| 381 | Warning message. |
| 382 | category : instance of Warning |
| 383 | The warning class. Defaults to ``RuntimeWarning``. |
| 384 | module : str |
| 385 | The name of the module emitting the warning. |
| 386 | ignore_namespaces : list of str |
| 387 | Namespaces to ignore when traversing the stack. |
| 388 | |
| 389 | .. versionadded:: 0.24 |
| 390 | """ |
| 391 | root_dirs = [importlib.import_module(ns) for ns in ignore_namespaces] |
| 392 | root_dirs = [op.dirname(ns.__file__) for ns in root_dirs] |
| 393 | frame = None |
| 394 | if logger.level <= logging.WARNING: |
| 395 | frame = inspect.currentframe() |
| 396 | while frame: |
| 397 | fname = frame.f_code.co_filename |
| 398 | lineno = frame.f_lineno |
| 399 | # in verbose dec |
| 400 | if not _verbose_dec_re.search(fname): |
| 401 | # treat tests as scripts |
| 402 | # and don't capture unittest/case.py (assert_raises) |
| 403 | if ( |
| 404 | not ( |
| 405 | any(fname.startswith(rd) for rd in root_dirs) |
| 406 | or ("unittest" in fname and "case" in fname) |
| 407 | ) |
| 408 | or op.basename(op.dirname(fname)) == "tests" |
| 409 | ): |
| 410 | break |
| 411 | frame = frame.f_back |
| 412 | del frame |
| 413 | # We need to use this instead of warn(message, category, stacklevel) |
| 414 | # because we move out of the MNE stack, so warnings won't properly |
| 415 | # recognize the module name (and our warnings.simplefilter will fail) |
| 416 | warnings.warn_explicit( |
| 417 | message, |
| 418 | category, |
| 419 | fname, |
| 420 | lineno, |
| 421 | module, |
| 422 | globals().get("__warningregistry__", {}), |
| 423 | ) |
| 424 | # To avoid a duplicate warning print, we only emit the logger.warning if |
| 425 | # one of the handlers is a FileHandler. See gh-5592 |
| 426 | # But it's also nice to be able to do: |
no outgoing calls