Flattens a selection whose selected values are all selections. This function takes a selection for which all of the selected values are already selections, and merges them into a single selection that selects all of the values from each individual selection. You can use this to bui
(
self: "Selection[Selection[SelectedSubtree]]",
)
| 433 | return self.set_by_path(replacer) |
| 434 | |
| 435 | def flatten_selected_selections( |
| 436 | self: "Selection[Selection[SelectedSubtree]]", |
| 437 | ) -> "Selection[SelectedSubtree]": |
| 438 | """Flattens a selection whose selected values are all selections. |
| 439 | |
| 440 | This function takes a selection for which all of the selected values are |
| 441 | already selections, and merges them into a single selection that selects |
| 442 | all of the values from each individual selection. |
| 443 | |
| 444 | You can use this to build more complex selections by chaining your own |
| 445 | logic. For instance, if you have written a function ``f`` that selects part |
| 446 | of a tree, you can run |
| 447 | |
| 448 | :: |
| 449 | |
| 450 | selection.apply(f, keep_selected=True).flatten_selected_selections() |
| 451 | |
| 452 | to "broadcast" that logic across all of the already-selected subtrees in |
| 453 | the original selection. |
| 454 | |
| 455 | See also `refine`, which allows you to express similar transformations more |
| 456 | directly. |
| 457 | |
| 458 | Returns: |
| 459 | A flattened selection object. |
| 460 | """ |
| 461 | # Strategy: Replace the values of each inner selection by a boundary, |
| 462 | # deselect everything, then re-select at the boundary. |
| 463 | |
| 464 | def process_subselection(subselection: Selection) -> Any: |
| 465 | if not isinstance(subselection, Selection): |
| 466 | raise ValueError( |
| 467 | "flatten_selected_selections can only be called on Selections for" |
| 468 | " which all values in `.selected_by_path` are also Selections. Got" |
| 469 | f" {subselection}" |
| 470 | ) |
| 471 | return subselection.apply(_InProgressSelectionBoundary) |
| 472 | |
| 473 | with _wrap_selection_errors(self): |
| 474 | return _build_selection_from_boundary(self.apply(process_subselection)) |
| 475 | |
| 476 | def refine( |
| 477 | self, selector_fn: "Callable[[Any], Selection[OtherSubtree]]" |
no test coverage detected