def _person_is_private(person: Person, lifetime_threshold: int) -> bool: # A dead person is not private, regardless of when they died. if person.end is not None: if person.end.date is None: return False if _event_has_expired(person.end, lifetime_threshold, 0): return False if _person_has_expired(person, lifetime_threshold, 1): return False def ancestors(person: Person, generation: int = -1): for parent in person.parents: yield generation, parent yield from ancestors(parent, generation - 1) for generation, ancestor in ancestors(person): if _person_has_expired(ancestor, lifetime_threshold, abs(generation) + 1): return False # If any descendant has any expired event, the person is considered not private. for descendant in walk(person, 'children'): if _person_has_expired(descendant, lifetime_threshold, 1): return False return True
def test_with_mixed_descendants(self) -> None: grandchild = self._Item([]) child = self._Item(grandchild) item = self._Item([child]) actual = walk(item, 'child') expected = [child, grandchild] self.assertEquals(expected, list(actual))
def test_one_to_one_with_descendants(self) -> None: grandchild = self._Item(None) child = self._Item(grandchild) item = self._Item(child) actual = walk(item, 'child') expected = [child, grandchild] self.assertEquals(expected, list(actual))
def _filter_walk(item, attribute_name): return walk(item, attribute_name)
def _filter_walk(item: Any, attribute_name: str) -> Iterable[Any]: return walk(item, attribute_name)
def _has_public_descendants(person: Person) -> bool: for descendant in walk(person, 'children'): if not descendant.private: return True return False
def test_one_to_many_without_descendants(self) -> None: item = self._Item([]) actual = walk(item, 'child') expected = [] self.assertEquals(expected, list(actual))
def test_with_invalid_attribute(self, item: Any) -> None: with self.assertRaises(AttributeError): list(walk(item, 'invalid_attribute_name'))