Fix memory leak in i18n by using weak references to plugin classes and methods.

This commit is contained in:
Valentin Lorentz 2014-01-22 10:51:01 +01:00
parent 5cfa7828ea
commit 974a64de44

View File

@ -37,6 +37,7 @@ import os
import re import re
import sys import sys
import time import time
import weakref
import threading import threading
conf = None conf = None
# Don't import conf here ; because conf needs this module # Don't import conf here ; because conf needs this module
@ -107,9 +108,9 @@ def getLocalePath(name, localeName, extension):
directory = os.path.join(base, 'locales') directory = os.path.join(base, 'locales')
return '%s/%s.%s' % (directory, localeName, extension) return '%s/%s.%s' % (directory, localeName, extension)
i18nClasses = {} i18nClasses = weakref.WeakValueDictionary()
internationalizedCommands = {} internationalizedCommands = weakref.WeakValueDictionary()
internationalizedFunctions = [] # No need to know there name internationalizedFunctions = [] # No need to know their name
def reloadLocalesIfRequired(): def reloadLocalesIfRequired():
global currentLocale global currentLocale
@ -120,11 +121,15 @@ def reloadLocalesIfRequired():
reloadLocales() reloadLocales()
def reloadLocales(): def reloadLocales():
for pluginName in i18nClasses: for pluginClass in i18nClasses.values():
i18nClasses[pluginName].loadLocale() pluginClass.loadLocale()
for command in internationalizedCommands.values(): for command in internationalizedCommands.values():
internationalizeDocstring(command) internationalizeDocstring(command)
for function in internationalizedFunctions: for function_ref in list(internationalizedFunctions):
function = function_ref
if not function:
internationalizedFunctions.remove(function_ref)
else:
function.loadLocale() function.loadLocale()
def parse(translationFile): def parse(translationFile):
@ -334,7 +339,7 @@ class internationalizedFunction:
self._internationalizer = internationalizer self._internationalizer = internationalizer
self._name = name self._name = name
self._origin = function self._origin = function
internationalizedFunctions.append(self) internationalizedFunctions.append(weakref.proxy(self))
def loadLocale(self): def loadLocale(self):
self.__call__ = self._internationalizer.localizeFunction(self._name) self.__call__ = self._internationalizer.localizeFunction(self._name)
if self.__call__ == None: if self.__call__ == None: