"""Central handling of warnings for the myst-nb extension.""" from __future__ import annotations from enum import Enum from typing import Sequence from docutils import nodes from myst_parser.warnings_ import MystWarnings from myst_parser.warnings_ import create_warning as myst_parser_create_warnings __all__ = [ "MystWarnings", "MystNBWarnings", "create_warning", ] class MystNBWarnings(Enum): """MySTNB warning types.""" LEXER = "lexer" """Issue resolving lexer""" FIG_CAPTION = "fig_caption" """Issue resoliving figure caption""" MIME_TYPE = "mime_type" """Issue resolving MIME type""" OUTPUT_TYPE = "output_type" """Issue resolving Output type""" CELL_METADATA_KEY = "cell_metadata_key" """Issue with a key in a cell's `metadata` dictionary.""" CELL_CONFIG = "cell_config" """Issue with a cell's configuration or metadata.""" def _is_suppressed_warning( type: str, subtype: str, suppress_warnings: Sequence[str] ) -> bool: """Check whether the warning is suppressed or not. Mirrors: https://github.com/sphinx-doc/sphinx/blob/47d9035bca9e83d6db30a0726a02dc9265bd66b1/sphinx/util/logging.py """ if type is None: return False subtarget: str | None for warning_type in suppress_warnings: if "." in warning_type: target, subtarget = warning_type.split(".", 1) else: target, subtarget = warning_type, None if target == type and subtarget in (None, subtype, "*"): return True return False def create_warning( document: nodes.document, message: str, subtype: MystNBWarnings | MystWarnings, *, line: int | None = None, append_to: nodes.Element | None = None, ) -> nodes.system_message | None: """Generate a warning, logging if it is necessary. If the warning type is listed in the ``suppress_warnings`` configuration, then ``None`` will be returned and no warning logged. """ # Pass off Myst Parser warnings to that package if isinstance(subtype, MystWarnings): myst_parser_create_warnings( document=document, message=message, subtype=subtype, line=line, append_to=append_to, ) wtype = "myst-nb" # figure out whether to suppress the warning, if sphinx is available, # it will have been set up by the Sphinx environment, # otherwise we will use the configuration set by docutils suppress_warnings: Sequence[str] = [] try: suppress_warnings = document.settings.env.app.config.suppress_warnings except AttributeError: suppress_warnings = document.settings.myst_suppress_warnings or [] if _is_suppressed_warning(wtype, subtype.value, suppress_warnings): return None kwargs = {"line": line} if line is not None else {} message = f"{message} [{wtype}.{subtype.value}]" msg_node = document.reporter.warning(message, **kwargs) if append_to is not None: append_to.append(msg_node) return msg_node