use __getattribute__ (now dynamic)

This commit is contained in:
un-pogaz 2022-10-14 09:29:36 +02:00
parent 3c20c32676
commit e41aed9a24

View File

@ -874,13 +874,32 @@ class FormatterFuncsCaller():
''' '''
def __init__(self, formatter): def __init__(self, formatter):
from functools import partial
object.__init__(self) object.__init__(self)
if not isinstance(formatter, TemplateFormatter):
raise ValueError('Class {} is not an instance of TemplateFormatter'
.format(formatter.__class__.__name__))
object.__setattr__(self, 'formatter', formatter)
def __getattribute__(self, name):
if name.endswith('_'): # _ at the end to avoid conflicts with the Python keyword
func_name = name[:-1]
if func_name in self.formatter.funcs:
def call(*args):
return self.call(func_name, *args)
return call
def call(name, *args):
func = formatter.funcs[name]
args = [str(a) for a in args]
try: try:
return object.__getattribute__(self, name)
except Exception as e:
e.is_internal = True
raise e
def call(self, name, *args):
formatter = self.formatter
args = [str(a) for a in args]
try:
func = formatter.funcs[name]
if func.object_type == StoredObjectType.PythonFunction: if func.object_type == StoredObjectType.PythonFunction:
rslt = func.evaluate(formatter, formatter.kwargs, formatter.book, formatter.locals, *args) rslt = func.evaluate(formatter, formatter.kwargs, formatter.book, formatter.locals, *args)
else: else:
@ -888,16 +907,13 @@ class FormatterFuncsCaller():
except Exception as e: except Exception as e:
# Change the error message to return this used name on the template # Change the error message to return this used name on the template
e = e.__class__('Error in the function {0} :: {1}'.format( e = e.__class__(_('Error in the function {0} :: {1}').format(
name+'_', name+'_',
re.sub(r'\w+\.evaluate\(\)', name+'_()', str(e), 1))) # replace UserFunction.evaluate() | Builtin*.evaluate() by the func name re.sub(r'\w+\.evaluate\(\)', name+'_()', str(e), 1))) # replace UserFunction.evaluate() | Builtin*.evaluate() by the func name
e.is_internal = True e.is_internal = True
raise e raise e
return rslt return rslt
for name in formatter.funcs.keys():
setattr(self, name+'_', partial(call, name)) # _ at the end to avoid conflicts with the Python keyword
class _Interpreter: class _Interpreter: