diff options
author | robot-contrib <robot-contrib@yandex-team.com> | 2023-10-19 17:11:31 +0300 |
---|---|---|
committer | robot-contrib <robot-contrib@yandex-team.com> | 2023-10-19 18:26:04 +0300 |
commit | b9fe236a503791a3a7b37d4ef5f466225218996c (patch) | |
tree | c2f80019399b393ddf0450d0f91fc36478af8bea /contrib/python/traitlets/py3/tests/_warnings.py | |
parent | 44dd27d0a2ae37c80d97a95581951d1d272bd7df (diff) | |
download | ydb-b9fe236a503791a3a7b37d4ef5f466225218996c.tar.gz |
Update contrib/python/traitlets/py3 to 5.11.2
Diffstat (limited to 'contrib/python/traitlets/py3/tests/_warnings.py')
-rw-r--r-- | contrib/python/traitlets/py3/tests/_warnings.py | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/contrib/python/traitlets/py3/tests/_warnings.py b/contrib/python/traitlets/py3/tests/_warnings.py new file mode 100644 index 00000000000..e3c3a0ac6d6 --- /dev/null +++ b/contrib/python/traitlets/py3/tests/_warnings.py @@ -0,0 +1,114 @@ +# From scikit-image: https://github.com/scikit-image/scikit-image/blob/c2f8c4ab123ebe5f7b827bc495625a32bb225c10/skimage/_shared/_warnings.py +# Licensed under modified BSD license + +__all__ = ["all_warnings", "expected_warnings"] + +import inspect +import os +import re +import sys +import warnings +from contextlib import contextmanager +from unittest import mock + + +@contextmanager +def all_warnings(): + """ + Context for use in testing to ensure that all warnings are raised. + Examples + -------- + >>> import warnings + >>> def foo(): + ... warnings.warn(RuntimeWarning("bar")) + + We raise the warning once, while the warning filter is set to "once". + Hereafter, the warning is invisible, even with custom filters: + >>> with warnings.catch_warnings(): + ... warnings.simplefilter('once') + ... foo() + + We can now run ``foo()`` without a warning being raised: + >>> from numpy.testing import assert_warns # doctest: +SKIP + >>> foo() # doctest: +SKIP + + To catch the warning, we call in the help of ``all_warnings``: + >>> with all_warnings(): # doctest: +SKIP + ... assert_warns(RuntimeWarning, foo) + """ + + # Whenever a warning is triggered, Python adds a __warningregistry__ + # member to the *calling* module. The exercize here is to find + # and eradicate all those breadcrumbs that were left lying around. + # + # We proceed by first searching all parent calling frames and explicitly + # clearing their warning registries (necessary for the doctests above to + # pass). Then, we search for all submodules of skimage and clear theirs + # as well (necessary for the skimage test suite to pass). + + frame = inspect.currentframe() + if frame: + for f in inspect.getouterframes(frame): + f[0].f_locals["__warningregistry__"] = {} + del frame + + for _, mod in list(sys.modules.items()): + try: + mod.__warningregistry__.clear() + except AttributeError: + pass + + with warnings.catch_warnings(record=True) as w, mock.patch.dict( + os.environ, {"TRAITLETS_ALL_DEPRECATIONS": "1"} + ): + warnings.simplefilter("always") + yield w + + +@contextmanager +def expected_warnings(matching): + r"""Context for use in testing to catch known warnings matching regexes + + Parameters + ---------- + matching : list of strings or compiled regexes + Regexes for the desired warning to catch + + Examples + -------- + >>> from skimage import data, img_as_ubyte, img_as_float # doctest: +SKIP + >>> with expected_warnings(["precision loss"]): # doctest: +SKIP + ... d = img_as_ubyte(img_as_float(data.coins())) # doctest: +SKIP + + Notes + ----- + Uses `all_warnings` to ensure all warnings are raised. + Upon exiting, it checks the recorded warnings for the desired matching + pattern(s). + Raises a ValueError if any match was not found or an unexpected + warning was raised. + Allows for three types of behaviors: "and", "or", and "optional" matches. + This is done to accomodate different build enviroments or loop conditions + that may produce different warnings. The behaviors can be combined. + If you pass multiple patterns, you get an orderless "and", where all of the + warnings must be raised. + If you use the "|" operator in a pattern, you can catch one of several warnings. + Finally, you can use "|\A\Z" in a pattern to signify it as optional. + """ + with all_warnings() as w: + # enter context + yield w + # exited user context, check the recorded warnings + remaining = [m for m in matching if r"\A\Z" not in m.split("|")] + for warn in w: + found = False + for match in matching: + if re.search(match, str(warn.message)) is not None: + found = True + if match in remaining: + remaining.remove(match) + if not found: + raise ValueError("Unexpected warning: %s" % str(warn.message)) + if len(remaining) > 0: + msg = "No warning raised matching:\n%s" % "\n".join(remaining) + raise ValueError(msg) |