Source code for structured_data._match.descriptor.property_

from ... import _doc_wrapper
from .. import matchable
from . import common


[docs]@_doc_wrapper.DocWrapper.wrap_class class Property(common.Descriptor): """Decorator with value-based dispatch. Acts as a property.""" fset = None fdel = None protected = False def __new__(cls, func=None, fset=None, fdel=None, doc=None, *args, **kwargs): del fset, fdel, doc return super().__new__(cls, func, *args, **kwargs) def __init__(self, func=None, fset=None, fdel=None, doc=None, *args, **kwargs): del func super().__init__(*args, **kwargs) self.fset = fset self.fdel = fdel if doc is not None: self.__doc__ = doc self.get_matchers = [] self.set_matchers = [] self.delete_matchers = [] self.protected = True def __setattr__(self, name, value): if self.protected and name != "__doc__": raise AttributeError super().__setattr__(name, value) def __delattr__(self, name): if self.protected and name != "__doc__": raise AttributeError super().__delattr__(name)
[docs] def getter(self, getter): """Return a copy of self with the getter replaced.""" new = Property(getter, self.fset, self.fdel, self.__doc__) new.get_matchers.extend(self.get_matchers) new.set_matchers.extend(self.set_matchers) new.delete_matchers.extend(self.delete_matchers) return new
[docs] def setter(self, setter): """Return a copy of self with the setter replaced.""" new = Property(self.__wrapped__, setter, self.fdel, self.__doc__) new.get_matchers.extend(self.get_matchers) new.set_matchers.extend(self.set_matchers) new.delete_matchers.extend(self.delete_matchers) return new
[docs] def deleter(self, deleter): """Return a copy of self with the deleter replaced.""" new = Property(self.__wrapped__, self.fset, deleter, self.__doc__) new.get_matchers.extend(self.get_matchers) new.set_matchers.extend(self.set_matchers) new.delete_matchers.extend(self.delete_matchers) return new
def __get__(self, instance, owner): if instance is None: return self matchable_ = matchable.Matchable(instance) for (structure, func) in self.get_matchers: if matchable_(structure): return func(**matchable_.matches) if self.__wrapped__ is None: raise ValueError(self) return self.__wrapped__(instance) def __set__(self, instance, value): matchable_ = matchable.Matchable((instance, value)) for (structure, func) in self.set_matchers: if matchable_(structure): func(**matchable_.matches) return if self.fset is None: raise ValueError((instance, value)) self.fset(instance, value) def __delete__(self, instance): matchable_ = matchable.Matchable(instance) for (structure, func) in self.delete_matchers: if matchable_(structure): func(**matchable_.matches) return if self.fdel is None: raise ValueError(instance) self.fdel(instance)
[docs] def get_when(self, instance): """Add a binding to the getter.""" return common.decorate(self.get_matchers, instance)
[docs] def set_when(self, instance, value): """Add a binding to the setter.""" return common.decorate(self.set_matchers, (instance, value))
[docs] def delete_when(self, instance): """Add a binding to the deleter.""" return common.decorate(self.delete_matchers, instance)