From 676825cf52530db23e62bf6e2f726169dfea45fe Mon Sep 17 00:00:00 2001 From: Doug Blank Date: Thu, 15 Jun 2017 19:55:31 -0400 Subject: [PATCH] Removes try/except and recursion in ancestor filters +/- N gens This fix rewrites the Ancestor-of +/- N filters to remove the try/except and removes the recursion. The recursion would only be a problem on very deep trees, but the try/except was hiding a variety of problems. Most directly, if a person did not have a main family then it would exit out of the loop. (I don't have a test database to break the code other than my real data, so you'll have to do that part.) I also made sure that the meaning of N is consistent in both filters: 1 - root person 2 - root person's parents 3 - root person's grandparents --- .../_islessthannthgenerationancestorof.py | 52 +++++++++---------- .../_ismorethannthgenerationancestorof.py | 50 +++++++++--------- 2 files changed, 50 insertions(+), 52 deletions(-) diff --git a/gramps/gen/filters/rules/person/_islessthannthgenerationancestorof.py b/gramps/gen/filters/rules/person/_islessthannthgenerationancestorof.py index 48139b1cd..b95e330d1 100644 --- a/gramps/gen/filters/rules/person/_islessthannthgenerationancestorof.py +++ b/gramps/gen/filters/rules/person/_islessthannthgenerationancestorof.py @@ -51,36 +51,34 @@ class IsLessThanNthGenerationAncestorOf(Rule): def prepare(self, db, user): self.db = db self.map = set() - try: - root_handle = db.get_person_from_gramps_id(self.list[0]).get_handle() - self.init_ancestor_list(root_handle,0) - except: - pass + person = db.get_person_from_gramps_id(self.list[0]) + if person: + root_handle = person.get_handle() + if root_handle: + self.init_ancestor_list(root_handle) + + def init_ancestor_list(self, root_handle): + queue = [(root_handle, 1)] # generation 1 is root + while queue: + handle, gen = queue.pop(0) # pop off front of queue + self.map.add(handle) + gen += 1 + if gen <= int(self.list[1]): + p = self.db.get_person_from_handle(handle) + fam_id = p.get_main_parents_family_handle() + if fam_id: + fam = self.db.get_family_from_handle(fam_id) + if fam: + f_id = fam.get_father_handle() + m_id = fam.get_mother_handle() + # append to back of queue: + if f_id: + queue.append((f_id, gen)) + if m_id: + queue.append((m_id, gen)) def reset(self): self.map.clear() def apply(self,db,person): return person.handle in self.map - - def init_ancestor_list(self, handle,gen): -# if p.get_handle() in self.map: -# loop_error(self.orig,p) - if not handle: - return - if gen: - self.map.add(handle) - if gen >= int(self.list[1]): - return - - p = self.db.get_person_from_handle(handle) - fam_id = p.get_main_parents_family_handle() - fam = self.db.get_family_from_handle(fam_id) - if fam: - f_id = fam.get_father_handle() - m_id = fam.get_mother_handle() - - if f_id: - self.init_ancestor_list(f_id,gen+1) - if m_id: - self.init_ancestor_list(m_id,gen+1) diff --git a/gramps/gen/filters/rules/person/_ismorethannthgenerationancestorof.py b/gramps/gen/filters/rules/person/_ismorethannthgenerationancestorof.py index 11e9f6158..9ee74c59f 100644 --- a/gramps/gen/filters/rules/person/_ismorethannthgenerationancestorof.py +++ b/gramps/gen/filters/rules/person/_ismorethannthgenerationancestorof.py @@ -51,34 +51,34 @@ class IsMoreThanNthGenerationAncestorOf(Rule): def prepare(self, db, user): self.db = db self.map = set() - try: - root_handle = db.get_person_from_gramps_id(self.list[0]).get_handle() - self.init_ancestor_list(root_handle,0) - except: - pass + person = db.get_person_from_gramps_id(self.list[0]) + if person: + root_handle = person.get_handle() + if root_handle: + self.init_ancestor_list(root_handle) + + def init_ancestor_list(self, root_handle): + queue = [(root_handle, 1)] # generation 1 is root + while queue: + handle, gen = queue.pop(0) # pop off front of queue + if gen > int(self.list[1]): + self.map.add(handle) + gen += 1 + p = self.db.get_person_from_handle(handle) + fam_id = p.get_main_parents_family_handle() + if fam_id: + fam = self.db.get_family_from_handle(fam_id) + if fam: + f_id = fam.get_father_handle() + m_id = fam.get_mother_handle() + # append to back of queue: + if f_id: + queue.append((f_id, gen)) + if m_id: + queue.append((m_id, gen)) def reset(self): self.map.clear() def apply(self,db,person): return person.handle in self.map - - def init_ancestor_list(self, handle, gen): -# if p.get_handle() in self.map: -# loop_error(self.orig,p) - if not handle: - return - if gen >= int(self.list[1]): - self.map.add(handle) - - p = self.db.get_person_from_handle(handle) - fam_id = p.get_main_parents_family_handle() - fam = self.db.get_family_from_handle(fam_id) - if fam: - f_id = fam.get_father_handle() - m_id = fam.get_mother_handle() - - if f_id: - self.init_ancestor_list(f_id, gen+1) - if m_id: - self.init_ancestor_list(m_id, gen+1)