def _set_one(self, obj, value, from_opposite=False) -> None: if not (isinstance(value, self.type) or (value is None)): raise AttributeError( f"Value should be of type {self.type.__name__}, got a {type(value)} instead" ) old = self._get(obj) # do nothing if we are assigned our current value: # Still do your thing, since undo handlers expect that. if value is old: return if old: self._del(obj, old, from_opposite=from_opposite, do_notify=False) if value is not None: setattr(obj, self._name, value) try: self._set_opposite(obj, value, from_opposite) except Exception: setattr(obj, self._name, old) raise self.handle(AssociationSet(obj, self, old, value))
def _del_one(self, obj, value, from_opposite=False, do_notify=True): value = self._get_one(obj) if value is None: return self._del_opposite(obj, value, from_opposite) try: delattr(obj, self._name) except AttributeError: pass else: if do_notify: self.handle(AssociationSet(obj, self, value, None))