A selected subset of nodes within a larger PyTree. Penzai selectors (such as ``.at(...)``) return ``Selection`` objects, which indicate a specific subset of nodes within a larger PyTree, allowing those nodes to be pulled out and modified in a functional way. Selected nodes are required to
| 162 | |
| 163 | @struct.pytree_dataclass |
| 164 | class Selection(Generic[SelectedSubtree], struct.Struct): |
| 165 | """A selected subset of nodes within a larger PyTree. |
| 166 | |
| 167 | Penzai selectors (such as ``.at(...)``) return ``Selection`` objects, which |
| 168 | indicate a specific subset of nodes within a larger PyTree, allowing those |
| 169 | nodes to be pulled out and modified in a functional way. |
| 170 | |
| 171 | Selected nodes are required to be non-overlapping: no selected node can be |
| 172 | the ancestor of any other selected node in the same selection. |
| 173 | |
| 174 | For convenience, a ``Selection`` is also a PyTree, and its leaves are the same |
| 175 | as the leaves in the original PyTree, but they are likely to be in a different |
| 176 | order. |
| 177 | |
| 178 | .. note:: Aside for functional programming geeks: |
| 179 | A ``Selection`` is conceptually related to an "optic", specifically a |
| 180 | "lens". If you're familiar with optics, you can |
| 181 | think of a ``Selection`` as a partially-applied lens: it allows either |
| 182 | retrieving the selected values, or setting the selected values in the |
| 183 | structure. (If you're not familiar with optics, you can ignore this.) |
| 184 | |
| 185 | Attributes: |
| 186 | selected_by_path: A mapping whose values are the selected parts from the |
| 187 | original structure, and whose keys are the keypaths for those parts (as |
| 188 | registered with JAX's PyTree registry). This is an `OrderedDict` to |
| 189 | prevent JAX from trying to sort the keys, which may be arbitrarily |
| 190 | hashable objects without an ordering. |
| 191 | remainder: The rest of the structure. The locations where the selected |
| 192 | components were are marked with `SelectionHole` nodes. If the remainder |
| 193 | also includes a ``Selection`` itself, the remainder may also include |
| 194 | `SelectionQuote` nodes. |
| 195 | """ |
| 196 | |
| 197 | selected_by_path: collections.OrderedDict[KeyPath, SelectedSubtree] |
| 198 | remainder: Any |
| 199 | |
| 200 | def count(self) -> int: |
| 201 | """Returns the number of elements in the selection.""" |
| 202 | return len(self.selected_by_path) |
| 203 | |
| 204 | def __len__(self) -> int: |
| 205 | """Returns the number of elements in the selection.""" |
| 206 | return len(self.selected_by_path) |
| 207 | |
| 208 | def is_empty(self) -> bool: |
| 209 | """Returns True if the selection is empty.""" |
| 210 | return not self.selected_by_path |
| 211 | |
| 212 | def deselect(self) -> Any: |
| 213 | """Rebuilds the tree, forgetting which nodes were selected. |
| 214 | |
| 215 | Returns: |
| 216 | A copy of `remainder` with the holes filled by the values in |
| 217 | `selected_by_path`. If called on an ordinary selection, this rebuilds |
| 218 | the original tree. |
| 219 | """ |
| 220 | |
| 221 | def rebuild(subtree) -> Any: |
no outgoing calls
no test coverage detected