Work on resolving inlinefunc errors #1498
This commit is contained in:
parent
8d7a7490a9
commit
2eaae6ac48
2 changed files with 25 additions and 16 deletions
|
|
@ -87,7 +87,14 @@ def protfunc_parser(value, available_functions=None, **kwargs):
|
||||||
if not isinstance(value, basestring):
|
if not isinstance(value, basestring):
|
||||||
return value
|
return value
|
||||||
available_functions = _PROT_FUNCS if available_functions is None else available_functions
|
available_functions = _PROT_FUNCS if available_functions is None else available_functions
|
||||||
result = inlinefuncs.parse_inlinefunc(value, _available_funcs=available_functions, **kwargs)
|
result = inlinefuncs.parse_inlinefunc(value, available_funcs=available_functions, **kwargs)
|
||||||
|
# at this point we have a string where all procfuncs were parsed
|
||||||
|
try:
|
||||||
|
result = literal_eval(result)
|
||||||
|
except ValueError:
|
||||||
|
# this is due to the string not being valid for literal_eval - keep it a string
|
||||||
|
pass
|
||||||
|
|
||||||
result = _PROTLIB.value_to_obj_or_any(result)
|
result = _PROTLIB.value_to_obj_or_any(result)
|
||||||
try:
|
try:
|
||||||
return literal_eval(result)
|
return literal_eval(result)
|
||||||
|
|
|
||||||
|
|
@ -157,6 +157,9 @@ def clr(*args, **kwargs):
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
def null(*args, **kwargs):
|
||||||
|
return args[0] if args else ''
|
||||||
|
|
||||||
# we specify a default nomatch function to use if no matching func was
|
# we specify a default nomatch function to use if no matching func was
|
||||||
# found. This will be overloaded by any nomatch function defined in
|
# found. This will be overloaded by any nomatch function defined in
|
||||||
# the imported modules.
|
# the imported modules.
|
||||||
|
|
@ -177,10 +180,6 @@ for module in utils.make_iter(settings.INLINEFUNC_MODULES):
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
# remove the core function if we include examples in this module itself
|
|
||||||
#_INLINE_FUNCS.pop("inline_func_parse", None)
|
|
||||||
|
|
||||||
|
|
||||||
# The stack size is a security measure. Set to <=0 to disable.
|
# The stack size is a security measure. Set to <=0 to disable.
|
||||||
try:
|
try:
|
||||||
_STACK_MAXSIZE = settings.INLINEFUNC_STACK_MAXSIZE
|
_STACK_MAXSIZE = settings.INLINEFUNC_STACK_MAXSIZE
|
||||||
|
|
@ -198,7 +197,7 @@ _RE_TOKEN = re.compile(r"""
|
||||||
(?P<end>(?<!\\)\))| # unescaped ) (end of function call)
|
(?P<end>(?<!\\)\))| # unescaped ) (end of function call)
|
||||||
(?P<start>(?<!\\)\$\w+\()| # unescaped $funcname( (start of function call)
|
(?P<start>(?<!\\)\$\w+\()| # unescaped $funcname( (start of function call)
|
||||||
(?P<escaped>\\'|\\"|\\\)|\\$\w+\()| # escaped tokens should re-appear in text
|
(?P<escaped>\\'|\\"|\\\)|\\$\w+\()| # escaped tokens should re-appear in text
|
||||||
(?P<rest>[\w\s.-\/#!%\^&\*;:=\-_`~\|\(}{\[\]]+|\"{1}|\'{1}) # everything else should also be included""",
|
(?P<rest>[\w\s.-\/#@$\>\<!%\^&\*;:=\-_`~\|\(}{\[\]]+|\"{1}|\'{1}) # everything else should also be included""",
|
||||||
re.UNICODE + re.IGNORECASE + re.VERBOSE + re.DOTALL)
|
re.UNICODE + re.IGNORECASE + re.VERBOSE + re.DOTALL)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -257,7 +256,7 @@ class InlinefuncError(RuntimeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def parse_inlinefunc(string, strip=False, _available_funcs=None, **kwargs):
|
def parse_inlinefunc(string, strip=False, available_funcs=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Parse the incoming string.
|
Parse the incoming string.
|
||||||
|
|
||||||
|
|
@ -265,7 +264,7 @@ def parse_inlinefunc(string, strip=False, _available_funcs=None, **kwargs):
|
||||||
string (str): The incoming string to parse.
|
string (str): The incoming string to parse.
|
||||||
strip (bool, optional): Whether to strip function calls rather than
|
strip (bool, optional): Whether to strip function calls rather than
|
||||||
execute them.
|
execute them.
|
||||||
_available_funcs(dict, optional): Define an alterinative source of functions to parse for.
|
available_funcs (dict, optional): Define an alternative source of functions to parse for.
|
||||||
If unset, use the functions found through `settings.INLINEFUNC_MODULES`.
|
If unset, use the functions found through `settings.INLINEFUNC_MODULES`.
|
||||||
Kwargs:
|
Kwargs:
|
||||||
session (Session): This is sent to this function by Evennia when triggering
|
session (Session): This is sent to this function by Evennia when triggering
|
||||||
|
|
@ -276,9 +275,12 @@ def parse_inlinefunc(string, strip=False, _available_funcs=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
global _PARSING_CACHE
|
global _PARSING_CACHE
|
||||||
|
|
||||||
_available_funcs = _INLINE_FUNCS if _available_funcs is None else _available_funcs
|
usecache = False
|
||||||
|
if not available_funcs:
|
||||||
|
available_funcs = _INLINE_FUNCS
|
||||||
|
usecache = True
|
||||||
|
|
||||||
if string in _PARSING_CACHE:
|
if usecache and string in _PARSING_CACHE:
|
||||||
# stack is already cached
|
# stack is already cached
|
||||||
stack = _PARSING_CACHE[string]
|
stack = _PARSING_CACHE[string]
|
||||||
elif not _RE_STARTTOKEN.search(string):
|
elif not _RE_STARTTOKEN.search(string):
|
||||||
|
|
@ -314,9 +316,9 @@ def parse_inlinefunc(string, strip=False, _available_funcs=None, **kwargs):
|
||||||
funcname = _RE_STARTTOKEN.match(gdict["start"]).group(1)
|
funcname = _RE_STARTTOKEN.match(gdict["start"]).group(1)
|
||||||
try:
|
try:
|
||||||
# try to fetch the matching inlinefunc from storage
|
# try to fetch the matching inlinefunc from storage
|
||||||
stack.append(_available_funcs[funcname])
|
stack.append(available_funcs[funcname])
|
||||||
except KeyError:
|
except KeyError:
|
||||||
stack.append(_available_funcs["nomatch"])
|
stack.append(available_funcs["nomatch"])
|
||||||
stack.append(funcname)
|
stack.append(funcname)
|
||||||
ncallable += 1
|
ncallable += 1
|
||||||
elif gdict["escaped"]:
|
elif gdict["escaped"]:
|
||||||
|
|
@ -343,8 +345,8 @@ def parse_inlinefunc(string, strip=False, _available_funcs=None, **kwargs):
|
||||||
if _STACK_MAXSIZE > 0 and _STACK_MAXSIZE < len(stack):
|
if _STACK_MAXSIZE > 0 and _STACK_MAXSIZE < len(stack):
|
||||||
# if stack is larger than limit, throw away parsing
|
# if stack is larger than limit, throw away parsing
|
||||||
return string + gdict["stackfull"](*args, **kwargs)
|
return string + gdict["stackfull"](*args, **kwargs)
|
||||||
else:
|
elif usecache:
|
||||||
# cache the stack
|
# cache the stack - we do this also if we don't check the cache above
|
||||||
_PARSING_CACHE[string] = stack
|
_PARSING_CACHE[string] = stack
|
||||||
|
|
||||||
# run the stack recursively
|
# run the stack recursively
|
||||||
|
|
@ -368,8 +370,8 @@ def parse_inlinefunc(string, strip=False, _available_funcs=None, **kwargs):
|
||||||
retval = "" if strip else func(*args, **kwargs)
|
retval = "" if strip else func(*args, **kwargs)
|
||||||
return utils.to_str(retval, force_string=True)
|
return utils.to_str(retval, force_string=True)
|
||||||
|
|
||||||
# execute the stack from the cache
|
# execute the stack
|
||||||
return "".join(_run_stack(item) for item in _PARSING_CACHE[string])
|
return "".join(_run_stack(item) for item in stack)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Nick templating
|
# Nick templating
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue