From e9d2919142b1ea2655d4574279b8ca569204ed97 Mon Sep 17 00:00:00 2001 From: isabelizimm Date: Fri, 19 Apr 2024 10:31:33 -0400 Subject: [PATCH] call original showwarning, add exc count --- .../positron_ipykernel/positron_ipkernel.py | 77 +++++++------------ .../tests/test_positron_ipkernel.py | 9 +-- 2 files changed, 32 insertions(+), 54 deletions(-) diff --git a/extensions/positron-python/python_files/positron/positron_ipykernel/positron_ipkernel.py b/extensions/positron-python/python_files/positron/positron_ipykernel/positron_ipkernel.py index 4dba3b1f01e..2f21952d9e5 100644 --- a/extensions/positron-python/python_files/positron/positron_ipykernel/positron_ipkernel.py +++ b/extensions/positron-python/python_files/positron/positron_ipykernel/positron_ipkernel.py @@ -191,6 +191,9 @@ def connection_show(self, line: str) -> None: _traceback_file_link_re = re.compile(r"^(File \x1b\[\d+;\d+m)(.+):(\d+)") +# keep reference to original showwarning +original_showwarning = warnings.showwarning + class PositronShell(ZMQInteractiveShell): kernel: PositronIPyKernel @@ -420,8 +423,8 @@ def __init__(self, **kwargs) -> None: # Register display publisher hooks self.shell.display_pub.register_hook(self.widget_hook) - warnings.showwarning = _showwarning - warnings.formatwarning = _formatwarning + warnings.showwarning = self._showwarning + # Ignore warnings that the user can't do anything about warnings.filterwarnings( "ignore", @@ -471,6 +474,29 @@ async def do_shutdown(self, restart: bool) -> JsonRecord: # type: ignore Report # points to the same underlying asyncio loop). return dict(status="ok", restart=restart) + # monkey patching warning.showwarning is recommended by the official documentation + # https://docs.python.org/3/library/warnings.html#warnings.showwarning + def _showwarning(self, message, category, filename, lineno, file=None, line=None): + # if coming from one of our files, log and don't send to user + positron_files_path = Path(__file__).parent + + if str(positron_files_path) in str(filename): + msg = f"{filename}-{lineno}: {category}: {message}" + logger.warning(msg) + return + + # Check if the filename refers to a cell in the Positron Console. + # We use the fact that ipykernel sets the filename to a path starting in the root temporary + # directory. We can't determine the full filename since it depends on the cell's code which + # is unknown at this point. See ipykernel.compiler.XCachingCompiler.get_code_name. + console_dir = get_tmp_directory() + if console_dir in str(filename): + filename = f"" + + msg = warnings.WarningMessage(message, category, filename, lineno, file, line) + + return original_showwarning(message, category, filename, lineno, file, line) # type: ignore reportAttributeAccessIssue + class PositronIPKernelApp(IPKernelApp): kernel: PositronIPyKernel @@ -526,50 +552,3 @@ def _link(uri: str, label: str, params: Dict[str, str] = {}) -> str: Create a hyperlink with the given label, URI, and params. """ return _start_hyperlink(uri, params) + label + _end_hyperlink() - - -# monkey patching warning.showwarning is recommended by the official documentation -# https://docs.python.org/3/library/warnings.html#warnings.showwarning -def _showwarning(message, category, filename, lineno, file=None, line=None): - # if coming from one of our files, log and don't send to user - positron_files_path = Path("python_files", "positron", "positron_ipykernel") - - if str(positron_files_path) in str(filename): - msg = f"{category}: {message}" - logger.warning(msg) - return - - # Check if the filename refers to a cell in the Positron Console. - # We use the fact that ipykernel sets the filename to a path starting in the root temporary - # directory. We can't determine the full filename since it depends on the cell's code which - # is unknown at this point. See ipykernel.compiler.XCachingCompiler.get_code_name. - console_dir = get_tmp_directory() - if console_dir in str(filename): - filename = "POSITRON_CONSOLE" - - msg = warnings.WarningMessage(message, category, filename, lineno, file, line) - - return warnings._showwarnmsg_impl(msg) # type: ignore reportAttributeAccessIssue - - -# vendored as-is from warnings -def _formatwarning(message, category, filename, lineno, line=None): - # --- Start Positron --- - if filename == "POSITRON_CONSOLE": - s = f"{category.__name__}: {message}\n" - # --- End Positron --- - else: - s = "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message) - if line is None: - try: - import linecache - - line = linecache.getline(filename, lineno) - except Exception: - # When a warning is logged during Python shutdown, linecache - # and the import machinery don't work anymore - line = None - if line: - line = line.strip() - s += " %s\n" % line - return s diff --git a/extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_positron_ipkernel.py b/extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_positron_ipkernel.py index 7e8442ebe30..4d4de9c4573 100644 --- a/extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_positron_ipkernel.py +++ b/extensions/positron-python/python_files/positron/positron_ipykernel/tests/test_positron_ipkernel.py @@ -12,7 +12,6 @@ from IPython.utils.syspathcontext import prepended_to_syspath from ipykernel.compiler import get_tmp_directory -from positron_ipykernel.positron_ipkernel import _showwarning from positron_ipykernel.help import help from positron_ipykernel.session_mode import SessionMode from positron_ipykernel.utils import alias_home @@ -328,18 +327,18 @@ def test_console_warning(shell: PositronShell, warning_kwargs): filename = get_tmp_directory() + os.sep + "12345678.py" with pytest.warns() as record: - _showwarning(filename=filename, **warning_kwargs) + shell.kernel._showwarning(filename=filename, **warning_kwargs) assert len(record) == 1 - assert record[0].filename == "POSITRON_CONSOLE" + assert record[0].filename == "" assert record[0].message == "this is a warning" -def test_console_warning_logger(caplog, warning_kwargs): +def test_console_warning_logger(shell: PositronShell, caplog, warning_kwargs): """ Check that Positron files are sent to logs """ with caplog.at_level(logging.WARNING): - _showwarning(filename=Path(__file__), **warning_kwargs) + shell.kernel._showwarning(filename=Path(__file__), **warning_kwargs) assert "this is a warning" in caplog.text