Skip to content

Commit

Permalink
Use catch_warnings context manager
Browse files Browse the repository at this point in the history
  • Loading branch information
seberm authored and psss committed Dec 9, 2024
1 parent 6a362c1 commit 6e5882a
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 22 deletions.
10 changes: 6 additions & 4 deletions tmt/steps/report/reportportal.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import tmt.steps.report
import tmt.utils
from tmt.result import ResultOutcome
from tmt.utils import field, format_timestamp, suppress_warning, yaml_to_dict
from tmt.utils import ActionType, catch_warnings, field, format_timestamp, yaml_to_dict

if TYPE_CHECKING:
from tmt._compat.typing import TypeAlias
Expand Down Expand Up @@ -772,11 +772,13 @@ def go(self, *, logger: Optional[tmt.log.Logger] = None) -> None:
self.check_options()

# If SSL verification is disabled, do not print warnings with urllib3
suppress_category = None
warning_filter_action: ActionType = 'default'
if not self.data.ssl_verify:
suppress_category = urllib3.exceptions.InsecureRequestWarning
warning_filter_action = 'ignore'
self.warn("SSL verification is disabled for all requests being made to ReportPortal "
f"instance ({self.data.url}).")

with suppress_warning(suppress_category):
with catch_warnings(
action=warning_filter_action,
category=urllib3.exceptions.InsecureRequestWarning):
self.execute_rp_import()
35 changes: 17 additions & 18 deletions tmt/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,6 @@
from tmt._compat.typing import Self, TypeAlias
from tmt.hardware import Size

# Handle the thread synchronization for the `suppress_warning(...)` context manager
_suppress_warning_lock = RLock()


def configure_optional_constant(default: Optional[int], envvar: str) -> Optional[int]:
"""
Expand Down Expand Up @@ -6286,29 +6283,31 @@ def is_url(url: str) -> bool:
return bool(parsed.scheme and parsed.netloc)


# Handle the thread synchronization for the `catch_warnings(...)` context manager
_catch_warning_lock = RLock()
ActionType = Literal['default', 'error', 'ignore', 'always', 'all', 'module', 'once']


@contextlib.contextmanager
def suppress_warning(category: Optional[type[Warning]]) -> Iterator[None]:
def catch_warnings(
action: ActionType,
category: type[Warning] = Warning) -> Iterator[None]:
"""
Optionally disable the given warning.
Optionally catch the given warning category.
Using this context manager you can catch/suppress given warnings category. These warnings gets
re-enabled/reset with an exit from this context manager.
Using this context manager you can suppress a warning. This warning gets re-enabled with an
exit from this context manager.
This function uses a reentrant lock for thread synchronization to be a thread-safe. That's why
it's wrapping :py:meth:`warnings.catch_warnings` instead of using it directly.
The example can be suppressing of the urllib insecure request warning:
.. code-block:: python
with suppress_warning(urllib3.exceptions.InsecureRequestWarning):
with catch_warnings('ignore', urllib3.exceptions.InsecureRequestWarning):
...
"""
if category is not None:
with _suppress_warning_lock:
try:
warnings.simplefilter('ignore', category)
yield
finally:
# Reset the warning to its default for a specific category
warnings.simplefilter('default', category)
else:
with _catch_warning_lock, warnings.catch_warnings():
warnings.simplefilter(action=action, category=category)
yield

0 comments on commit 6e5882a

Please sign in to comment.