A context manager to record raised warnings. Each recorded warning is an instance of :class:`warnings.WarningMessage`. Adapted from `warnings.catch_warnings`. .. note:: ``DeprecationWarning`` and ``PendingDeprecationWarning`` are treated differently; see :ref:`ensuring
| 173 | |
| 174 | |
| 175 | class WarningsRecorder(warnings.catch_warnings): |
| 176 | """A context manager to record raised warnings. |
| 177 | |
| 178 | Each recorded warning is an instance of :class:`warnings.WarningMessage`. |
| 179 | |
| 180 | Adapted from `warnings.catch_warnings`. |
| 181 | |
| 182 | .. note:: |
| 183 | ``DeprecationWarning`` and ``PendingDeprecationWarning`` are treated |
| 184 | differently; see :ref:`ensuring_function_triggers`. |
| 185 | |
| 186 | """ |
| 187 | |
| 188 | def __init__(self, *, _ispytest: bool = False) -> None: |
| 189 | check_ispytest(_ispytest) |
| 190 | super().__init__(record=True) |
| 191 | self._entered = False |
| 192 | self._list: list[warnings.WarningMessage] = [] |
| 193 | |
| 194 | @property |
| 195 | def list(self) -> list[warnings.WarningMessage]: |
| 196 | """The list of recorded warnings.""" |
| 197 | return self._list |
| 198 | |
| 199 | def __getitem__(self, i: int) -> warnings.WarningMessage: |
| 200 | """Get a recorded warning by index.""" |
| 201 | return self._list[i] |
| 202 | |
| 203 | def __iter__(self) -> Iterator[warnings.WarningMessage]: |
| 204 | """Iterate through the recorded warnings.""" |
| 205 | return iter(self._list) |
| 206 | |
| 207 | def __len__(self) -> int: |
| 208 | """The number of recorded warnings.""" |
| 209 | return len(self._list) |
| 210 | |
| 211 | def pop(self, cls: type[Warning] = Warning) -> warnings.WarningMessage: |
| 212 | """Pop the first recorded warning which is an instance of ``cls``, |
| 213 | but not an instance of a child class of any other match. |
| 214 | Raises ``AssertionError`` if there is no match. |
| 215 | """ |
| 216 | best_idx: int | None = None |
| 217 | for i, w in enumerate(self._list): |
| 218 | if w.category == cls: |
| 219 | return self._list.pop(i) # exact match, stop looking |
| 220 | if issubclass(w.category, cls) and ( |
| 221 | best_idx is None |
| 222 | or not issubclass(w.category, self._list[best_idx].category) |
| 223 | ): |
| 224 | best_idx = i |
| 225 | if best_idx is not None: |
| 226 | return self._list.pop(best_idx) |
| 227 | __tracebackhide__ = True |
| 228 | raise AssertionError(f"{cls!r} not found in warning list") |
| 229 | |
| 230 | def clear(self) -> None: |
| 231 | """Clear the list of recorded warnings.""" |
| 232 | self._list[:] = [] |
no outgoing calls