From ec40418f5dcbb34db3b53ad6099521f58d1ef582 Mon Sep 17 00:00:00 2001 From: Gary Burton Date: Sun, 3 Feb 2013 16:40:43 +0000 Subject: [PATCH] Fix memory leaks. svn: r21285 --- 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 2a1e40bec..872b779c6 100644 --- a/gramps/plugins/lib/libgedcom.py +++ b/gramps/plugins/lib/libgedcom.py @@ -762,6 +762,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 @@ -1832,6 +1841,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] @@ -1911,6 +1921,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 @@ -2003,6 +2014,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} @@ -2038,6 +2050,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 @@ -2062,6 +2075,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} @@ -2111,6 +2125,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, @@ -2140,6 +2155,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} @@ -2154,6 +2170,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, @@ -2161,6 +2178,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, @@ -2177,6 +2195,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, @@ -2189,6 +2208,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, @@ -2196,6 +2216,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, @@ -2211,6 +2232,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, @@ -2220,6 +2242,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, @@ -2237,6 +2260,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 @@ -2292,6 +2316,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, @@ -2299,6 +2324,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 @@ -2352,6 +2378,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 @@ -2380,6 +2407,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, @@ -2399,10 +2427,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, @@ -2416,11 +2446,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, @@ -2429,15 +2461,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, @@ -2445,10 +2480,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 @@ -2504,6 +2541,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, @@ -2511,24 +2549,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 @@ -2547,6 +2590,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 = {} @@ -2614,6 +2658,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() @@ -2625,6 +2670,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): """