diff --git a/zulipterminal/core.py b/zulipterminal/core.py index 6e6aae1f76..8fcab1086a 100644 --- a/zulipterminal/core.py +++ b/zulipterminal/core.py @@ -11,7 +11,9 @@ import zulip from zulipterminal.config.themes import ThemeSpec -from zulipterminal.helper import MACOS, WSL, Message, asynch, near_message_url +from zulipterminal.helper import ( + MACOS, WSL, Message, asynch, near_message_url, suppress_output, +) from zulipterminal.model import Model from zulipterminal.ui import Screen, View from zulipterminal.ui_tools.utils import create_msg_box_list @@ -281,7 +283,9 @@ def view_in_browser(self, message: Message) -> None: self.message_url = near_message_url(self.model.server_url[:-1], message) - webbrowser.open(self.message_url) + with suppress_output(): + # Suppress anything on stdout & stderr when opening the browser. + webbrowser.open(self.message_url) def _finalize_show(self, w_list: List[Any]) -> None: focus_position = self.model.get_focus_in_current_narrow() diff --git a/zulipterminal/helper.py b/zulipterminal/helper.py index 16fc0960fd..129fca3389 100644 --- a/zulipterminal/helper.py +++ b/zulipterminal/helper.py @@ -5,13 +5,14 @@ import time import urllib from collections import OrderedDict, defaultdict +from contextlib import contextmanager from functools import wraps from itertools import chain, combinations from re import ASCII, match from threading import Thread from typing import ( - Any, Callable, DefaultDict, Dict, FrozenSet, Iterable, List, Set, Tuple, - TypeVar, Union, + Any, Callable, DefaultDict, Dict, FrozenSet, Iterable, Iterator, List, Set, + Tuple, TypeVar, Union, ) import lxml.html @@ -650,3 +651,22 @@ def near_message_url(server_url: str, message: Message) -> str: else: url = near_pm_message_url(server_url, message) return url + + +@contextmanager +def suppress_output() -> Iterator[None]: + """ + Context manager to redirect stdout and stderr to /dev/null. + + Adapted from https://stackoverflow.com/a/2323563. + """ + out = os.dup(1) + err = os.dup(2) + os.close(1) + os.close(2) + os.open(os.devnull, os.O_RDWR) + try: + yield + finally: + os.dup2(out, 1) + os.dup2(err, 2)