Format code with black. Add makefile to run fmt/tests

This commit is contained in:
Griatch 2019-09-28 18:18:11 +02:00
parent d00bce9288
commit c2c7fa311a
299 changed files with 19037 additions and 11611 deletions

View file

@ -188,8 +188,10 @@ _CMD_NOINPUT = cmdhandler.CMD_NOINPUT
# i18n
from django.utils.translation import ugettext as _
_ERR_NOT_IMPLEMENTED = _("Menu node '{nodename}' is either not implemented or "
"caused an error. Make another choice.")
_ERR_NOT_IMPLEMENTED = _(
"Menu node '{nodename}' is either not implemented or " "caused an error. Make another choice."
)
_ERR_GENERAL = _("Error in menu node '{nodename}'.")
_ERR_NO_OPTION_DESC = _("No description.")
_HELP_FULL = _("Commands: <menu option>, help, quit")
@ -206,9 +208,11 @@ to non-persistent mode (which means the menu session won't survive
an eventual server reload).|n
"""
_TRACE_PERSISTENT_SAVING = "EvMenu persistent-mode error. Commonly, this is because one or " \
"more of the EvEditor callbacks could not be pickled, for example " \
"because it's a class method or is defined inside another function."
_TRACE_PERSISTENT_SAVING = (
"EvMenu persistent-mode error. Commonly, this is because one or "
"more of the EvEditor callbacks could not be pickled, for example "
"because it's a class method or is defined inside another function."
)
class EvMenuError(RuntimeError):
@ -216,8 +220,10 @@ class EvMenuError(RuntimeError):
Error raised by menu when facing internal errors.
"""
pass
# -------------------------------------------------------------
#
# Menu command and command set
@ -229,6 +235,7 @@ class CmdEvMenuNode(Command):
"""
Menu options.
"""
key = _CMD_NOINPUT
aliases = [_CMD_NOMATCH]
locks = "cmd:all()"
@ -238,6 +245,7 @@ class CmdEvMenuNode(Command):
"""
Implement all menu commands.
"""
def _restore(caller):
# check if there is a saved menu available.
# this will re-start a completely new evmenu call.
@ -275,7 +283,9 @@ class CmdEvMenuNode(Command):
if not menu:
# can't restore from a session
err = "Menu object not found as %s.ndb._menutree!" % orig_caller
orig_caller.msg(err) # don't give the session as a kwarg here, direct to original
orig_caller.msg(
err
) # don't give the session as a kwarg here, direct to original
raise EvMenuError(err)
# we must do this after the caller with the menu has been correctly identified since it
# can be either Account, Object or Session (in the latter case this info will be superfluous).
@ -289,6 +299,7 @@ class EvMenuCmdSet(CmdSet):
The Menu cmdset replaces the current cmdset.
"""
key = "menu_cmdset"
priority = 1
mergetype = "Replace"
@ -303,7 +314,7 @@ class EvMenuCmdSet(CmdSet):
self.add(CmdEvMenuNode())
#------------------------------------------------------------
# ------------------------------------------------------------
#
# Menu main class
#
@ -320,12 +331,23 @@ class EvMenu(object):
# convenient helpers for easy overloading
node_border_char = "_"
def __init__(self, caller, menudata, startnode="start",
cmdset_mergetype="Replace", cmdset_priority=1,
auto_quit=True, auto_look=True, auto_help=True,
cmd_on_exit="look",
persistent=False, startnode_input="", session=None,
debug=False, **kwargs):
def __init__(
self,
caller,
menudata,
startnode="start",
cmdset_mergetype="Replace",
cmdset_priority=1,
auto_quit=True,
auto_look=True,
auto_help=True,
cmd_on_exit="look",
persistent=False,
startnode_input="",
session=None,
debug=False,
**kwargs,
):
"""
Initialize the menu tree and start the caller onto the first node.
@ -435,7 +457,9 @@ class EvMenu(object):
if isinstance(cmd_on_exit, str):
# At this point menu._session will have been replaced by the
# menu command to the actual session calling.
self.cmd_on_exit = lambda caller, menu: caller.execute_cmd(cmd_on_exit, session=menu._session)
self.cmd_on_exit = lambda caller, menu: caller.execute_cmd(
cmd_on_exit, session=menu._session
)
elif callable(cmd_on_exit):
self.cmd_on_exit = cmd_on_exit
else:
@ -453,10 +477,24 @@ class EvMenu(object):
self.test_nodetext = ""
# assign kwargs as initialization vars on ourselves.
if set(("_startnode", "_menutree", "_session", "_persistent",
"cmd_on_exit", "default", "nodetext", "helptext",
"options", "cmdset_mergetype", "auto_quit")).intersection(set(kwargs.keys())):
raise RuntimeError("One or more of the EvMenu `**kwargs` is reserved by EvMenu for internal use.")
if set(
(
"_startnode",
"_menutree",
"_session",
"_persistent",
"cmd_on_exit",
"default",
"nodetext",
"helptext",
"options",
"cmdset_mergetype",
"auto_quit",
)
).intersection(set(kwargs.keys())):
raise RuntimeError(
"One or more of the EvMenu `**kwargs` is reserved by EvMenu for internal use."
)
for key, val in kwargs.items():
setattr(self, key, val)
@ -473,17 +511,19 @@ class EvMenu(object):
if persistent:
# save the menu to the database
calldict = {"startnode": startnode,
"cmdset_mergetype": cmdset_mergetype,
"cmdset_priority": cmdset_priority,
"auto_quit": auto_quit,
"auto_look": auto_look,
"auto_help": auto_help,
"cmd_on_exit": cmd_on_exit,
"persistent": persistent}
calldict = {
"startnode": startnode,
"cmdset_mergetype": cmdset_mergetype,
"cmdset_priority": cmdset_priority,
"auto_quit": auto_quit,
"auto_look": auto_look,
"auto_help": auto_help,
"cmd_on_exit": cmd_on_exit,
"persistent": persistent,
}
calldict.update(kwargs)
try:
caller.attributes.add("_menutree_saved", (self.__class__, (menudata, ), calldict))
caller.attributes.add("_menutree_saved", (self.__class__, (menudata,), calldict))
caller.attributes.add("_menutree_saved_startnode", (startnode, startnode_input))
except Exception as err:
caller.msg(_ERROR_PERSISTENT_SAVING.format(error=err), session=self._session)
@ -526,8 +566,11 @@ class EvMenu(object):
else:
# a python path of a module
module = mod_import(menudata)
return dict((key, func) for key, func in module.__dict__.items()
if isfunction(func) and not key.startswith("_"))
return dict(
(key, func)
for key, func in module.__dict__.items()
if isfunction(func) and not key.startswith("_")
)
def _format_node(self, nodetext, optionlist):
"""
@ -665,7 +708,9 @@ class EvMenu(object):
ret = self._safe_call(nodename, raw_string, **kwargs)
if isinstance(ret, (tuple, list)):
if not len(ret) > 1 or not isinstance(ret[1], dict):
raise EvMenuError("exec callable must return either None, str or (str, dict)")
raise EvMenuError(
"exec callable must return either None, str or (str, dict)"
)
ret, kwargs = ret[:2]
else:
# nodename is a string; lookup as node and run as node in-place (don't goto it)
@ -711,8 +756,11 @@ class EvMenu(object):
goto, goto_kwargs = goto[:2] # ignore any extra arguments
if not hasattr(goto_kwargs, "__getitem__"):
# not a dict-like structure
raise EvMenuError("EvMenu node {}: goto kwargs is not a dict: {}".format(
nodename, goto_kwargs))
raise EvMenuError(
"EvMenu node {}: goto kwargs is not a dict: {}".format(
nodename, goto_kwargs
)
)
else:
goto = goto[0]
if execute and isinstance(execute, (tuple, list)):
@ -720,8 +768,11 @@ class EvMenu(object):
execute, exec_kwargs = execute[:2] # ignore any extra arguments
if not hasattr(exec_kwargs, "__getitem__"):
# not a dict-like structure
raise EvMenuError("EvMenu node {}: exec kwargs is not a dict: {}".format(
nodename, goto_kwargs))
raise EvMenuError(
"EvMenu node {}: exec kwargs is not a dict: {}".format(
nodename, goto_kwargs
)
)
else:
execute = execute[0]
return goto, goto_kwargs, execute, exec_kwargs
@ -750,7 +801,8 @@ class EvMenu(object):
if isinstance(nodename, (tuple, list)):
if not len(nodename) > 1 or not isinstance(nodename[1], dict):
raise EvMenuError(
"{}: goto callable must return str or (str, dict)".format(inp_nodename))
"{}: goto callable must return str or (str, dict)".format(inp_nodename)
)
nodename, kwargs = nodename[:2]
if not nodename:
# no nodename return. Re-run current node
@ -762,8 +814,9 @@ class EvMenu(object):
return
if self._persistent:
self.caller.attributes.add("_menutree_saved_startnode",
(nodename, (raw_string, kwargs)))
self.caller.attributes.add(
"_menutree_saved_startnode", (nodename, (raw_string, kwargs))
)
# validation of the node return values
helptext = ""
@ -797,8 +850,12 @@ class EvMenu(object):
display_options.append((keys[0], desc))
for key in keys:
if goto or execute:
self.options[strip_ansi(key).strip().lower()] = \
(goto, goto_kwargs, execute, exec_kwargs)
self.options[strip_ansi(key).strip().lower()] = (
goto,
goto_kwargs,
execute,
exec_kwargs,
)
self.nodetext = self._format_node(nodetext, display_options)
self.node_kwargs = kwargs
@ -833,10 +890,9 @@ class EvMenu(object):
"""
if runexec:
# replace goto only if callback returns
goto, goto_kwargs = (
self.run_exec(runexec, raw_string,
**(runexec_kwargs if runexec_kwargs else {})) or
(goto, goto_kwargs))
goto, goto_kwargs = self.run_exec(
runexec, raw_string, **(runexec_kwargs if runexec_kwargs else {})
) or (goto, goto_kwargs)
if goto:
self.goto(goto, raw_string, **(goto_kwargs if goto_kwargs else {}))
@ -867,37 +923,51 @@ class EvMenu(object):
all_props = inspect.getmembers(self)
all_methods = [name for name, _ in inspect.getmembers(self, predicate=inspect.ismethod)]
all_builtins = [name for name, _ in inspect.getmembers(self, predicate=inspect.isbuiltin)]
props = {prop: value for prop, value in all_props if prop not in all_methods and
prop not in all_builtins and not prop.endswith("__")}
props = {
prop: value
for prop, value in all_props
if prop not in all_methods and prop not in all_builtins and not prop.endswith("__")
}
local = {key: var for key, var in locals().items()
if key not in all_props and not key.endswith("__")}
local = {
key: var
for key, var in locals().items()
if key not in all_props and not key.endswith("__")
}
if arg:
if arg in props:
debugtxt = " |y* {}:|n\n{}".format(arg, props[arg])
elif arg in local:
debugtxt = " |y* {}:|n\n{}".format(arg, local[arg])
elif arg == 'full':
debugtxt = ("|yMENU DEBUG full ... |n\n" + "\n".join(
"|y *|n {}: {}".format(key, val)
for key, val in sorted(props.items())) +
"\n |yLOCAL VARS:|n\n" + "\n".join(
"|y *|n {}: {}".format(key, val)
for key, val in sorted(local.items())) +
"\n |y... END MENU DEBUG|n")
elif arg == "full":
debugtxt = (
"|yMENU DEBUG full ... |n\n"
+ "\n".join(
"|y *|n {}: {}".format(key, val) for key, val in sorted(props.items())
)
+ "\n |yLOCAL VARS:|n\n"
+ "\n".join(
"|y *|n {}: {}".format(key, val) for key, val in sorted(local.items())
)
+ "\n |y... END MENU DEBUG|n"
)
else:
debugtxt = "|yUsage: menudebug full|<name of property>|n"
else:
debugtxt = ("|yMENU DEBUG properties ... |n\n" + "\n".join(
"|y *|n {}: {}".format(
key, crop(to_str(val, force_string=True), width=50))
for key, val in sorted(props.items())) +
"\n |yLOCAL VARS:|n\n" + "\n".join(
"|y *|n {}: {}".format(
key, crop(to_str(val, force_string=True), width=50))
for key, val in sorted(local.items())) +
"\n |y... END MENU DEBUG|n")
debugtxt = (
"|yMENU DEBUG properties ... |n\n"
+ "\n".join(
"|y *|n {}: {}".format(key, crop(to_str(val, force_string=True), width=50))
for key, val in sorted(props.items())
)
+ "\n |yLOCAL VARS:|n\n"
+ "\n".join(
"|y *|n {}: {}".format(key, crop(to_str(val, force_string=True), width=50))
for key, val in sorted(local.items())
)
+ "\n |y... END MENU DEBUG|n"
)
self.caller.msg(debugtxt)
def parse_input(self, raw_string):
@ -953,7 +1023,7 @@ class EvMenu(object):
nodetext (str): The formatted node text.
"""
return dedent(nodetext.strip('\n'), baseline_index=0).rstrip()
return dedent(nodetext.strip("\n"), baseline_index=0).rstrip()
def helptext_formatter(self, helptext):
"""
@ -966,7 +1036,7 @@ class EvMenu(object):
helptext (str): The formatted help text.
"""
return dedent(helptext.strip('\n'), baseline_index=0).rstrip()
return dedent(helptext.strip("\n"), baseline_index=0).rstrip()
def options_formatter(self, optionlist):
"""
@ -995,9 +1065,12 @@ class EvMenu(object):
for key, desc in optionlist:
if key or desc:
desc_string = ": %s" % desc if desc else ""
table_width_max = max(table_width_max,
max(m_len(p) for p in key.split("\n")) +
max(m_len(p) for p in desc_string.split("\n")) + colsep)
table_width_max = max(
table_width_max,
max(m_len(p) for p in key.split("\n"))
+ max(m_len(p) for p in desc_string.split("\n"))
+ colsep,
)
raw_key = strip_ansi(key)
if raw_key != key:
# already decorations in key definition
@ -1005,7 +1078,7 @@ class EvMenu(object):
else:
# add a default white color to key
table.append(" |lc%s|lt|w%s|n|le%s" % (raw_key, raw_key, desc_string))
ncols = (_MAX_TEXT_WIDTH // table_width_max) # number of ncols
ncols = _MAX_TEXT_WIDTH // table_width_max # number of ncols
if ncols < 0:
# no visible option at all
@ -1026,11 +1099,13 @@ class EvMenu(object):
table.extend([" " for i in range(nrows - nlastcol)])
# build the actual table grid
table = [table[icol * nrows: (icol * nrows) + nrows] for icol in range(0, ncols)]
table = [table[icol * nrows : (icol * nrows) + nrows] for icol in range(0, ncols)]
# adjust the width of each column
for icol in range(len(table)):
col_width = max(max(m_len(p) for p in part.split("\n")) for part in table[icol]) + colsep
col_width = (
max(max(m_len(p) for p in part.split("\n")) for part in table[icol]) + colsep
)
table[icol] = [pad(part, width=col_width + colsep, align="l") for part in table[icol]]
# format the table into columns
@ -1052,8 +1127,7 @@ class EvMenu(object):
sep = self.node_border_char
if self._session:
screen_width = self._session.protocol_flags.get(
"SCREENWIDTH", {0: _MAX_TEXT_WIDTH})[0]
screen_width = self._session.protocol_flags.get("SCREENWIDTH", {0: _MAX_TEXT_WIDTH})[0]
else:
screen_width = _MAX_TEXT_WIDTH
@ -1072,6 +1146,7 @@ class EvMenu(object):
#
# -----------------------------------------------------------
def list_node(option_generator, select=None, pagesize=10):
"""
Decorator for making an EvMenu node into a multi-page list node. Will add new options,
@ -1104,7 +1179,6 @@ def list_node(option_generator, select=None, pagesize=10):
"""
def decorator(func):
def _select_parser(caller, raw_string, **kwargs):
"""
Parse the select action
@ -1128,15 +1202,16 @@ def list_node(option_generator, select=None, pagesize=10):
elif select:
# we assume a string was given, we inject the result into the kwargs
# to pass on to the next node
kwargs['selection'] = selection
kwargs["selection"] = selection
return str(select)
# this means the previous node will be re-run with these same kwargs
return None
def _list_node(caller, raw_string, **kwargs):
option_list = option_generator(caller) \
if callable(option_generator) else option_generator
option_list = (
option_generator(caller) if callable(option_generator) else option_generator
)
npages = 0
page_index = 0
@ -1145,8 +1220,9 @@ def list_node(option_generator, select=None, pagesize=10):
if option_list:
nall_options = len(option_list)
pages = [option_list[ind:ind + pagesize]
for ind in range(0, nall_options, pagesize)]
pages = [
option_list[ind : ind + pagesize] for ind in range(0, nall_options, pagesize)
]
npages = len(pages)
page_index = max(0, min(npages - 1, kwargs.get("optionpage_index", 0)))
@ -1157,26 +1233,38 @@ def list_node(option_generator, select=None, pagesize=10):
# dynamic, multi-page option list. Each selection leads to the `select`
# callback being called with a result from the available choices
options.extend([{"desc": opt,
"goto": (_select_parser,
{"available_choices": page})} for opt in page])
options.extend(
[
{"desc": opt, "goto": (_select_parser, {"available_choices": page})}
for opt in page
]
)
if npages > 1:
# if the goto callable returns None, the same node is rerun, and
# kwargs not used by the callable are passed on to the node. This
# allows us to call ourselves over and over, using different kwargs.
options.append({"key": ("|Wcurrent|n", "c"),
"desc": "|W({}/{})|n".format(page_index + 1, npages),
"goto": (lambda caller: None,
{"optionpage_index": page_index})})
options.append(
{
"key": ("|Wcurrent|n", "c"),
"desc": "|W({}/{})|n".format(page_index + 1, npages),
"goto": (lambda caller: None, {"optionpage_index": page_index}),
}
)
if page_index > 0:
options.append({"key": ("|wp|Wrevious page|n", "p"),
"goto": (lambda caller: None,
{"optionpage_index": page_index - 1})})
options.append(
{
"key": ("|wp|Wrevious page|n", "p"),
"goto": (lambda caller: None, {"optionpage_index": page_index - 1}),
}
)
if page_index < npages - 1:
options.append({"key": ("|wn|Wext page|n", "n"),
"goto": (lambda caller: None,
{"optionpage_index": page_index + 1})})
options.append(
{
"key": ("|wn|Wext page|n", "n"),
"goto": (lambda caller: None, {"optionpage_index": page_index + 1}),
}
)
# add data from the decorated node
@ -1222,8 +1310,10 @@ def list_node(option_generator, select=None, pagesize=10):
eopt[cback] = (signature[0], {"available_choices": page})
else:
# malformed input.
logger.log_err("EvMenu @list_node decorator found "
"malformed option to decorate: {}".format(eopt))
logger.log_err(
"EvMenu @list_node decorator found "
"malformed option to decorate: {}".format(eopt)
)
extra_options.append(eopt)
options.extend(extra_options)
@ -1232,6 +1322,7 @@ def list_node(option_generator, select=None, pagesize=10):
return text, options
return _list_node
return decorator
@ -1241,10 +1332,12 @@ def list_node(option_generator, select=None, pagesize=10):
#
# -------------------------------------------------------------------------------------------------
class CmdGetInput(Command):
"""
Enter your data and press return.
"""
key = _CMD_NOMATCH
aliases = _CMD_NOINPUT
@ -1281,6 +1374,7 @@ class InputCmdSet(CmdSet):
"""
This stores the input command
"""
key = "input_cmdset"
priority = 1
mergetype = "Replace"
@ -1295,6 +1389,7 @@ class InputCmdSet(CmdSet):
class _Prompt(object):
"""Dummy holder"""
pass
@ -1374,6 +1469,7 @@ def get_input(caller, prompt, callback, session=None, *args, **kwargs):
#
# -------------------------------------------------------------
def _generate_goto(caller, **kwargs):
return kwargs.get("name", "test_dynamic_node"), {"name": "replaced!"}
@ -1390,39 +1486,52 @@ def test_start_node(caller):
Select options or use 'quit' to exit the menu.
The menu was initialized with two variables: %s and %s.
""" % (menu.testval, menu.testval2)
""" % (
menu.testval,
menu.testval2,
)
options = ({"key": ("|yS|net", "s"),
"desc": "Set an attribute on yourself.",
"exec": lambda caller: caller.attributes.add("menuattrtest", "Test value"),
"goto": "test_set_node"},
{"key": ("|yL|nook", "l"),
"desc": "Look and see a custom message.",
"goto": "test_look_node"},
{"key": ("|yV|niew", "v"),
"desc": "View your own name",
"goto": "test_view_node"},
{"key": ("|yD|nynamic", "d"),
"desc": "Dynamic node",
"goto": (_generate_goto, {"name": "test_dynamic_node"})},
{"key": ("|yQ|nuit", "quit", "q", "Q"),
"desc": "Quit this menu example.",
"goto": "test_end_node"},
{"key": "_default",
"goto": "test_displayinput_node"})
options = (
{
"key": ("|yS|net", "s"),
"desc": "Set an attribute on yourself.",
"exec": lambda caller: caller.attributes.add("menuattrtest", "Test value"),
"goto": "test_set_node",
},
{
"key": ("|yL|nook", "l"),
"desc": "Look and see a custom message.",
"goto": "test_look_node",
},
{"key": ("|yV|niew", "v"), "desc": "View your own name", "goto": "test_view_node"},
{
"key": ("|yD|nynamic", "d"),
"desc": "Dynamic node",
"goto": (_generate_goto, {"name": "test_dynamic_node"}),
},
{
"key": ("|yQ|nuit", "quit", "q", "Q"),
"desc": "Quit this menu example.",
"goto": "test_end_node",
},
{"key": "_default", "goto": "test_displayinput_node"},
)
return text, options
def test_look_node(caller):
text = "This is a custom look location!"
options = {"key": ("|yL|nook", "l"),
"desc": "Go back to the previous menu.",
"goto": "test_start_node"}
options = {
"key": ("|yL|nook", "l"),
"desc": "Go back to the previous menu.",
"goto": "test_start_node",
}
return text, options
def test_set_node(caller):
text = ("""
text = (
"""
The attribute 'menuattrtest' was set to
|w%s|n
@ -1433,20 +1542,22 @@ def test_set_node(caller):
string "_default", meaning it will catch any input, in this case
to return to the main menu. So you can e.g. press <return> to go
back now.
""" % caller.db.menuattrtest, # optional help text for this node
"""
"""
% caller.db.menuattrtest, # optional help text for this node
"""
This is the help entry for this node. It is created by returning
the node text as a tuple - the second string in that tuple will be
used as the help text.
""")
""",
)
options = {"key": ("back (default)", "_default"),
"goto": "test_start_node"}
options = {"key": ("back (default)", "_default"), "goto": "test_start_node"}
return text, options
def test_view_node(caller, **kwargs):
text = """
text = (
"""
Your name is |g%s|n!
click |lclook|lthere|le to trigger a look command under MXP.
@ -1454,19 +1565,21 @@ def test_view_node(caller, **kwargs):
set), and so gets assigned a number automatically. You can infact
-always- use numbers (1...N) to refer to listed options also if you
don't see a string option key (try it!).
""" % caller.key
"""
% caller.key
)
if kwargs.get("executed_from_dynamic_node", False):
# we are calling this node as a exec, skip return values
caller.msg("|gCalled from dynamic node:|n \n {}".format(text))
return
else:
options = {"desc": "back to main",
"goto": "test_start_node"}
options = {"desc": "back to main", "goto": "test_start_node"}
return text, options
def test_displayinput_node(caller, raw_string):
text = """
text = (
"""
You entered the text:
"|w%s|n"
@ -1478,18 +1591,22 @@ def test_displayinput_node(caller, raw_string):
makes it hidden from view. It catches all input (except the
in-menu help/quit commands) and will, in this case, bring you back
to the start node.
""" % raw_string.rstrip()
options = {"key": "_default",
"goto": "test_start_node"}
"""
% raw_string.rstrip()
)
options = {"key": "_default", "goto": "test_start_node"}
return text, options
def _test_call(caller, raw_input, **kwargs):
mode = kwargs.get("mode", "exec")
caller.msg("\n|y'{}' |n_test_call|y function called with\n "
"caller: |n{}\n |yraw_input: \"|n{}|y\" \n kwargs: |n{}\n".format(
mode, caller, raw_input.rstrip(), kwargs))
caller.msg(
"\n|y'{}' |n_test_call|y function called with\n "
'caller: |n{}\n |yraw_input: "|n{}|y" \n kwargs: |n{}\n'.format(
mode, caller, raw_input.rstrip(), kwargs
)
)
if mode == "exec":
kwargs = {"random": random.random()}
@ -1504,18 +1621,26 @@ def test_dynamic_node(caller, **kwargs):
text = """
This is a dynamic node with input:
{}
""".format(kwargs)
options = ({"desc": "pass a new random number to this node",
"goto": ("test_dynamic_node", {"random": random.random()})},
{"desc": "execute a func with kwargs",
"exec": (_test_call, {"mode": "exec", "test_random": random.random()})},
{"desc": "dynamic_goto",
"goto": (_test_call, {"mode": "goto", "goto_input": "test"})},
{"desc": "exec test_view_node with kwargs",
"exec": ("test_view_node", {"executed_from_dynamic_node": True}),
"goto": "test_dynamic_node"},
{"desc": "back to main",
"goto": "test_start_node"})
""".format(
kwargs
)
options = (
{
"desc": "pass a new random number to this node",
"goto": ("test_dynamic_node", {"random": random.random()}),
},
{
"desc": "execute a func with kwargs",
"exec": (_test_call, {"mode": "exec", "test_random": random.random()}),
},
{"desc": "dynamic_goto", "goto": (_test_call, {"mode": "goto", "goto_input": "test"})},
{
"desc": "exec test_view_node with kwargs",
"exec": ("test_view_node", {"executed_from_dynamic_node": True}),
"goto": "test_dynamic_node",
},
{"desc": "back to main", "goto": "test_start_node"},
)
return text, options
@ -1538,6 +1663,7 @@ class CmdTestMenu(Command):
Starts a demo menu from a menu node definition module.
"""
key = "testmenu"
def func(self):
@ -1546,5 +1672,12 @@ class CmdTestMenu(Command):
self.caller.msg("Usage: testmenu menumodule")
return
# start menu
EvMenu(self.caller, self.args.strip(), startnode="test_start_node", persistent=True,
cmdset_mergetype="Replace", testval="val", testval2="val2")
EvMenu(
self.caller,
self.args.strip(),
startnode="test_start_node",
persistent=True,
cmdset_mergetype="Replace",
testval="val",
testval2="val2",
)