Since the parameters of the pipeline can change at any time we have to invalidate the internal state of the pipeline. To handle both invalidations of the inputs of the pipeline and the pipeline itself we set up watchers on both. 1. The first invalidation we
(self, depth=0)
| 338 | return ps |
| 339 | |
| 340 | def _setup_invalidations(self, depth=0): |
| 341 | """ |
| 342 | Since the parameters of the pipeline can change at any time |
| 343 | we have to invalidate the internal state of the pipeline. |
| 344 | To handle both invalidations of the inputs of the pipeline |
| 345 | and the pipeline itself we set up watchers on both. |
| 346 | |
| 347 | 1. The first invalidation we have to set up is to re-evaluate |
| 348 | the function that feeds the pipeline. Only the root node of |
| 349 | a pipeline has to perform this invalidation because all |
| 350 | leaf nodes inherit the same shared_obj. This avoids |
| 351 | evaluating the same function for every branch of the pipeline. |
| 352 | 2. The second invalidation is for the pipeline itself, i.e. |
| 353 | if any parameter changes we have to notify the pipeline that |
| 354 | it has to re-evaluate the pipeline. This is done by marking |
| 355 | the pipeline as `_dirty`. The next time the `_current` value |
| 356 | is requested we then run and `.eval()` pass that re-executes |
| 357 | the pipeline. |
| 358 | """ |
| 359 | if self._fn is not None and depth == 0: |
| 360 | for _, params in full_groupby(self._fn_params, lambda x: id(x.owner)): |
| 361 | params[0].owner.param.watch(self._update_obj, [p.name for p in params]) |
| 362 | for _, params in full_groupby(self._params, lambda x: id(x.owner)): |
| 363 | params[0].owner.param.watch(self._invalidate_current, [p.name for p in params]) |
| 364 | |
| 365 | def _invalidate_current(self, *events): |
| 366 | self._dirty = True |