Delay instantiating all the formatter function classes

This commit is contained in:
Charles Haley 2013-05-02 19:47:44 +02:00
parent 6b73a151a1
commit c8f566dfb8

View File

@ -10,6 +10,7 @@ __docformat__ = 'restructuredtext en'
import inspect, re, traceback import inspect, re, traceback
from math import trunc from math import trunc
from threading import RLock
from calibre import human_readable from calibre import human_readable
from calibre.constants import DEBUG from calibre.constants import DEBUG
@ -25,6 +26,15 @@ class FormatterFunctions(object):
def __init__(self): def __init__(self):
self._builtins = {} self._builtins = {}
self._functions = {} self._functions = {}
self._lock = RLock()
self._loaded = False
def load_builtins(self):
with self._lock:
if not self._loaded:
self._loaded = True
for c in _formatter_builtins:
c()
def register_builtin(self, func_class): def register_builtin(self, func_class):
if not isinstance(func_class, FormatterFunction): if not isinstance(func_class, FormatterFunction):
@ -39,6 +49,7 @@ class FormatterFunctions(object):
self._functions[a] = func_class self._functions[a] = func_class
def register_function(self, func_class): def register_function(self, func_class):
self.load_builtins()
if not isinstance(func_class, FormatterFunction): if not isinstance(func_class, FormatterFunction):
raise ValueError('Class %s is not an instance of FormatterFunction'%( raise ValueError('Class %s is not an instance of FormatterFunction'%(
func_class.__class__.__name__)) func_class.__class__.__name__))
@ -48,9 +59,11 @@ class FormatterFunctions(object):
self._functions[name] = func_class self._functions[name] = func_class
def get_builtins(self): def get_builtins(self):
self.load_builtins()
return self._builtins return self._builtins
def get_builtins_and_aliases(self): def get_builtins_and_aliases(self):
self.load_builtins()
res = {} res = {}
for f in self._builtins.itervalues(): for f in self._builtins.itervalues():
res[f.name] = f res[f.name] = f
@ -59,10 +72,12 @@ class FormatterFunctions(object):
return res return res
def get_functions(self): def get_functions(self):
self.load_builtins()
return self._functions return self._functions
def reset_to_builtins(self): def reset_to_builtins(self):
self._functions = {} self._functions = {}
self.load_builtins()
for n,c in self._builtins.items(): for n,c in self._builtins.items():
self._functions[n] = c self._functions[n] = c
for a in c.aliases: for a in c.aliases:
@ -1210,27 +1225,27 @@ class BuiltinFinishFormatting(BuiltinFormatterFunction):
return prefix + formatter._do_format(val, fmt) + suffix return prefix + formatter._do_format(val, fmt) + suffix
_formatter_builtins = [ _formatter_builtins = [
BuiltinAdd(), BuiltinAnd(), BuiltinApproximateFormats(), BuiltinAdd, BuiltinAnd, BuiltinApproximateFormats,
BuiltinAssign(), BuiltinBooksize(), BuiltinAssign, BuiltinBooksize,
BuiltinCapitalize(), BuiltinCmp(), BuiltinContains(), BuiltinCount(), BuiltinCapitalize, BuiltinCmp, BuiltinContains, BuiltinCount,
BuiltinCurrentLibraryName(), BuiltinCurrentLibraryPath(), BuiltinCurrentLibraryName, BuiltinCurrentLibraryPath,
BuiltinDaysBetween(), BuiltinDivide(), BuiltinEval(), BuiltinFirstNonEmpty(), BuiltinDaysBetween, BuiltinDivide, BuiltinEval, BuiltinFirstNonEmpty,
BuiltinField(), BuiltinFinishFormatting(), BuiltinFormatDate(), BuiltinField, BuiltinFinishFormatting, BuiltinFormatDate,
BuiltinFormatNumber(), BuiltinFormatsModtimes(), BuiltinFormatsPaths(), BuiltinFormatNumber, BuiltinFormatsModtimes, BuiltinFormatsPaths,
BuiltinFormatsSizes(), BuiltinFormatsSizes,
BuiltinHasCover(), BuiltinHumanReadable(), BuiltinIdentifierInList(), BuiltinHasCover, BuiltinHumanReadable, BuiltinIdentifierInList,
BuiltinIfempty(), BuiltinLanguageCodes(), BuiltinLanguageStrings(), BuiltinIfempty, BuiltinLanguageCodes, BuiltinLanguageStrings,
BuiltinInList(), BuiltinListDifference(), BuiltinListEquals(), BuiltinInList, BuiltinListDifference, BuiltinListEquals,
BuiltinListIntersection(), BuiltinListitem(), BuiltinListRe(), BuiltinListIntersection, BuiltinListitem, BuiltinListRe,
BuiltinListSort(), BuiltinListUnion(), BuiltinLookup(), BuiltinListSort, BuiltinListUnion, BuiltinLookup,
BuiltinLowercase(), BuiltinMultiply(), BuiltinNot(), BuiltinLowercase, BuiltinMultiply, BuiltinNot,
BuiltinOndevice(), BuiltinOr(), BuiltinPrint(), BuiltinRawField(), BuiltinOndevice, BuiltinOr, BuiltinPrint, BuiltinRawField,
BuiltinRe(), BuiltinSelect(), BuiltinSeriesSort(), BuiltinShorten(), BuiltinRe, BuiltinSelect, BuiltinSeriesSort, BuiltinShorten,
BuiltinStrcat(), BuiltinStrcatMax(), BuiltinStrcat, BuiltinStrcatMax,
BuiltinStrcmp(), BuiltinStrInList(), BuiltinStrlen(), BuiltinSubitems(), BuiltinStrcmp, BuiltinStrInList, BuiltinStrlen, BuiltinSubitems,
BuiltinSublist(),BuiltinSubstr(), BuiltinSubtract(), BuiltinSwapAroundComma(), BuiltinSublist,BuiltinSubstr, BuiltinSubtract, BuiltinSwapAroundComma,
BuiltinSwitch(), BuiltinTemplate(), BuiltinTest(), BuiltinTitlecase(), BuiltinSwitch, BuiltinTemplate, BuiltinTest, BuiltinTitlecase,
BuiltinToday(), BuiltinUppercase(), BuiltinToday, BuiltinUppercase,
] ]
class FormatterUserFunction(FormatterFunction): class FormatterUserFunction(FormatterFunction):
@ -1260,10 +1275,11 @@ class UserFunction(FormatterUserFunction):
return cls return cls
def load_user_template_functions(funcs): def load_user_template_functions(funcs):
formatter_functions().reset_to_builtins() if funcs:
for func in funcs: formatter_functions().reset_to_builtins()
try: for func in funcs:
cls = compile_user_function(*func) try:
formatter_functions().register_function(cls) cls = compile_user_function(*func)
except: formatter_functions().register_function(cls)
traceback.print_exc() except:
traceback.print_exc()