Find child-class failures that correspond to stripped parent-class markers. When ``strip_reasonless_expected_failures`` removes a marker from a parent (mixin) class, test failures are reported against the concrete subclasses, not the parent itself. This function maps those child failur
(
contents: str,
stripped_tests: set[tuple[str, str]],
all_failing_tests: set[tuple[str, str]],
)
| 251 | |
| 252 | |
| 253 | def _expand_stripped_to_children( |
| 254 | contents: str, |
| 255 | stripped_tests: set[tuple[str, str]], |
| 256 | all_failing_tests: set[tuple[str, str]], |
| 257 | ) -> set[tuple[str, str]]: |
| 258 | """Find child-class failures that correspond to stripped parent-class markers. |
| 259 | |
| 260 | When ``strip_reasonless_expected_failures`` removes a marker from a parent |
| 261 | (mixin) class, test failures are reported against the concrete subclasses, |
| 262 | not the parent itself. This function maps those child failures back so |
| 263 | they get re-marked (and later consolidated to the parent by |
| 264 | ``_consolidate_to_parent``). |
| 265 | |
| 266 | Returns the set of ``(class, method)`` pairs from *all_failing_tests* that |
| 267 | should be re-marked. |
| 268 | """ |
| 269 | # Direct matches (stripped test itself is a concrete TestCase) |
| 270 | result = stripped_tests & all_failing_tests |
| 271 | |
| 272 | unmatched = stripped_tests - all_failing_tests |
| 273 | if not unmatched: |
| 274 | return result |
| 275 | |
| 276 | tree = ast.parse(contents) |
| 277 | class_bases, class_methods = _build_inheritance_info(tree) |
| 278 | |
| 279 | for parent_cls, method_name in unmatched: |
| 280 | if method_name not in class_methods.get(parent_cls, set()): |
| 281 | continue |
| 282 | for cls in _find_all_inheritors( |
| 283 | parent_cls, method_name, class_bases, class_methods |
| 284 | ): |
| 285 | if (cls, method_name) in all_failing_tests: |
| 286 | result.add((cls, method_name)) |
| 287 | |
| 288 | return result |
| 289 | |
| 290 | |
| 291 | def _consolidate_to_parent( |