From b61c6cb378ca0e9504ca3c2d43b306893a7f184d Mon Sep 17 00:00:00 2001 From: Sergey Noritsyn Date: Mon, 1 Dec 2025 23:21:03 -0500 Subject: [PATCH] Add enable_link_path parameter to disable OSC 8 hyperlinks - Addresses Issue #3896 --- rich/console.py | 6 ++++++ tests/test_log.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/rich/console.py b/rich/console.py index 994adfc069..5492b53dda 100644 --- a/rich/console.py +++ b/rich/console.py @@ -611,6 +611,7 @@ class Console: highlight (bool, optional): Enable automatic highlighting. Defaults to True. log_time (bool, optional): Boolean to enable logging of time by :meth:`log` methods. Defaults to True. log_path (bool, optional): Boolean to enable the logging of the caller by :meth:`log`. Defaults to True. + enable_link_path (bool, optional): Boolean to enable terminal hyperlinks in file paths logged by :meth:`log`. Defaults to True. log_time_format (Union[str, TimeFormatterCallable], optional): If ``log_time`` is enabled, either string for strftime or callable that formats the time. Defaults to "[%X] ". highlighter (HighlighterType, optional): Default highlighter. legacy_windows (bool, optional): Enable legacy Windows mode, or ``None`` to auto detect. Defaults to ``None``. @@ -648,6 +649,7 @@ def __init__( highlight: bool = True, log_time: bool = True, log_path: bool = True, + enable_link_path: bool = True, log_time_format: Union[str, FormatTimeCallable] = "[%X]", highlighter: Optional["HighlighterType"] = ReprHighlighter(), legacy_windows: Optional[bool] = None, @@ -723,6 +725,7 @@ def __init__( show_path=log_path, time_format=log_time_format, ) + self.enable_link_path = enable_link_path self.highlighter: HighlighterType = highlighter or _null_highlighter self.safe_box = safe_box self.get_datetime = get_datetime or datetime.now @@ -1977,6 +1980,9 @@ def log( filename, line_no, locals = self._caller_frame_info(_stack_offset) link_path = None if filename.startswith("<") else os.path.abspath(filename) + # Disable hyperlinks if enable_link_path is False, but keep the path text + if not self.enable_link_path: + link_path = None path = filename.rpartition(os.sep)[-1] if log_locals: locals_map = { diff --git a/tests/test_log.py b/tests/test_log.py index 37fdda4621..b5b8bd27ec 100644 --- a/tests/test_log.py +++ b/tests/test_log.py @@ -59,6 +59,48 @@ def test_justify(): assert result == " foo\n" +def test_enable_link_path(): + """Test that enable_link_path=False disables hyperlinks but keeps path text.""" + console = Console( + file=io.StringIO(), + width=80, + force_terminal=True, + log_time_format="[TIME]", + color_system="truecolor", + legacy_windows=False, + enable_link_path=False, # Disable hyperlinks + ) + console.log("Test message") + output = console.file.getvalue() + + # Should NOT contain OSC 8 hyperlink escape sequences + assert "\x1b]8;" not in output + + # Should still contain the path text (filename) + assert "test_log.py" in output + + +def test_enable_link_path_default(): + """Test that enable_link_path defaults to True (hyperlinks enabled).""" + console = Console( + file=io.StringIO(), + width=80, + force_terminal=True, + log_time_format="[TIME]", + color_system="truecolor", + legacy_windows=False, + # enable_link_path not specified, should default to True + ) + console.log("Test message") + output = console.file.getvalue() + + # Should contain OSC 8 hyperlink escape sequences + assert "\x1b]8;" in output + + # Should also contain the path text + assert "test_log.py" in output + + if __name__ == "__main__": render = render_log() print(render)