Link traits from different objects together so they remain in sync. Parameters ---------- source : (object / attribute name) pair target : (object / attribute name) pair transform: iterable with two callables (optional) Data transformation between source and target and t
| 273 | |
| 274 | |
| 275 | class link: |
| 276 | """Link traits from different objects together so they remain in sync. |
| 277 | |
| 278 | Parameters |
| 279 | ---------- |
| 280 | source : (object / attribute name) pair |
| 281 | target : (object / attribute name) pair |
| 282 | transform: iterable with two callables (optional) |
| 283 | Data transformation between source and target and target and source. |
| 284 | |
| 285 | Examples |
| 286 | -------- |
| 287 | >>> class X(HasTraits): |
| 288 | ... value = Int() |
| 289 | |
| 290 | >>> src = X(value=1) |
| 291 | >>> tgt = X(value=42) |
| 292 | >>> c = link((src, "value"), (tgt, "value")) |
| 293 | |
| 294 | Setting source updates target objects: |
| 295 | >>> src.value = 5 |
| 296 | >>> tgt.value |
| 297 | 5 |
| 298 | """ |
| 299 | |
| 300 | updating = False |
| 301 | |
| 302 | def __init__( |
| 303 | self, source: t.Any, target: t.Any, transform: t.Iterable[FuncT] | None = None |
| 304 | ) -> None: |
| 305 | _validate_link(source, target) |
| 306 | self.source, self.target = source, target |
| 307 | if transform: |
| 308 | self._transform, self._transform_inv = transform # type:ignore[method-assign] |
| 309 | self.link() |
| 310 | |
| 311 | def _transform(self, x: T) -> T: |
| 312 | """default transform: no-op""" |
| 313 | return x |
| 314 | |
| 315 | _transform_inv = _transform |
| 316 | |
| 317 | def link(self) -> None: |
| 318 | try: |
| 319 | setattr( |
| 320 | self.target[0], |
| 321 | self.target[1], |
| 322 | self._transform(getattr(self.source[0], self.source[1])), |
| 323 | ) |
| 324 | |
| 325 | finally: |
| 326 | self.source[0].observe(self._update_target, names=self.source[1]) |
| 327 | self.target[0].observe(self._update_source, names=self.target[1]) |
| 328 | |
| 329 | @contextlib.contextmanager |
| 330 | def _busy_updating(self) -> t.Any: |
| 331 | self.updating = True |
| 332 | try: |
no outgoing calls
searching dependent graphs…