(
self, config: Config, items: list[nodes.Item]
)
| 362 | |
| 363 | @hookimpl(wrapper=True, tryfirst=True) |
| 364 | def pytest_collection_modifyitems( |
| 365 | self, config: Config, items: list[nodes.Item] |
| 366 | ) -> Generator[None]: |
| 367 | res = yield |
| 368 | |
| 369 | if not self.active: |
| 370 | return res |
| 371 | |
| 372 | if self.lastfailed: |
| 373 | previously_failed = [] |
| 374 | previously_passed = [] |
| 375 | for item in items: |
| 376 | if item.nodeid in self.lastfailed: |
| 377 | previously_failed.append(item) |
| 378 | else: |
| 379 | previously_passed.append(item) |
| 380 | self._previously_failed_count = len(previously_failed) |
| 381 | |
| 382 | if not previously_failed: |
| 383 | # Running a subset of all tests with recorded failures |
| 384 | # only outside of it. |
| 385 | self._report_status = ( |
| 386 | f"{len(self.lastfailed)} known failures not in selected tests" |
| 387 | ) |
| 388 | else: |
| 389 | if self.config.getoption("lf"): |
| 390 | items[:] = previously_failed |
| 391 | config.hook.pytest_deselected(items=previously_passed) |
| 392 | else: # --failedfirst |
| 393 | items[:] = previously_failed + previously_passed |
| 394 | |
| 395 | noun = "failure" if self._previously_failed_count == 1 else "failures" |
| 396 | suffix = " first" if self.config.getoption("failedfirst") else "" |
| 397 | self._report_status = ( |
| 398 | f"rerun previous {self._previously_failed_count} {noun}{suffix}" |
| 399 | ) |
| 400 | |
| 401 | if self._skipped_files > 0: |
| 402 | files_noun = "file" if self._skipped_files == 1 else "files" |
| 403 | self._report_status += f" (skipped {self._skipped_files} {files_noun})" |
| 404 | else: |
| 405 | self._report_status = "no previously failed tests, " |
| 406 | if self.config.getoption("last_failed_no_failures") == "none": |
| 407 | self._report_status += "deselecting all items." |
| 408 | config.hook.pytest_deselected(items=items[:]) |
| 409 | items[:] = [] |
| 410 | else: |
| 411 | self._report_status += "not deselecting items." |
| 412 | |
| 413 | return res |
| 414 | |
| 415 | def pytest_sessionfinish(self, session: Session) -> None: |
| 416 | config = self.config |
no test coverage detected