| 207 | |
| 208 | |
| 209 | class LFPluginCollWrapper: |
| 210 | def __init__(self, lfplugin: "LFPlugin") -> None: |
| 211 | self.lfplugin = lfplugin |
| 212 | self._collected_at_least_one_failure = False |
| 213 | |
| 214 | @hookimpl(hookwrapper=True) |
| 215 | def pytest_make_collect_report(self, collector: nodes.Collector): |
| 216 | if isinstance(collector, Session): |
| 217 | out = yield |
| 218 | res: CollectReport = out.get_result() |
| 219 | |
| 220 | # Sort any lf-paths to the beginning. |
| 221 | lf_paths = self.lfplugin._last_failed_paths |
| 222 | |
| 223 | res.result = sorted( |
| 224 | res.result, |
| 225 | # use stable sort to priorize last failed |
| 226 | key=lambda x: x.path in lf_paths, |
| 227 | reverse=True, |
| 228 | ) |
| 229 | return |
| 230 | |
| 231 | elif isinstance(collector, Module): |
| 232 | if collector.path in self.lfplugin._last_failed_paths: |
| 233 | out = yield |
| 234 | res = out.get_result() |
| 235 | result = res.result |
| 236 | lastfailed = self.lfplugin.lastfailed |
| 237 | |
| 238 | # Only filter with known failures. |
| 239 | if not self._collected_at_least_one_failure: |
| 240 | if not any(x.nodeid in lastfailed for x in result): |
| 241 | return |
| 242 | self.lfplugin.config.pluginmanager.register( |
| 243 | LFPluginCollSkipfiles(self.lfplugin), "lfplugin-collskip" |
| 244 | ) |
| 245 | self._collected_at_least_one_failure = True |
| 246 | |
| 247 | session = collector.session |
| 248 | result[:] = [ |
| 249 | x |
| 250 | for x in result |
| 251 | if x.nodeid in lastfailed |
| 252 | # Include any passed arguments (not trivial to filter). |
| 253 | or session.isinitpath(x.path) |
| 254 | # Keep all sub-collectors. |
| 255 | or isinstance(x, nodes.Collector) |
| 256 | ] |
| 257 | return |
| 258 | yield |
| 259 | |
| 260 | |
| 261 | class LFPluginCollSkipfiles: |