From efdb6e9fd563b25ff7535d0f1c82b71f8f995ae6 Mon Sep 17 00:00:00 2001 From: Gary Burton Date: Sun, 3 Feb 2013 16:25:03 +0000 Subject: [PATCH] Fix memory leaks. svn: r21284 --- gramps/plugins/lib/libgedcom.py | 58 +++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/gramps/plugins/lib/libgedcom.py b/gramps/plugins/lib/libgedcom.py index 9fe68dfa4..7387a3b3e 100644 --- a/gramps/plugins/lib/libgedcom.py +++ b/gramps/plugins/lib/libgedcom.py @@ -761,6 +761,15 @@ class Lexer(object): else: self.current_list.insert(0, data) + def clean_up(self): + """ + Break circular references to parsing methods stored in dictionaries + to aid garbage collection + """ + for key in (self.func_map.keys()): + del self.func_map[key] + del self.func_map + #----------------------------------------------------------------------- # # GedLine - represents a tokenized version of a GEDCOM line @@ -1831,6 +1840,7 @@ class GedcomParser(UpdateCallback): self.gedmap = GedcomInfoDB() self.gedsource = self.gedmap.get_from_source_tag('GEDCOM 5.5') self.use_def_src = default_source + self.func_list = [] if self.use_def_src: self.def_src = Source() fname = os.path.basename(filename).split('\\')[-1] @@ -1910,6 +1920,7 @@ class GedcomParser(UpdateCallback): # +1 <> TOKEN_CHAN : self.__repo_chan, } + self.func_list.append(self.subm_parse_tbl) # # Parse table for <> below the level 0 INDI tag @@ -2002,6 +2013,7 @@ class GedcomParser(UpdateCallback): TOKEN__TODO : self.__skip_record, TOKEN_TITL : self.__person_titl, } + self.func_list.append(self.indi_parse_tbl) self.name_parse_tbl = { # +1 NPFX {0:1} @@ -2037,6 +2049,7 @@ class GedcomParser(UpdateCallback): # found in Brother's keeper. TOKEN__ADPN : self.__name_adpn, } + self.func_list.append(self.name_parse_tbl) # # Parse table for <> below the level 0 REPO tag @@ -2061,6 +2074,7 @@ class GedcomParser(UpdateCallback): TOKEN_EMAIL : self.__repo_email, TOKEN_WWW : self.__repo_www, } + self.func_list.append(self.repo_parse_tbl) self.event_parse_tbl = { # n TYPE {0:1} @@ -2110,6 +2124,7 @@ class GedcomParser(UpdateCallback): TOKEN_EMAIL : self.__event_email, # FTB for RESI events TOKEN_WWW : self.__event_www, # FTB for RESI events } + self.func_list.append(self.event_parse_tbl) self.adopt_parse_tbl = { TOKEN_TYPE : self.__event_type, @@ -2139,6 +2154,7 @@ class GedcomParser(UpdateCallback): TOKEN_CHAN : self.__ignore, TOKEN_QUAY : self.__ignore, } + self.func_list.append(self.adopt_parse_tbl) self.famc_parse_tbl = { # n FAMC @@ {1:1} @@ -2153,6 +2169,7 @@ class GedcomParser(UpdateCallback): # GEDit TOKEN_STAT : self.__ignore, } + self.func_list.append(self.famc_parse_tbl) self.person_fact_parse_tbl = { TOKEN_TYPE : self.__person_fact_type, @@ -2160,6 +2177,7 @@ class GedcomParser(UpdateCallback): TOKEN_NOTE : self.__person_attr_note, TOKEN_RNOTE : self.__person_attr_note, } + self.func_list.append(self.person_fact_parse_tbl) self.person_attr_parse_tbl = { TOKEN_TYPE : self.__person_attr_type, @@ -2176,6 +2194,7 @@ class GedcomParser(UpdateCallback): TOKEN_NOTE : self.__person_attr_note, TOKEN_RNOTE : self.__person_attr_note, } + self.func_list.append(self.person_attr_parse_tbl) self.lds_parse_tbl = { TOKEN_TEMP : self.__lds_temple, @@ -2188,6 +2207,7 @@ class GedcomParser(UpdateCallback): TOKEN_RNOTE : self.__lds_note, TOKEN_STAT : self.__lds_stat, } + self.func_list.append(self.lds_parse_tbl) self.asso_parse_tbl = { TOKEN_RELA : self.__person_asso_rela, @@ -2195,6 +2215,7 @@ class GedcomParser(UpdateCallback): TOKEN_NOTE : self.__person_asso_note, TOKEN_RNOTE : self.__person_asso_note, } + self.func_list.append(self.asso_parse_tbl) self.citation_parse_tbl = { TOKEN_PAGE : self.__citation_page, @@ -2210,6 +2231,7 @@ class GedcomParser(UpdateCallback): TOKEN_RNOTE : self.__citation_note, TOKEN_TEXT : self.__citation_data_text, } + self.func_list.append(self.citation_parse_tbl) self.object_parse_tbl = { TOKEN_FORM : self.__object_ref_form, @@ -2219,6 +2241,7 @@ class GedcomParser(UpdateCallback): TOKEN_RNOTE : self.__object_ref_note, TOKEN_IGNORE : self.__ignore, } + self.func_list.append(self.object_parse_tbl) self.parse_loc_tbl = { TOKEN_ADDR : self.__location_addr, @@ -2236,6 +2259,7 @@ class GedcomParser(UpdateCallback): TOKEN_PHON : self.__ignore, TOKEN_IGNORE : self.__ignore, } + self.func_list.append(self.parse_loc_tbl) # # Parse table for <> below the level 0 FAM tag @@ -2291,6 +2315,7 @@ class GedcomParser(UpdateCallback): TOKEN_SUBM : self.__ignore, TOKEN_ATTR : self.__family_attr, } + self.func_list.append(self.family_func) self.family_rel_tbl = { TOKEN__FREL : self.__family_frel, @@ -2298,6 +2323,7 @@ class GedcomParser(UpdateCallback): TOKEN_ADOP : self.__family_adopt, TOKEN__STAT : self.__family_stat, } + self.func_list.append(self.family_rel_tbl) # # Parse table for <> below the level 0 SOUR tag @@ -2351,6 +2377,7 @@ class GedcomParser(UpdateCallback): TOKEN_DATE : self.__ignore, TOKEN_IGNORE : self.__ignore, } + self.func_list.append(self.source_func) # # Parse table for <> below the level 0 OBJE tag @@ -2379,6 +2406,7 @@ class GedcomParser(UpdateCallback): TOKEN_RIN : self.__obje_rin, TOKEN_CHAN : self.__obje_chan, } + self.func_list.append(self.obje_func) self.parse_addr_tbl = { TOKEN_DATE : self.__address_date, @@ -2398,10 +2426,12 @@ class GedcomParser(UpdateCallback): TOKEN_TYPE : self.__ignore, TOKEN_CAUS : self.__ignore, } + self.func_list.append(self.parse_addr_tbl) self.event_cause_tbl = { TOKEN_SOUR : self.__event_cause_source, } + self.func_list.append(self.event_cause_tbl) self.event_place_map = { TOKEN_NOTE : self.__event_place_note, @@ -2415,11 +2445,13 @@ class GedcomParser(UpdateCallback): # Not legal, but generated by Ultimate Family Tree TOKEN_QUAY : self.__ignore, } + self.func_list.append(self.event_place_map) self.place_map_tbl = { TOKEN_LATI : self.__place_lati, TOKEN_LONG : self.__place_long, } + self.func_list.append(self.place_map_tbl) self.repo_ref_tbl = { TOKEN_CALN : self.__repo_ref_call, @@ -2428,15 +2460,18 @@ class GedcomParser(UpdateCallback): TOKEN_MEDI : self.__repo_ref_medi, TOKEN_IGNORE : self.__ignore, } + self.func_list.append(self.repo_ref_tbl) self.parse_person_adopt = { TOKEN_ADOP : self.__person_adopt_famc_adopt, } + self.func_list.append(self.parse_person_adopt) self.opt_note_tbl = { TOKEN_RNOTE : self.__optional_note, TOKEN_NOTE : self.__optional_note, } + self.func_list.append(self.opt_note_tbl) self.citation_data_tbl = { TOKEN_DATE : self.__citation_data_date, @@ -2444,10 +2479,12 @@ class GedcomParser(UpdateCallback): TOKEN_RNOTE : self.__citation_data_note, TOKEN_NOTE : self.__citation_data_note, } + self.func_list.append(self.citation_data_tbl) self.citation_even_tbl = { TOKEN_ROLE : self.__citation_even_role, } + self.func_list.append(self.citation_even_tbl) # # Parse table for <
> record below the level 0 HEAD tag @@ -2503,6 +2540,7 @@ class GedcomParser(UpdateCallback): TOKEN_DATE : self.__header_date, TOKEN_NOTE : self.__header_note, } + self.func_list.append(self.head_parse_tbl) self.header_sour_parse_tbl = { TOKEN_VERS : self.__header_sour_vers, @@ -2510,24 +2548,29 @@ class GedcomParser(UpdateCallback): TOKEN_CORP : self.__header_sour_corp, TOKEN_DATA : self.__header_sour_data, } + self.func_list.append(self.header_sour_parse_tbl) self.header_sour_data = { TOKEN_DATE : self.__header_sour_date, TOKEN_COPR : self.__header_sour_copr, } + self.func_list.append(self.header_sour_data) self.header_corp_addr = { TOKEN_ADDR : self.__repo_addr, TOKEN_PHON : self.__repo_phon, } + self.func_list.append(self.header_corp_addr) self.header_subm = { TOKEN_NAME : self.__header_subm_name, } + self.func_list.append(self.header_subm) self.place_form = { TOKEN_FORM : self.__place_form, } + self.func_list.append(self.place_form) # # Parse table for <> below the level 0 NOTE tag @@ -2546,6 +2589,7 @@ class GedcomParser(UpdateCallback): TOKEN_RIN : self.__ignore, TOKEN_CHAN : self.__note_chan, } + self.func_list.append(self.note_parse_tbl) # look for existing place titles, build a map self.place_names = {} @@ -2613,6 +2657,7 @@ class GedcomParser(UpdateCallback): src.set_handle(handle) src.set_title(title) self.dbase.add_source(src, self.trans) + self.__clean_up() if not self.dbase.get_feature("skip-check-xref"): self.__check_xref() @@ -2624,6 +2669,19 @@ class GedcomParser(UpdateCallback): message = _("GEDCOM import report: %s errors detected") % \ self.number_of_errors self.user.info(message, "".join(self.errors), monospaced=True) + + def __clean_up(self): + """ + Break circular references to parsing methods stored in dictionaries + to aid garbage collection + """ + for func_map in self.func_list: + for key in func_map.keys(): + del func_map[key] + del func_map + del self.func_list + del self.update + self.lexer.clean_up() def __find_person_handle(self, gramps_id): """