+ @property
+ def is_doable(self) -> bool:
+ """Decide whether .is_done can be set to True based on children's."""
+ for child in self.children:
+ if not child.is_done:
+ return False
+ return True
+
+ @property
+ def is_done(self) -> bool:
+ """Wrapper around self._is_done so we can control its setter."""
+ return self._is_done
+
+ @is_done.setter
+ def is_done(self, value: bool) -> None:
+ if value != self.is_done and not self.is_doable:
+ raise BadFormatException('cannot change doneness of undoable Todo')
+ self._is_done = value
+