| 121 | |
| 122 | |
| 123 | def runtestprotocol( |
| 124 | item: Item, log: bool = True, nextitem: Item | None = None |
| 125 | ) -> list[TestReport]: |
| 126 | hasrequest = hasattr(item, "_request") |
| 127 | if hasrequest and not item._request: # type: ignore[attr-defined] |
| 128 | # This only happens if the item is re-run, as is done by |
| 129 | # pytest-rerunfailures. |
| 130 | item._initrequest() # type: ignore[attr-defined] |
| 131 | try: |
| 132 | rep = call_and_report(item, "setup", log) |
| 133 | reports = [rep] |
| 134 | if rep.passed: |
| 135 | setup_only = item.config.getoption("setuponly", False) |
| 136 | if item.config.getoption("setupshow", False): |
| 137 | show_test_item(item, add_space=not setup_only) |
| 138 | if not setup_only: |
| 139 | reports.append(call_and_report(item, "call", log)) |
| 140 | # If the session is about to fail or stop, teardown everything - this is |
| 141 | # necessary to correctly report fixture teardown errors (see #11706) |
| 142 | if item.session.shouldfail or item.session.shouldstop: |
| 143 | nextitem = None |
| 144 | reports.append(call_and_report(item, "teardown", log, nextitem=nextitem)) |
| 145 | finally: |
| 146 | # After all teardown hooks have been called (or an exception was reraised) |
| 147 | # want funcargs and request info to go away. |
| 148 | if hasrequest: |
| 149 | item._request = False # type: ignore[attr-defined] |
| 150 | item.funcargs = None # type: ignore[attr-defined] |
| 151 | return reports |
| 152 | |
| 153 | |
| 154 | def show_test_item(item: Item, *, add_space: bool) -> None: |