| 176 | |
| 177 | |
| 178 | def _init_runner_class() -> type[doctest.DocTestRunner]: |
| 179 | import doctest |
| 180 | |
| 181 | class PytestDoctestRunner(doctest.DebugRunner): |
| 182 | """Runner to collect failures. |
| 183 | |
| 184 | Note that the out variable in this case is a list instead of a |
| 185 | stdout-like object. |
| 186 | """ |
| 187 | |
| 188 | def __init__( |
| 189 | self, |
| 190 | checker: doctest.OutputChecker | None = None, |
| 191 | verbose: bool | None = None, |
| 192 | optionflags: int = 0, |
| 193 | continue_on_failure: bool = True, |
| 194 | ) -> None: |
| 195 | super().__init__(checker=checker, verbose=verbose, optionflags=optionflags) |
| 196 | self.continue_on_failure = continue_on_failure |
| 197 | |
| 198 | def report_failure( |
| 199 | self, |
| 200 | out, |
| 201 | test: doctest.DocTest, |
| 202 | example: doctest.Example, |
| 203 | got: str, |
| 204 | ) -> None: |
| 205 | failure = doctest.DocTestFailure(test, example, got) |
| 206 | if self.continue_on_failure: |
| 207 | out.append(failure) |
| 208 | else: |
| 209 | raise failure |
| 210 | |
| 211 | def report_unexpected_exception( |
| 212 | self, |
| 213 | out, |
| 214 | test: doctest.DocTest, |
| 215 | example: doctest.Example, |
| 216 | exc_info: tuple[type[BaseException], BaseException, types.TracebackType], |
| 217 | ) -> None: |
| 218 | if isinstance(exc_info[1], OutcomeException): |
| 219 | raise exc_info[1] |
| 220 | if isinstance(exc_info[1], bdb.BdbQuit): |
| 221 | outcomes.exit("Quitting debugger") |
| 222 | failure = doctest.UnexpectedException(test, example, exc_info) |
| 223 | if self.continue_on_failure: |
| 224 | out.append(failure) |
| 225 | else: |
| 226 | raise failure |
| 227 | |
| 228 | return PytestDoctestRunner |
| 229 | |
| 230 | |
| 231 | def _get_runner( |