Pimped Python property with getitem access for interfacing with instruments. Can be used as a decorator. Takes the same parameters as `Feat`, plus: :param keys: List/tuple restricts the keys to the specified ones.
| 314 | |
| 315 | |
| 316 | class DictFeat(Feat): |
| 317 | """Pimped Python property with getitem access for interfacing with |
| 318 | instruments. Can be used as a decorator. |
| 319 | |
| 320 | Takes the same parameters as `Feat`, plus: |
| 321 | |
| 322 | :param keys: List/tuple restricts the keys to the specified ones. |
| 323 | |
| 324 | """ |
| 325 | |
| 326 | def __init__(self, fget=MISSING, fset=None, doc=None, *, |
| 327 | keys=None, **kwargs): |
| 328 | super().__init__(fget, fset, doc, **kwargs) |
| 329 | self.modifiers[MISSING][MISSING]['keys'] = keys |
| 330 | |
| 331 | |
| 332 | def getitem(self, instance, key): |
| 333 | keys = _dget(self.modifiers, instance, key)['keys'] |
| 334 | if keys and not key in keys: |
| 335 | raise KeyError('{} is not valid key for {} {}'.format(key, self.name, |
| 336 | keys)) |
| 337 | if isinstance(keys, dict): |
| 338 | key = keys[key] |
| 339 | |
| 340 | return self.get(instance, instance.__class__, key) |
| 341 | |
| 342 | def setitem(self, instance, key, value, force=False): |
| 343 | keys = _dget(self.modifiers, instance, key)['keys'] |
| 344 | if keys and not key in keys: |
| 345 | raise KeyError('{} is not valid key for {} {}'.format(key, self.name, |
| 346 | keys)) |
| 347 | if isinstance(keys, dict): |
| 348 | key = keys[key] |
| 349 | |
| 350 | self.set(instance, value, force, key) |
| 351 | |
| 352 | def __get__(self, instance, owner=None): |
| 353 | if not instance: |
| 354 | return self |
| 355 | return _DictFeatAccesor(instance, self) |
| 356 | |
| 357 | def __set__(self, instance, value): |
| 358 | if not isinstance(value, dict): |
| 359 | raise AttributeError('This is a DictFeat and cannot be set in this way. ' |
| 360 | 'You probably want to do something like:' |
| 361 | 'obj.prop[index] = value or obj.prop = dict') |
| 362 | |
| 363 | for key, value in value.items(): |
| 364 | self.setitem(instance, key, value) |
| 365 | |
| 366 | def __delete__(self, instance): |
| 367 | raise AttributeError('{} is a permanent attribute from {}', self.name, instance.__class__.__name__) |
| 368 | |
| 369 | def get_cache(self, instance, key=MISSING): |
| 370 | keys = _dget(self.modifiers, instance, key)['keys'] |
| 371 | if instance not in self.value: |
| 372 | self.value[instance] = dict() |
| 373 | if isinstance(keys, dict): |