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 # doctes
(matching)
| 68 | |
| 69 | @contextmanager |
| 70 | def expected_warnings(matching): |
| 71 | r"""Context for use in testing to catch known warnings matching regexes |
| 72 | |
| 73 | Parameters |
| 74 | ---------- |
| 75 | matching : list of strings or compiled regexes |
| 76 | Regexes for the desired warning to catch |
| 77 | |
| 78 | Examples |
| 79 | -------- |
| 80 | >>> from skimage import data, img_as_ubyte, img_as_float # doctest: +SKIP |
| 81 | >>> with expected_warnings(["precision loss"]): # doctest: +SKIP |
| 82 | ... d = img_as_ubyte(img_as_float(data.coins())) # doctest: +SKIP |
| 83 | |
| 84 | Notes |
| 85 | ----- |
| 86 | Uses `all_warnings` to ensure all warnings are raised. |
| 87 | Upon exiting, it checks the recorded warnings for the desired matching |
| 88 | pattern(s). |
| 89 | Raises a ValueError if any match was not found or an unexpected |
| 90 | warning was raised. |
| 91 | Allows for three types of behaviors: "and", "or", and "optional" matches. |
| 92 | This is done to accommodate different build environments or loop conditions |
| 93 | that may produce different warnings. The behaviors can be combined. |
| 94 | If you pass multiple patterns, you get an orderless "and", where all of the |
| 95 | warnings must be raised. |
| 96 | If you use the "|" operator in a pattern, you can catch one of several warnings. |
| 97 | Finally, you can use "|\A\Z" in a pattern to signify it as optional. |
| 98 | """ |
| 99 | with all_warnings() as w: |
| 100 | # enter context |
| 101 | yield w |
| 102 | # exited user context, check the recorded warnings |
| 103 | remaining = [m for m in matching if r"\A\Z" not in m.split("|")] |
| 104 | for warn in w: |
| 105 | found = False |
| 106 | for match in matching: |
| 107 | if re.search(match, str(warn.message)) is not None: |
| 108 | found = True |
| 109 | if match in remaining: |
| 110 | remaining.remove(match) |
| 111 | if not found: |
| 112 | raise ValueError("Unexpected warning: %s" % str(warn.message)) |
| 113 | if len(remaining) > 0: |
| 114 | msg = "No warning raised matching:\n%s" % "\n".join(remaining) |
| 115 | raise ValueError(msg) |
searching dependent graphs…