Make scripts/objects lists use EvMore. Change EvMore to not justify by default.

This commit is contained in:
Griatch 2020-01-11 15:49:12 +01:00
parent b5aee2c41e
commit 69d85bd184
221 changed files with 2190 additions and 6810 deletions

View file

@ -96,10 +96,7 @@ class ANSIParser(object):
(r"|-", ANSI_TAB), # tab
(r"|_", ANSI_SPACE), # space
(r"|*", ANSI_INVERSE), # invert
(
r"|^",
ANSI_BLINK,
), # blinking text (very annoying and not supported by all clients)
(r"|^", ANSI_BLINK), # blinking text (very annoying and not supported by all clients)
(r"|u", ANSI_UNDERLINE), # underline
(r"|r", ANSI_HILITE + ANSI_RED),
(r"|g", ANSI_HILITE + ANSI_GREEN),
@ -181,9 +178,7 @@ class ANSIParser(object):
# prepare regex matching
brightbg_sub = re.compile(
r"|".join(
[r"(?<!\|)%s" % re.escape(tup[0]) for tup in ansi_xterm256_bright_bg_map]
),
r"|".join([r"(?<!\|)%s" % re.escape(tup[0]) for tup in ansi_xterm256_bright_bg_map]),
re.DOTALL,
)
xterm256_fg_sub = re.compile(r"|".join(xterm256_fg), re.DOTALL)
@ -264,9 +259,7 @@ class ANSIParser(object):
if not grayscale:
# 6x6x6 color-cube (xterm indexes 16-231)
try:
red, green, blue = [
int(val) for val in rgbmatch.groups() if val is not None
]
red, green, blue = [int(val) for val in rgbmatch.groups() if val is not None]
except (IndexError, ValueError):
logger.log_trace()
return rgbmatch.group(0)
@ -647,14 +640,7 @@ class ANSIMeta(type):
"__len__",
]:
setattr(cls, func_name, _query_super(func_name))
for func_name in [
"__mod__",
"expandtabs",
"decode",
"replace",
"format",
"encode",
]:
for func_name in ["__mod__", "expandtabs", "decode", "replace", "format", "encode"]:
setattr(cls, func_name, _on_raw(func_name))
for func_name in ["capitalize", "translate", "lower", "upper", "swapcase"]:
setattr(cls, func_name, _transform(func_name))
@ -994,9 +980,7 @@ class ANSIString(str, metaclass=ANSIMeta):
# Plain string, no ANSI codes.
return code_indexes, list(range(0, len(self._raw_string)))
# all indexes not occupied by ansi codes are normal characters
char_indexes = [
i for i in range(len(self._raw_string)) if i not in code_indexes
]
char_indexes = [i for i in range(len(self._raw_string)) if i not in code_indexes]
return code_indexes, char_indexes
def _get_interleving(self, index):
@ -1032,12 +1016,8 @@ class ANSIString(str, metaclass=ANSIMeta):
code_indexes = self._code_indexes[:]
char_indexes = self._char_indexes[:]
for i in range(1, other + 1):
code_indexes.extend(
self._shifter(self._code_indexes, i * len(self._raw_string))
)
char_indexes.extend(
self._shifter(self._char_indexes, i * len(self._raw_string))
)
code_indexes.extend(self._shifter(self._code_indexes, i * len(self._raw_string)))
char_indexes.extend(self._shifter(self._char_indexes, i * len(self._raw_string)))
return ANSIString(
raw_string,
code_indexes=code_indexes,
@ -1311,10 +1291,7 @@ class ANSIString(str, metaclass=ANSIMeta):
char_indexes = self._shifter(list(range(0, len(line))), len(prefix))
raw_string = prefix + line + postfix
return ANSIString(
raw_string,
clean_string=line,
char_indexes=char_indexes,
code_indexes=code_indexes,
raw_string, clean_string=line, char_indexes=char_indexes, code_indexes=code_indexes
)
# The following methods should not be called with the '_difference' argument explicitly. This is

View file

@ -214,9 +214,7 @@ def read_batchfile(pythonpath, file_ending=".py"):
"""
# find all possible absolute paths
abspaths = utils.pypath_to_realpath(
pythonpath, file_ending, settings.BASE_BATCHPROCESS_PATHS
)
abspaths = utils.pypath_to_realpath(pythonpath, file_ending, settings.BASE_BATCHPROCESS_PATHS)
if not abspaths:
raise IOError("Absolute batchcmd paths could not be found.")
text = None
@ -349,9 +347,7 @@ class BatchCodeProcessor(object):
"""Run parse_file on the import before sub:ing it into this file"""
path = match.group(1)
try:
return "# batchcode insert (%s):" % path + "\n".join(
self.parse_file(path)
)
return "# batchcode insert (%s):" % path + "\n".join(self.parse_file(path))
except IOError as err:
raise IOError("#INSERT {} failed.".format(path))

View file

@ -113,8 +113,7 @@ class GlobalScriptContainer(Container):
"""
self.typeclass_storage = None
self.loaded_data = {
key: {} if data is None else data
for key, data in settings.GLOBAL_SCRIPTS.items()
key: {} if data is None else data for key, data in settings.GLOBAL_SCRIPTS.items()
}
def _get_scripts(self, key=None, default=None):

View file

@ -363,9 +363,7 @@ help_entry = create_help_entry
# Comm system methods
def create_message(
senderobj, message, channels=None, receivers=None, locks=None, header=None
):
def create_message(senderobj, message, channels=None, receivers=None, locks=None, header=None):
"""
Create a new communication Msg. Msgs represent a unit of
database-persistent communication between entites.
@ -415,9 +413,7 @@ message = create_message
create_msg = create_message
def create_channel(
key, aliases=None, desc=None, locks=None, keep_log=True, typeclass=None
):
def create_channel(key, aliases=None, desc=None, locks=None, keep_log=True, typeclass=None):
"""
Create A communication Channel. A Channel serves as a central hub
for distributing Msgs to groups of people without specifying the
@ -564,11 +560,7 @@ def create_account(
new_account.set_password(password)
new_account._createdict = dict(
locks=locks,
permissions=permissions,
report_to=report_to,
tags=tags,
attributes=attributes,
locks=locks, permissions=permissions, report_to=report_to, tags=tags, attributes=attributes
)
# saving will trigger the signal that calls the
# at_first_save hook on the typeclass, where the _createdict

View file

@ -32,14 +32,7 @@ from django.utils.safestring import SafeString, SafeBytes
from evennia.utils.utils import uses_database, is_iter, to_str, to_bytes
from evennia.utils import logger
__all__ = (
"to_pickle",
"from_pickle",
"do_pickle",
"do_unpickle",
"dbserialize",
"dbunserialize",
)
__all__ = ("to_pickle", "from_pickle", "do_pickle", "do_unpickle", "dbserialize", "dbunserialize")
PICKLE_PROTOCOL = 2
@ -123,9 +116,7 @@ def _init_globals():
global _FROM_MODEL_MAP, _TO_MODEL_MAP, _SESSION_HANDLER, _IGNORE_DATETIME_MODELS
if not _FROM_MODEL_MAP:
_FROM_MODEL_MAP = defaultdict(str)
_FROM_MODEL_MAP.update(
dict((c.model, c.natural_key()) for c in ContentType.objects.all())
)
_FROM_MODEL_MAP.update(dict((c.model, c.natural_key()) for c in ContentType.objects.all()))
if not _TO_MODEL_MAP:
from django.conf import settings
@ -210,9 +201,7 @@ class _SaverMutable(object):
return dat
elif dtype == dict:
dat = _SaverDict(_parent=parent)
dat._data.update(
(key, process_tree(val, dat)) for key, val in item.items()
)
dat._data.update((key, process_tree(val, dat)) for key, val in item.items())
return dat
elif dtype == set:
dat = _SaverSet(_parent=parent)
@ -567,15 +556,11 @@ def to_pickle(data):
elif dtype in (list, _SaverList):
return [process_item(val) for val in item]
elif dtype in (dict, _SaverDict):
return dict(
(process_item(key), process_item(val)) for key, val in item.items()
)
return dict((process_item(key), process_item(val)) for key, val in item.items())
elif dtype in (set, _SaverSet):
return set(process_item(val) for val in item)
elif dtype in (OrderedDict, _SaverOrderedDict):
return OrderedDict(
(process_item(key), process_item(val)) for key, val in item.items()
)
return OrderedDict((process_item(key), process_item(val)) for key, val in item.items())
elif dtype in (deque, _SaverDeque):
return deque(process_item(val) for val in item)
@ -592,9 +577,7 @@ def to_pickle(data):
except TypeError:
return item
except Exception:
logger.log_error(
f"The object {item} of type {type(item)} could not be stored."
)
logger.log_error(f"The object {item} of type {type(item)} could not be stored.")
raise
return process_item(data)
@ -636,15 +619,11 @@ def from_pickle(data, db_obj=None):
elif dtype == tuple:
return tuple(process_item(val) for val in item)
elif dtype == dict:
return dict(
(process_item(key), process_item(val)) for key, val in item.items()
)
return dict((process_item(key), process_item(val)) for key, val in item.items())
elif dtype == set:
return set(process_item(val) for val in item)
elif dtype == OrderedDict:
return OrderedDict(
(process_item(key), process_item(val)) for key, val in item.items()
)
return OrderedDict((process_item(key), process_item(val)) for key, val in item.items())
elif dtype == deque:
return deque(process_item(val) for val in item)
elif hasattr(item, "__iter__"):

View file

@ -332,9 +332,7 @@ def _load_editor(caller):
Load persistent editor from storage.
"""
saved_options = caller.attributes.get("_eveditor_saved")
saved_buffer, saved_undo = caller.attributes.get(
"_eveditor_buffer_temp", (None, None)
)
saved_buffer, saved_undo = caller.attributes.get("_eveditor_buffer_temp", (None, None))
unsaved = caller.attributes.get("_eveditor_unsaved", False)
indent = caller.attributes.get("_eveditor_indent", 0)
if saved_options:
@ -461,9 +459,7 @@ class CmdEditorGroup(CmdEditorBase):
# Echo buffer without the line numbers and syntax parsing
if self.linerange:
buf = linebuffer[lstart:lend]
editor.display_buffer(
buf=buf, offset=lstart, linenums=False, options={"raw": True}
)
editor.display_buffer(buf=buf, offset=lstart, linenums=False, options={"raw": True})
else:
editor.display_buffer(linenums=False, options={"raw": True})
elif cmd == ":::":
@ -515,16 +511,11 @@ class CmdEditorGroup(CmdEditorBase):
if not self.linerange:
lstart = 0
lend = self.cline + 1
caller.msg(
"Removed %s for lines %i-%i."
% (self.arg1, lstart + 1, lend + 1)
)
caller.msg("Removed %s for lines %i-%i." % (self.arg1, lstart + 1, lend + 1))
else:
caller.msg("Removed %s for %s." % (self.arg1, self.lstr))
sarea = "\n".join(linebuffer[lstart:lend])
sarea = re.sub(
r"%s" % self.arg1.strip("'").strip('"'), "", sarea, re.MULTILINE
)
sarea = re.sub(r"%s" % self.arg1.strip("'").strip('"'), "", sarea, re.MULTILINE)
buf = linebuffer[:lstart] + sarea.split("\n") + linebuffer[lend:]
editor.update_buffer(buf)
elif cmd == ":DD":
@ -566,9 +557,7 @@ class CmdEditorGroup(CmdEditorBase):
else:
buf = linebuffer[:lstart] + new_lines + linebuffer[lstart:]
editor.update_buffer(buf)
caller.msg(
"Inserted %i new line(s) at %s." % (len(new_lines), self.lstr)
)
caller.msg("Inserted %i new line(s) at %s." % (len(new_lines), self.lstr))
elif cmd == ":r":
# :r <l> <txt> - replace lines
new_lines = self.args.split("\n")
@ -606,9 +595,7 @@ class CmdEditorGroup(CmdEditorBase):
# :s <li> <w> <txt> - search and replace words
# in entire buffer or on certain lines
if not self.arg1 or not self.arg2:
caller.msg(
"You must give a search word and something to replace it with."
)
caller.msg("You must give a search word and something to replace it with.")
else:
if not self.linerange:
lstart = 0
@ -619,8 +606,7 @@ class CmdEditorGroup(CmdEditorBase):
)
else:
caller.msg(
"Search-replaced %s -> %s for %s."
% (self.arg1, self.arg2, self.lstr)
"Search-replaced %s -> %s for %s." % (self.arg1, self.arg2, self.lstr)
)
sarea = "\n".join(linebuffer[lstart:lend])
@ -673,9 +659,7 @@ class CmdEditorGroup(CmdEditorBase):
if not self.linerange:
lstart = 0
lend = self.cline + 1
self.caller.msg(
"%s-justified lines %i-%i." % (align_name[align], lstart + 1, lend)
)
self.caller.msg("%s-justified lines %i-%i." % (align_name[align], lstart + 1, lend))
else:
self.caller.msg("%s-justified %s." % (align_name[align], self.lstr))
jbuf = "\n".join(linebuffer[lstart:lend])
@ -699,9 +683,7 @@ class CmdEditorGroup(CmdEditorBase):
if not self.linerange:
lstart = 0
lend = self.cline + 1
caller.msg(
"Removed left margin (dedented) lines %i-%i." % (lstart + 1, lend)
)
caller.msg("Removed left margin (dedented) lines %i-%i." % (lstart + 1, lend))
else:
caller.msg("Removed left margin (dedented) %s." % self.lstr)
fbuf = "\n".join(linebuffer[lstart:lend])
@ -723,9 +705,7 @@ class CmdEditorGroup(CmdEditorBase):
editor.decrease_indent()
indent = editor._indent
if indent >= 0:
caller.msg(
"Decreased indentation: new indentation is {}.".format(indent)
)
caller.msg("Decreased indentation: new indentation is {}.".format(indent))
else:
caller.msg("|rManual indentation is OFF.|n Use := to turn it on.")
else:
@ -736,9 +716,7 @@ class CmdEditorGroup(CmdEditorBase):
editor.increase_indent()
indent = editor._indent
if indent >= 0:
caller.msg(
"Increased indentation: new indentation is {}.".format(indent)
)
caller.msg("Increased indentation: new indentation is {}.".format(indent))
else:
caller.msg("|rManual indentation is OFF.|n Use := to turn it on.")
else:
@ -880,9 +858,7 @@ class EvEditor(object):
dict(_pristine_buffer=self._pristine_buffer, _sep=self._sep),
),
)
caller.attributes.add(
"_eveditor_buffer_temp", (self._buffer, self._undo_buffer)
)
caller.attributes.add("_eveditor_buffer_temp", (self._buffer, self._undo_buffer))
caller.attributes.add("_eveditor_unsaved", False)
caller.attributes.add("_eveditor_indent", 0)
except Exception as err:
@ -1001,15 +977,11 @@ class EvEditor(object):
self._caller.msg(_MSG_UNDO)
elif step and step > 0:
# redo
if (
self._undo_pos >= len(self._undo_buffer) - 1
or self._undo_pos + 1 >= self._undo_max
):
if self._undo_pos >= len(self._undo_buffer) - 1 or self._undo_pos + 1 >= self._undo_max:
self._caller.msg(_MSG_NO_REDO)
else:
self._undo_pos = min(
self._undo_pos + step,
min(len(self._undo_buffer), self._undo_max) - 1,
self._undo_pos + step, min(len(self._undo_buffer), self._undo_max) - 1
)
self._buffer = self._undo_buffer[self._undo_pos]
self._caller.msg(_MSG_REDO)

View file

@ -168,9 +168,7 @@ def _to_ansi(obj, regexable=False):
# escape the |-structure twice.
obj = _ANSI_ESCAPE.sub(r"||||", obj)
if isinstance(obj, dict):
return dict(
(key, _to_ansi(value, regexable=regexable)) for key, value in obj.items()
)
return dict((key, _to_ansi(value, regexable=regexable)) for key, value in obj.items())
elif is_iter(obj):
return [_to_ansi(o) for o in obj]
else:
@ -210,9 +208,7 @@ class EvForm(object):
dict((to_str(key), value) for key, value in cells.items()) if cells else {}
)
self.tables_mapping = (
dict((to_str(key), value) for key, value in tables.items())
if tables
else {}
dict((to_str(key), value) for key, value in tables.items()) if tables else {}
)
self.cellchar = "x"
@ -284,9 +280,7 @@ class EvForm(object):
dy_up = 0
if iy > 0:
for i in range(1, iy):
if all(
form[iy - i][ix] == cellchar for ix in range(leftix, rightix)
):
if all(form[iy - i][ix] == cellchar for ix in range(leftix, rightix)):
dy_up += 1
else:
break
@ -294,9 +288,7 @@ class EvForm(object):
dy_down = 0
if iy < nform - 1:
for i in range(1, nform - iy - 1):
if all(
form[iy + i][ix] == cellchar for ix in range(leftix, rightix)
):
if all(form[iy + i][ix] == cellchar for ix in range(leftix, rightix)):
dy_down += 1
else:
break
@ -338,9 +330,7 @@ class EvForm(object):
dy_up = 0
if iy > 0:
for i in range(1, iy):
if all(
form[iy - i][ix] == tablechar for ix in range(leftix, rightix)
):
if all(form[iy - i][ix] == tablechar for ix in range(leftix, rightix)):
dy_up += 1
else:
break
@ -348,9 +338,7 @@ class EvForm(object):
dy_down = 0
if iy < nform - 1:
for i in range(1, nform - iy - 1):
if all(
form[iy + i][ix] == tablechar for ix in range(leftix, rightix)
):
if all(form[iy + i][ix] == tablechar for ix in range(leftix, rightix)):
dy_down += 1
else:
break
@ -416,14 +404,8 @@ class EvForm(object):
kwargs.pop("width", None)
kwargs.pop("height", None)
new_cells = (
dict((to_str(key), value) for key, value in cells.items()) if cells else {}
)
new_tables = (
dict((to_str(key), value) for key, value in tables.items())
if tables
else {}
)
new_cells = dict((to_str(key), value) for key, value in cells.items()) if cells else {}
new_tables = dict((to_str(key), value) for key, value in tables.items()) if tables else {}
self.cells_mapping.update(new_cells)
self.tables_mapping.update(new_tables)
@ -501,9 +483,7 @@ def _test():
}
)
# create the EvTables
tableA = EvTable(
"HP", "MV", "MP", table=[["**"], ["*****"], ["***"]], border="incols"
)
tableA = EvTable("HP", "MV", "MP", table=[["**"], ["*****"], ["***"]], border="incols")
tableB = EvTable(
"Skill",
"Value",

View file

@ -173,16 +173,7 @@ from evennia import Command, CmdSet
from evennia.utils import logger
from evennia.utils.evtable import EvTable
from evennia.utils.ansi import strip_ansi
from evennia.utils.utils import (
mod_import,
make_iter,
pad,
to_str,
m_len,
is_iter,
dedent,
crop,
)
from evennia.utils.utils import mod_import, make_iter, pad, to_str, m_len, is_iter, dedent, crop
from evennia.commands import cmdhandler
# read from protocol NAWS later?
@ -199,8 +190,7 @@ _CMD_NOINPUT = cmdhandler.CMD_NOINPUT
from django.utils.translation import ugettext as _
_ERR_NOT_IMPLEMENTED = _(
"Menu node '{nodename}' is either not implemented or "
"caused an error. Make another choice."
"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.")
@ -533,16 +523,10 @@ class EvMenu(object):
}
calldict.update(kwargs)
try:
caller.attributes.add(
"_menutree_saved", (self.__class__, (menudata,), calldict)
)
caller.attributes.add(
"_menutree_saved_startnode", (startnode, startnode_input)
)
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
)
caller.msg(_ERROR_PERSISTENT_SAVING.format(error=err), session=self._session)
logger.log_trace(_TRACE_PERSISTENT_SAVING)
persistent = False
@ -556,9 +540,7 @@ class EvMenu(object):
if isinstance(startnode_input, (tuple, list)) and len(startnode_input) > 1:
startnode_input, startnode_kwargs = startnode_input[:2]
if not isinstance(startnode_kwargs, dict):
raise EvMenuError(
"startnode_input must be either a str or a tuple (str, dict)."
)
raise EvMenuError("startnode_input must be either a str or a tuple (str, dict).")
# start the menu
self.goto(self._startnode, startnode_input, **startnode_kwargs)
@ -628,14 +610,10 @@ class EvMenu(object):
try:
nargs = len(getargspec(callback).args)
except TypeError:
raise EvMenuError(
"Callable {} doesn't accept any arguments!".format(callback)
)
raise EvMenuError("Callable {} doesn't accept any arguments!".format(callback))
supports_kwargs = bool(getargspec(callback).keywords)
if nargs <= 0:
raise EvMenuError(
"Callable {} doesn't accept any arguments!".format(callback)
)
raise EvMenuError("Callable {} doesn't accept any arguments!".format(callback))
if supports_kwargs:
if nargs > 1:
@ -677,9 +655,7 @@ class EvMenu(object):
try:
node = self._menutree[nodename]
except KeyError:
self.caller.msg(
_ERR_NOT_IMPLEMENTED.format(nodename=nodename), session=self._session
)
self.caller.msg(_ERR_NOT_IMPLEMENTED.format(nodename=nodename), session=self._session)
raise EvMenuError
try:
ret = self._safe_call(node, raw_string, **kwargs)
@ -688,15 +664,11 @@ class EvMenu(object):
else:
nodetext, options = ret, None
except KeyError:
self.caller.msg(
_ERR_NOT_IMPLEMENTED.format(nodename=nodename), session=self._session
)
self.caller.msg(_ERR_NOT_IMPLEMENTED.format(nodename=nodename), session=self._session)
logger.log_trace()
raise EvMenuError
except Exception:
self.caller.msg(
_ERR_GENERAL.format(nodename=nodename), session=self._session
)
self.caller.msg(_ERR_GENERAL.format(nodename=nodename), session=self._session)
logger.log_trace()
raise
@ -746,16 +718,10 @@ class EvMenu(object):
ret = self._execute_node(nodename, raw_string, **kwargs)
if isinstance(ret, (tuple, list)):
if not len(ret) > 1 and ret[1] and not isinstance(ret[1], dict):
raise EvMenuError(
"exec node must return either None, str or (str, dict)"
)
raise EvMenuError("exec node must return either None, str or (str, dict)")
ret, kwargs = ret[:2]
except EvMenuError as err:
errmsg = "Error in exec '%s' (input: '%s'): %s" % (
nodename,
raw_string.rstrip(),
err,
)
errmsg = "Error in exec '%s' (input: '%s'): %s" % (nodename, raw_string.rstrip(), err)
self.caller.msg("|r%s|n" % errmsg)
logger.log_trace(errmsg)
return
@ -835,9 +801,7 @@ 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:
@ -876,16 +840,12 @@ class EvMenu(object):
desc = dic.get("desc", dic.get("text", None))
if "_default" in keys:
keys = [key for key in keys if key != "_default"]
goto, goto_kwargs, execute, exec_kwargs = self.extract_goto_exec(
nodename, dic
)
goto, goto_kwargs, execute, exec_kwargs = self.extract_goto_exec(nodename, dic)
self.default = (goto, goto_kwargs, execute, exec_kwargs)
else:
# use the key (only) if set, otherwise use the running number
keys = list(make_iter(dic.get("key", str(inum + 1).strip())))
goto, goto_kwargs, execute, exec_kwargs = self.extract_goto_exec(
nodename, dic
)
goto, goto_kwargs, execute, exec_kwargs = self.extract_goto_exec(nodename, dic)
if keys:
display_options.append((keys[0], desc))
for key in keys:
@ -907,17 +867,13 @@ class EvMenu(object):
elif options:
self.helptext = _HELP_FULL if self.auto_quit else _HELP_NO_QUIT
else:
self.helptext = (
_HELP_NO_OPTIONS if self.auto_quit else _HELP_NO_OPTIONS_NO_QUIT
)
self.helptext = _HELP_NO_OPTIONS if self.auto_quit else _HELP_NO_OPTIONS_NO_QUIT
self.display_nodetext()
if not options:
self.close_menu()
def run_exec_then_goto(
self, runexec, goto, raw_string, runexec_kwargs=None, goto_kwargs=None
):
def run_exec_then_goto(self, runexec, goto, raw_string, runexec_kwargs=None, goto_kwargs=None):
"""
Call 'exec' callback and goto (which may also be a callable) in sequence.
@ -965,18 +921,12 @@ 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)
]
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("__")
if prop not in all_methods and prop not in all_builtins and not prop.endswith("__")
}
local = {
@ -994,13 +944,11 @@ class EvMenu(object):
debugtxt = (
"|yMENU DEBUG full ... |n\n"
+ "\n".join(
"|y *|n {}: {}".format(key, val)
for key, val in sorted(props.items())
"|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())
"|y *|n {}: {}".format(key, val) for key, val in sorted(local.items())
)
+ "\n |y... END MENU DEBUG|n"
)
@ -1010,16 +958,12 @@ class EvMenu(object):
debugtxt = (
"|yMENU DEBUG properties ... |n\n"
+ "\n".join(
"|y *|n {}: {}".format(
key, crop(to_str(val, force_string=True), width=50)
)
"|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)
)
"|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"
@ -1045,9 +989,7 @@ class EvMenu(object):
# this will take precedence over the default commands
# below
goto, goto_kwargs, execfunc, exec_kwargs = self.options[cmd]
self.run_exec_then_goto(
execfunc, goto, raw_string, exec_kwargs, goto_kwargs
)
self.run_exec_then_goto(execfunc, goto, raw_string, exec_kwargs, goto_kwargs)
elif self.auto_look and cmd in ("look", "l"):
self.display_nodetext()
elif self.auto_help and cmd in ("help", "h"):
@ -1058,9 +1000,7 @@ class EvMenu(object):
self.print_debug_info(cmd[9:].strip())
elif self.default:
goto, goto_kwargs, execfunc, exec_kwargs = self.default
self.run_exec_then_goto(
execfunc, goto, raw_string, exec_kwargs, goto_kwargs
)
self.run_exec_then_goto(execfunc, goto, raw_string, exec_kwargs, goto_kwargs)
else:
self.caller.msg(_HELP_NO_OPTION_MATCH, session=self._session)
@ -1137,9 +1077,7 @@ class EvMenu(object):
table.append(" |lc%s|lt%s|le%s" % (raw_key, key, desc_string))
else:
# add a default white color to key
table.append(
" |lc%s|lt|w%s|n|le%s" % (raw_key, raw_key, desc_string)
)
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
if ncols < 0:
@ -1161,19 +1099,14 @@ 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
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]
]
table[icol] = [pad(part, width=col_width + colsep, align="l") for part in table[icol]]
# format the table into columns
return str(EvTable(table=table, border="none"))
@ -1194,9 +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
@ -1263,9 +1194,7 @@ def list_node(option_generator, select=None, pagesize=10):
if callable(select):
try:
if bool(getargspec(select).keywords):
return select(
caller, selection, available_choices=available_choices
)
return select(caller, selection, available_choices=available_choices)
else:
return select(caller, selection)
except Exception:
@ -1281,9 +1210,7 @@ def list_node(option_generator, select=None, pagesize=10):
def _list_node(caller, raw_string, **kwargs):
option_list = (
option_generator(caller)
if callable(option_generator)
else option_generator
option_generator(caller) if callable(option_generator) else option_generator
)
npages = 0
@ -1294,8 +1221,7 @@ 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)
option_list[ind : ind + pagesize] for ind in range(0, nall_options, pagesize)
]
npages = len(pages)
@ -1329,20 +1255,14 @@ def list_node(option_generator, select=None, pagesize=10):
options.append(
{
"key": ("|wp|Wrevious page|n", "p"),
"goto": (
lambda caller: None,
{"optionpage_index": page_index - 1},
),
"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},
),
"goto": (lambda caller: None, {"optionpage_index": page_index + 1}),
}
)
@ -1375,9 +1295,7 @@ def list_node(option_generator, select=None, pagesize=10):
if isinstance(decorated_options, dict):
decorated_options = [decorated_options]
for eopt in decorated_options:
cback = (
("goto" in eopt and "goto") or ("exec" in eopt and "exec") or None
)
cback = ("goto" in eopt and "goto") or ("exec" in eopt and "exec") or None
if cback:
signature = eopt[cback]
if callable(signature):
@ -1437,9 +1355,7 @@ class CmdGetInput(Command):
prompt = caller.ndb._getinput._prompt
args = caller.ndb._getinput._args
kwargs = caller.ndb._getinput._kwargs
result = (
self.raw_string.rstrip()
) # we strip the ending line break caused by sending
result = self.raw_string.rstrip() # we strip the ending line break caused by sending
ok = not callback(caller, prompt, result, *args, **kwargs)
if ok:
@ -1587,11 +1503,7 @@ def test_start_node(caller):
"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": ("|yV|niew", "v"), "desc": "View your own name", "goto": "test_view_node"},
{
"key": ("|yD|nynamic", "d"),
"desc": "Dynamic node",
@ -1721,10 +1633,7 @@ def test_dynamic_node(caller, **kwargs):
"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": "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}),

View file

@ -39,6 +39,8 @@ _CMD_NOINPUT = cmdhandler.CMD_NOINPUT
_SCREEN_WIDTH = settings.CLIENT_DEFAULT_WIDTH
_SCREEN_HEIGHT = settings.CLIENT_DEFAULT_HEIGHT
_EVTABLE = None
# text
_DISPLAY = """{text}
@ -51,20 +53,7 @@ class CmdMore(Command):
"""
key = _CMD_NOINPUT
aliases = [
"quit",
"q",
"abort",
"a",
"next",
"n",
"back",
"b",
"top",
"t",
"end",
"e",
]
aliases = ["quit", "q", "abort", "a", "next", "n", "back", "b", "top", "t", "end", "e"]
auto_help = False
def func(self):
@ -139,28 +128,38 @@ class EvMore(object):
text,
always_page=False,
session=None,
justify=False,
justify_kwargs=None,
exit_on_lastpage=False,
exit_cmd=None,
**kwargs,
):
"""
Initialization of the text handler.
Args:
caller (Object or Account): Entity reading the text.
text (str or iterator): The text to put under paging. If an iterator,
each iteration step is expected to be a line in the final display,
and each line will be run through repr().
text (str, EvTable or iterator): The text or data to put under paging.
- If a string, paginage normally. If this text contains
one or more `\f` format symbol, automatic pagination and justification
are force-disabled and page-breaks will only happen after each `\f`.
- If `EvTable`, the EvTable will be paginated with the same
setting on each page if it is too long. The table
decorations will be considered in the size of the page.
- Otherwise `text` is converted to an iterator, where each step is
expected to be a line in the final display. Each line
will be run through repr() (so one could pass a list of objects).
always_page (bool, optional): If `False`, the
pager will only kick in if `text` is too big
to fit the screen.
session (Session, optional): If given, this session will be used
to determine the screen width and will receive all output.
justify_kwargs (dict, bool or None, optional): If given, this should
be valid keyword arguments to the utils.justify() function. If False,
no justification will be done (especially important for handling
fixed-width text content, like tables!).
justify (bool, optional): If set, auto-justify long lines. This must be turned
off for fixed-width or formatted output, like tables. It's force-disabled
if `text` is an EvTable.
justify_kwargs (dict, optional): Keywords for the justifiy function. Used only
if `justify` is True. If this is not set, default arguments will be used.
exit_on_lastpage (bool, optional): If reaching the last page without the
page being completely filled, exit pager immediately. If unset,
another move forward is required to exit. If set, the pager
@ -169,8 +168,7 @@ class EvMore(object):
the caller when the more page exits. Note that this will be using whatever
cmdset the user had *before* the evmore pager was activated (so none of
the evmore commands will be available when this is run).
kwargs (any, optional): These will be passed on
to the `caller.msg` method.
kwargs (any, optional): These will be passed on to the `caller.msg` method.
Examples:
super_long_text = " ... "
@ -181,6 +179,11 @@ class EvMore(object):
pages = Paginator(query, 10) # 10 objs per page
EvMore(caller, pages) # will repr() each object per line, 10 to a page
multi_page_table = [ [[..],[..]], ...]
EvMore(caller, multi_page_table, use_evtable=True,
evtable_args=("Header1", "Header2"),
evtable_kwargs={"align": "r", "border": "tablecols"})
"""
self._caller = caller
self._kwargs = kwargs
@ -190,6 +193,7 @@ class EvMore(object):
self.exit_on_lastpage = exit_on_lastpage
self.exit_cmd = exit_cmd
self._exit_msg = "Exited |wmore|n pager."
if not session:
# if not supplied, use the first session to
# determine screen size
@ -200,27 +204,36 @@ class EvMore(object):
self._session = session
# set up individual pages for different sessions
height = max(
4, session.protocol_flags.get("SCREENHEIGHT", {0: _SCREEN_HEIGHT})[0] - 4
)
height = max(4, session.protocol_flags.get("SCREENHEIGHT", {0: _SCREEN_HEIGHT})[0] - 4)
width = session.protocol_flags.get("SCREENWIDTH", {0: _SCREEN_WIDTH})[0]
# analyze text
if hasattr(text, "table") and hasattr(text, "get"):
# This is an EvTable.
table = text
if table.height:
# enforced height of each paged table, plus space for evmore extras
height = table.height - 4
# convert table to string
text = str(text)
justify_kwargs = None # enforce
if not isinstance(text, str):
# not a string - pre-set pages of some form
text = "\n".join(str(repr(element)) for element in make_iter(text))
# the normal case - a string we need to manually split.
if "\f" in text:
# we use \f to indicate the user wants to enforce their line breaks
# on their own. If so, we do no automatic line-breaking/justification
# at all.
self._pages = text.split("\f")
self._npages = len(self._pages)
self._npos = 0
else:
if justify_kwargs is False:
# no justification. Simple division by line
lines = text.split("\n")
else:
# we must break very long lines into multiple ones
if justify:
# we must break very long lines into multiple ones. Note that this
# will also remove spurious whitespace.
justify_kwargs = justify_kwargs or {}
width = justify_kwargs.get("width", width)
justify_kwargs["width"] = width
@ -233,19 +246,20 @@ class EvMore(object):
lines.extend(justify(line, **justify_kwargs).split("\n"))
else:
lines.append(line)
else:
# no justification. Simple division by line
lines = text.split("\n")
# always limit number of chars to 10 000 per page
height = min(10000 // max(1, width), height)
self._pages = [
"\n".join(lines[i : i + height]) for i in range(0, len(lines), height)
]
# figure out the pagination
self._pages = ["\n".join(lines[i : i + height]) for i in range(0, len(lines), height)]
self._npages = len(self._pages)
self._npos = 0
if self._npages <= 1 and not always_page:
# no need for paging; just pass-through.
caller.msg(text=text, session=self._session, **kwargs)
caller.msg(text=self._get_page(0), session=self._session, **kwargs)
else:
# go into paging mode
# first pass on the msg kwargs
@ -255,12 +269,15 @@ class EvMore(object):
# goto top of the text
self.page_top()
def _get_page(self, pos):
return self._pages[pos]
def display(self, show_footer=True):
"""
Pretty-print the page.
"""
pos = self._npos
text = self._pages[pos]
text = self._get_page(pos)
if show_footer:
page = _DISPLAY.format(text=text, pageno=pos + 1, pagemax=self._npages)
else:
@ -324,30 +341,51 @@ class EvMore(object):
self._caller.execute_cmd(self.exit_cmd, session=self._session)
# helper function
def msg(
caller,
text="",
always_page=False,
session=None,
justify=False,
justify_kwargs=None,
exit_on_lastpage=True,
**kwargs,
):
"""
More-supported version of msg, mimicking the normal msg method.
EvMore-supported version of msg, mimicking the normal msg method.
Args:
caller (Object or Account): Entity reading the text.
text (str): The text to put under paging.
text (str, EvTable or iterator): The text or data to put under paging.
- If a string, paginage normally. If this text contains
one or more `\f` format symbol, automatic pagination is disabled
and page-breaks will only happen after each `\f`.
- If `EvTable`, the EvTable will be paginated with the same
setting on each page if it is too long. The table
decorations will be considered in the size of the page.
- Otherwise `text` is converted to an iterator, where each step is
is expected to be a line in the final display, and each line
will be run through repr().
always_page (bool, optional): If `False`, the
pager will only kick in if `text` is too big
to fit the screen.
session (Session, optional): If given, this session will be used
to determine the screen width and will receive all output.
justify (bool, optional): If set, justify long lines in output. Disable for
fixed-format output, like tables.
justify_kwargs (dict, bool or None, optional): If given, this should
be valid keyword arguments to the utils.justify() function. If False,
no justification will be done.
exit_on_lastpage (bool, optional): Immediately exit pager when reaching the last page.
use_evtable (bool, optional): If True, each page will be rendered as an
EvTable. For this to work, `text` must be an iterable, where each element
is the table (list of list) to render on that page.
evtable_args (tuple, optional): The args to use for EvTable on each page.
evtable_kwargs (dict, optional): The kwargs to use for EvTable on each
page (except `table`, which is supplied by EvMore per-page).
kwargs (any, optional): These will be passed on
to the `caller.msg` method.
@ -357,6 +395,7 @@ def msg(
text,
always_page=always_page,
session=session,
justify=justify,
justify_kwargs=justify_kwargs,
exit_on_lastpage=exit_on_lastpage,
**kwargs,

View file

@ -387,18 +387,10 @@ class EvCell(object):
self.formatted = None
padwidth = kwargs.get("pad_width", None)
padwidth = int(padwidth) if padwidth is not None else None
self.pad_left = int(
kwargs.get("pad_left", padwidth if padwidth is not None else 1)
)
self.pad_right = int(
kwargs.get("pad_right", padwidth if padwidth is not None else 1)
)
self.pad_top = int(
kwargs.get("pad_top", padwidth if padwidth is not None else 0)
)
self.pad_bottom = int(
kwargs.get("pad_bottom", padwidth if padwidth is not None else 0)
)
self.pad_left = int(kwargs.get("pad_left", padwidth if padwidth is not None else 1))
self.pad_right = int(kwargs.get("pad_right", padwidth if padwidth is not None else 1))
self.pad_top = int(kwargs.get("pad_top", padwidth if padwidth is not None else 0))
self.pad_bottom = int(kwargs.get("pad_bottom", padwidth if padwidth is not None else 0))
self.enforce_size = kwargs.get("enforce_size", False)
@ -427,15 +419,11 @@ class EvCell(object):
self.border_bottom = kwargs.get("border_bottom", borderwidth)
borderchar = kwargs.get("border_char", None)
self.border_left_char = kwargs.get(
"border_left_char", borderchar if borderchar else "|"
)
self.border_left_char = kwargs.get("border_left_char", borderchar if borderchar else "|")
self.border_right_char = kwargs.get(
"border_right_char", borderchar if borderchar else self.border_left_char
)
self.border_top_char = kwargs.get(
"border_top_char", borderchar if borderchar else "-"
)
self.border_top_char = kwargs.get("border_top_char", borderchar if borderchar else "-")
self.border_bottom_char = kwargs.get(
"border_bottom_char", borderchar if borderchar else self.border_top_char
)
@ -443,12 +431,8 @@ class EvCell(object):
corner_char = kwargs.get("corner_char", "+")
self.corner_top_left_char = kwargs.get("corner_top_left_char", corner_char)
self.corner_top_right_char = kwargs.get("corner_top_right_char", corner_char)
self.corner_bottom_left_char = kwargs.get(
"corner_bottom_left_char", corner_char
)
self.corner_bottom_right_char = kwargs.get(
"corner_bottom_right_char", corner_char
)
self.corner_bottom_left_char = kwargs.get("corner_bottom_left_char", corner_char)
self.corner_bottom_right_char = kwargs.get("corner_bottom_right_char", corner_char)
# alignments
self.align = kwargs.get("align", "l")
@ -466,11 +450,7 @@ class EvCell(object):
if "width" in kwargs:
width = kwargs.pop("width")
self.width = (
width
- self.pad_left
- self.pad_right
- self.border_left
- self.border_right
width - self.pad_left - self.pad_right - self.border_left - self.border_right
)
if self.width <= 0 < self.raw_width:
raise Exception("Cell width too small - no space for data.")
@ -479,11 +459,7 @@ class EvCell(object):
if "height" in kwargs:
height = kwargs.pop("height")
self.height = (
height
- self.pad_top
- self.pad_bottom
- self.border_top
- self.border_bottom
height - self.pad_top - self.pad_bottom - self.border_top - self.border_bottom
)
if self.height <= 0 < self.raw_height:
raise Exception("Cell height too small - no space for data.")
@ -512,9 +488,7 @@ class EvCell(object):
Apply all EvCells' formatting operations.
"""
data = self._border(
self._pad(self._valign(self._align(self._fit_width(self.data))))
)
data = self._border(self._pad(self._valign(self._align(self._fit_width(self.data)))))
return data
def _split_lines(self, text):
@ -567,9 +541,7 @@ class EvCell(object):
adjusted_data = adjusted_data[:-excess]
crop_string_length = len(crop_string)
if len(adjusted_data[-1]) > crop_string_length:
adjusted_data[-1] = (
adjusted_data[-1][:-crop_string_length] + crop_string
)
adjusted_data[-1] = adjusted_data[-1][:-crop_string_length] + crop_string
else:
adjusted_data[-1] += crop_string
elif excess < 0:
@ -816,17 +788,13 @@ class EvCell(object):
kwargs.pop("pad_left", padwidth if padwidth is not None else self.pad_left)
)
self.pad_right = int(
kwargs.pop(
"pad_right", padwidth if padwidth is not None else self.pad_right
)
kwargs.pop("pad_right", padwidth if padwidth is not None else self.pad_right)
)
self.pad_top = int(
kwargs.pop("pad_top", padwidth if padwidth is not None else self.pad_top)
)
self.pad_bottom = int(
kwargs.pop(
"pad_bottom", padwidth if padwidth is not None else self.pad_bottom
)
kwargs.pop("pad_bottom", padwidth if padwidth is not None else self.pad_bottom)
)
self.enforce_size = kwargs.get("enforce_size", False)
@ -848,15 +816,13 @@ class EvCell(object):
"border_left", borderwidth if borderwidth is not None else self.border_left
)
self.border_right = kwargs.pop(
"border_right",
borderwidth if borderwidth is not None else self.border_right,
"border_right", borderwidth if borderwidth is not None else self.border_right
)
self.border_top = kwargs.pop(
"border_top", borderwidth if borderwidth is not None else self.border_top
)
self.border_bottom = kwargs.pop(
"border_bottom",
borderwidth if borderwidth is not None else self.border_bottom,
"border_bottom", borderwidth if borderwidth is not None else self.border_bottom
)
borderchar = kwargs.get("border_char", None)
@ -875,8 +841,7 @@ class EvCell(object):
corner_char = kwargs.get("corner_char", None)
self.corner_top_left_char = kwargs.pop(
"corner_top_left",
corner_char if corner_char is not None else self.corner_top_left_char,
"corner_top_left", corner_char if corner_char is not None else self.corner_top_left_char
)
self.corner_top_right_char = kwargs.pop(
"corner_top_right",
@ -1142,8 +1107,9 @@ class EvTable(object):
Exception: If given erroneous input or width settings for the data.
Notes:
Beyond those table-specific keywords, the non-overlapping keywords of `EcCell.__init__` are
also available. These will be passed down to every cell in the table.
Beyond those table-specific keywords, the non-overlapping keywords
of `EcCell.__init__` are also available. These will be passed down
to every cell in the table.
"""
# at this point table is a 2D grid - a list of columns
@ -1203,9 +1169,7 @@ class EvTable(object):
kwargs.pop("corner_bottom_left_char", " " if pcorners else self.corner_char)
)
self.corner_bottom_right_char = _to_ansi(
kwargs.pop(
"corner_bottom_right_char", " " if pcorners else self.corner_char
)
kwargs.pop("corner_bottom_right_char", " " if pcorners else self.corner_char)
)
self.width = kwargs.pop("width", None)
@ -1395,9 +1359,7 @@ class EvTable(object):
if ncols:
# get minimum possible cell widths for each row
cwidths_min = [
max(cell.get_min_width() for cell in col) for col in self.worktable
]
cwidths_min = [max(cell.get_min_width() for cell in col) for col in self.worktable]
cwmin = sum(cwidths_min)
# get which cols have separately set widths - these should be locked
@ -1481,10 +1443,7 @@ class EvTable(object):
# get minimum possible cell heights for each column
cheights_min = [
max(
cell.get_min_height()
for cell in (col[iy] for col in self.worktable)
)
max(cell.get_min_height() for cell in (col[iy] for col in self.worktable))
for iy in range(nrowmax)
]
chmin = sum(cheights_min)
@ -1545,12 +1504,7 @@ class EvTable(object):
try:
col.reformat_cell(iy, height=cheights[iy], **options)
except Exception as e:
msg = "ix=%s, iy=%s, height=%s: %s" % (
ix,
iy,
cheights[iy],
e.message,
)
msg = "ix=%s, iy=%s, height=%s: %s" % (ix, iy, cheights[iy], e.message)
raise Exception("Error in vertical align:\n %s" % msg)
# calculate actual table width/height in characters
@ -1570,9 +1524,7 @@ class EvTable(object):
cell_data = [cell.get() for cell in cell_row]
cell_height = min(len(lines) for lines in cell_data)
for iline in range(cell_height):
yield ANSIString("").join(
_to_ansi(celldata[iline] for celldata in cell_data)
)
yield ANSIString("").join(_to_ansi(celldata[iline] for celldata in cell_data))
def add_header(self, *args, **kwargs):
"""
@ -1726,12 +1678,8 @@ class EvTable(object):
self.corner_char = kwargs.get("corner_char", self.corner_char)
self.header_line_char = kwargs.get("header_line_char", self.header_line_char)
self.corner_top_left_char = _to_ansi(
kwargs.pop("corner_top_left_char", self.corner_char)
)
self.corner_top_right_char = _to_ansi(
kwargs.pop("corner_top_right_char", self.corner_char)
)
self.corner_top_left_char = _to_ansi(kwargs.pop("corner_top_left_char", self.corner_char))
self.corner_top_right_char = _to_ansi(kwargs.pop("corner_top_right_char", self.corner_char))
self.corner_bottom_left_char = _to_ansi(
kwargs.pop("corner_bottom_left_char", self.corner_char)
)
@ -1776,9 +1724,7 @@ class EvTable(object):
def __str__(self):
"""print table (this also balances it)"""
# h = "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
return str(
str(ANSIString("\n").join([line for line in self._generate_lines()]))
)
return str(str(ANSIString("\n").join([line for line in self._generate_lines()])))
def _test():

View file

@ -89,8 +89,7 @@ def server_epoch():
global _SERVER_EPOCH
if not _SERVER_EPOCH:
_SERVER_EPOCH = (
ServerConfig.objects.conf("server_epoch", default=None)
or time.time() - runtime()
ServerConfig.objects.conf("server_epoch", default=None) or time.time() - runtime()
)
return _SERVER_EPOCH
@ -212,14 +211,7 @@ def real_seconds_until(sec=None, min=None, hour=None, day=None, month=None, year
def schedule(
callback,
repeat=False,
sec=None,
min=None,
hour=None,
day=None,
month=None,
year=None,
callback, repeat=False, sec=None, min=None, hour=None, day=None, month=None, year=None
):
"""
Call a callback at a given in-game time.
@ -244,9 +236,7 @@ def schedule(
schedule(func, min=5, sec=0) # Will call 5 minutes past the next (in-game) hour.
schedule(func, hour=2, min=30, sec=0) # Will call the next (in-game) day at 02:30.
"""
seconds = real_seconds_until(
sec=sec, min=min, hour=hour, day=day, month=month, year=year
)
seconds = real_seconds_until(sec=sec, min=min, hour=hour, day=day, month=month, year=year)
script = create_script(
"evennia.utils.gametime.TimeScript",
key="TimeScript",

View file

@ -40,10 +40,7 @@ PROC_MODIFIED_OBJS = WeakValueDictionary()
# subprocess or not)
_SELF_PID = os.getpid()
_SERVER_PID, _PORTAL_PID = get_evennia_pids()
_IS_SUBPROCESS = (_SERVER_PID and _PORTAL_PID) and _SELF_PID not in (
_SERVER_PID,
_PORTAL_PID,
)
_IS_SUBPROCESS = (_SERVER_PID and _PORTAL_PID) and _SELF_PID not in (_SERVER_PID, _PORTAL_PID)
_IS_MAIN_THREAD = threading.currentThread().getName() == "MainThread"
@ -111,9 +108,7 @@ class SharedMemoryModelBase(ModelBase):
attrs["_is_deleted"] = False
# set up the typeclass handling only if a variable _is_typeclass is set on the class
def create_wrapper(
cls, fieldname, wrappername, editable=True, foreignkey=False
):
def create_wrapper(cls, fieldname, wrappername, editable=True, foreignkey=False):
"Helper method to create property wrappers with unique names (must be in separate call)"
def _get(cls, fname):
@ -140,16 +135,13 @@ class SharedMemoryModelBase(ModelBase):
"Wrapper for setting database field"
if _GA(cls, "_is_deleted"):
raise ObjectDoesNotExist(
"Cannot set %s to %s: Hosting object was already deleted!"
% (fname, value)
"Cannot set %s to %s: Hosting object was already deleted!" % (fname, value)
)
_SA(cls, fname, value)
# only use explicit update_fields in save if we actually have a
# primary key assigned already (won't be set when first creating object)
update_fields = (
[fname]
if _GA(cls, "_get_pk_val")(_GA(cls, "_meta")) is not None
else None
[fname] if _GA(cls, "_get_pk_val")(_GA(cls, "_meta")) is not None else None
)
_GA(cls, "save")(update_fields=update_fields)
@ -157,8 +149,7 @@ class SharedMemoryModelBase(ModelBase):
"Setter only used on foreign key relations, allows setting with #dbref"
if _GA(cls, "_is_deleted"):
raise ObjectDoesNotExist(
"Cannot set %s to %s: Hosting object was already deleted!"
% (fname, value)
"Cannot set %s to %s: Hosting object was already deleted!" % (fname, value)
)
if isinstance(value, (str, int)):
value = to_str(value)
@ -178,9 +169,7 @@ class SharedMemoryModelBase(ModelBase):
# only use explicit update_fields in save if we actually have a
# primary key assigned already (won't be set when first creating object)
update_fields = (
[fname]
if _GA(cls, "_get_pk_val")(_GA(cls, "_meta")) is not None
else None
[fname] if _GA(cls, "_get_pk_val")(_GA(cls, "_meta")) is not None else None
)
_GA(cls, "save")(update_fields=update_fields)
@ -192,9 +181,7 @@ class SharedMemoryModelBase(ModelBase):
"Wrapper for clearing database field - sets it to None"
_SA(cls, fname, None)
update_fields = (
[fname]
if _GA(cls, "_get_pk_val")(_GA(cls, "_meta")) is not None
else None
[fname] if _GA(cls, "_get_pk_val")(_GA(cls, "_meta")) is not None else None
)
_GA(cls, "save")(update_fields=update_fields)
@ -224,15 +211,11 @@ class SharedMemoryModelBase(ModelBase):
return _set(cls, fieldname, val)
def fdel(cls):
return (
_del(cls, fieldname) if editable else _del_nonedit(cls, fieldname)
)
return _del(cls, fieldname) if editable else _del_nonedit(cls, fieldname)
# set docstrings for auto-doc
fget.__doc__ = "A wrapper for getting database field `%s`." % fieldname
fset.__doc__ = (
"A wrapper for setting (and saving) database field `%s`." % fieldname
)
fset.__doc__ = "A wrapper for setting (and saving) database field `%s`." % fieldname
fdel.__doc__ = "A wrapper for deleting database field `%s`." % fieldname
# assigning
attrs[wrappername] = property(fget, fset, fdel)
@ -249,17 +232,11 @@ class SharedMemoryModelBase(ModelBase):
if fname.startswith("db_") and type(field).__name__ != "ManyToManyField"
):
foreignkey = type(field).__name__ == "ForeignKey"
wrappername = (
"dbid" if fieldname == "id" else fieldname.replace("db_", "", 1)
)
wrappername = "dbid" if fieldname == "id" else fieldname.replace("db_", "", 1)
if wrappername not in attrs:
# makes sure not to overload manually created wrappers on the model
create_wrapper(
cls,
fieldname,
wrappername,
editable=field.editable,
foreignkey=foreignkey,
cls, fieldname, wrappername, editable=field.editable, foreignkey=foreignkey
)
return super().__new__(cls, name, bases, attrs)
@ -450,9 +427,7 @@ class SharedMemoryModel(Model, metaclass=SharedMemoryModelBase):
"""
global _MONITOR_HANDLER
if not _MONITOR_HANDLER:
from evennia.scripts.monitorhandler import (
MONITOR_HANDLER as _MONITOR_HANDLER,
)
from evennia.scripts.monitorhandler import MONITOR_HANDLER as _MONITOR_HANDLER
if _IS_SUBPROCESS:
# we keep a store of objects modified in subprocesses so
@ -490,8 +465,7 @@ class SharedMemoryModel(Model, metaclass=SharedMemoryModelBase):
if "update_fields" in kwargs and kwargs["update_fields"]:
# get field objects from their names
update_fields = (
self._meta.get_field(fieldname)
for fieldname in kwargs.get("update_fields")
self._meta.get_field(fieldname) for fieldname in kwargs.get("update_fields")
)
else:
# meta.fields are already field objects; get them all
@ -645,8 +619,7 @@ def conditional_flush(max_rmem, force=False):
# too soon after last flush.
logger.log_warn(
"Warning: Idmapper flush called more than "
"once in %s min interval. Check memory usage."
% (AUTO_FLUSH_MIN_INTERVAL / 60.0)
"once in %s min interval. Check memory usage." % (AUTO_FLUSH_MIN_INTERVAL / 60.0)
)
return
@ -658,8 +631,7 @@ def conditional_flush(max_rmem, force=False):
Ncache_max = mem2cachesize(max_rmem)
Ncache, _ = cache_size()
actual_rmem = (
float(os.popen("ps -p %d -o %s | tail -1" % (os.getpid(), "rss")).read())
/ 1000.0
float(os.popen("ps -p %d -o %s | tail -1" % (os.getpid(), "rss")).read()) / 1000.0
) # resident memory
if Ncache >= Ncache_max and actual_rmem > max_rmem * 0.9:

View file

@ -235,9 +235,7 @@ except AttributeError:
# regex definitions
_RE_STARTTOKEN = re.compile(
r"(?<!\\)\$(\w+)\("
) # unescaped $funcname( (start of function call)
_RE_STARTTOKEN = re.compile(r"(?<!\\)\$(\w+)\(") # unescaped $funcname( (start of function call)
# note: this regex can be experimented with at https://regex101.com/r/kGR3vE/2
_RE_TOKEN = re.compile(
@ -313,9 +311,7 @@ class InlinefuncError(RuntimeError):
pass
def parse_inlinefunc(
string, strip=False, available_funcs=None, stacktrace=False, **kwargs
):
def parse_inlinefunc(string, strip=False, available_funcs=None, stacktrace=False, **kwargs):
"""
Parse the incoming string.
@ -368,9 +364,7 @@ def parse_inlinefunc(
gdict = match.groupdict()
if stacktrace:
out = " MATCH: {}".format(
{key: val for key, val in gdict.items() if val}
)
out = " MATCH: {}".format({key: val for key, val in gdict.items() if val})
print(out)
logger.log_info(out)
@ -535,14 +529,10 @@ def initialize_nick_templates(in_template, out_template):
regex_string = fnmatch.translate(in_template)
n_inargs = len(_RE_NICK_ARG.findall(regex_string))
regex_string = _RE_NICK_SPACE.sub("\s+", regex_string)
regex_string = _RE_NICK_ARG.sub(
lambda m: "(?P<arg%s>.+?)" % m.group(2), regex_string
)
regex_string = _RE_NICK_ARG.sub(lambda m: "(?P<arg%s>.+?)" % m.group(2), regex_string)
# create the out_template
template_string = _RE_NICK_TEMPLATE_ARG.sub(
lambda m: "{arg%s}" % m.group(2), out_template
)
template_string = _RE_NICK_TEMPLATE_ARG.sub(lambda m: "{arg%s}" % m.group(2), out_template)
# validate the tempaltes - they should at least have the same number of args
n_outargs = len(_RE_NICK_TEMPLATE_ARG.findall(out_template))

View file

@ -87,11 +87,7 @@ class WeeklyLogFile(logfile.DailyLogFile):
# all dates here are tuples (year, month, day)
now = self.toDate()
then = self.lastDate
return (
now[0] > then[0]
or now[1] > then[1]
or now[2] > (then[2] + self.day_rotation)
)
return now[0] > then[0] or now[1] > then[1] or now[2] > (then[2] + self.day_rotation)
def suffix(self, tupledate):
"""Return the suffix given a (year, month, day) tuple or unixtime.
@ -153,9 +149,7 @@ def log_msg(msg):
try:
log.msg(msg)
except Exception:
print(
"Exception raised while writing message to log. Original message: %s" % msg
)
print("Exception raised while writing message to log. Original message: %s" % msg)
def log_trace(errmsg=None):
@ -390,9 +384,7 @@ def _open_log_file(filename):
# return cached handle
return _LOG_FILE_HANDLES[filename]
try:
filehandle = EvenniaLogFile.fromFullPath(
filename, rotateLength=_LOG_ROTATE_SIZE
)
filehandle = EvenniaLogFile.fromFullPath(filename, rotateLength=_LOG_ROTATE_SIZE)
# filehandle = open(filename, "a+") # append mode + reading
_LOG_FILE_HANDLES[filename] = filehandle
_LOG_FILE_HANDLE_COUNTS[filename] = 0
@ -486,9 +478,9 @@ def tail_log_file(filename, offset, nlines, callback=None):
filehandle = _open_log_file(filename)
if filehandle:
if callback:
return deferToThread(
seek_file, filehandle, offset, nlines, callback
).addErrback(errback)
return deferToThread(seek_file, filehandle, offset, nlines, callback).addErrback(
errback
)
else:
return seek_file(filehandle, offset, nlines, callback)
else:

View file

@ -22,9 +22,7 @@ class BaseOption(object):
"""
def __str__(self):
return "<Option {key}: {value}>".format(
key=self.key, value=crop(str(self.value), width=10)
)
return "<Option {key}: {value}>".format(key=self.key, value=crop(str(self.value), width=10))
def __repr__(self):
return str(self)
@ -309,9 +307,7 @@ class Datetime(BaseOption):
def deserialize(self, save_data):
if isinstance(save_data, int):
return datetime.datetime.utcfromtimestamp(save_data)
raise ValueError(
f"{self.key} expected UTC Datetime in EPOCH format, got '{save_data}'"
)
raise ValueError(f"{self.key} expected UTC Datetime in EPOCH format, got '{save_data}'")
def serialize(self):
return int(self.value_storage.strftime("%s"))

View file

@ -151,15 +151,11 @@ class OptionHandler(object):
"""
if not key:
raise ValueError("Option field blank!")
match = string_partial_matching(
list(self.options_dict.keys()), key, ret_index=False
)
match = string_partial_matching(list(self.options_dict.keys()), key, ret_index=False)
if not match:
raise ValueError("Option not found!")
if len(match) > 1:
raise ValueError(
f"Multiple matches: {', '.join(match)}. Please be more specific."
)
raise ValueError(f"Multiple matches: {', '.join(match)}. Please be more specific.")
match = match[0]
op = self.get(match, return_obj=True)
op.set(value, **kwargs)

View file

@ -45,9 +45,7 @@ __all__ = (
# import objects this way to avoid circular import problems
ObjectDB = ContentType.objects.get(app_label="objects", model="objectdb").model_class()
AccountDB = ContentType.objects.get(
app_label="accounts", model="accountdb"
).model_class()
AccountDB = ContentType.objects.get(app_label="accounts", model="accountdb").model_class()
ScriptDB = ContentType.objects.get(app_label="scripts", model="scriptdb").model_class()
Msg = ContentType.objects.get(app_label="comms", model="msg").model_class()
Channel = ContentType.objects.get(app_label="comms", model="channeldb").model_class()

View file

@ -7,12 +7,7 @@ from twisted.internet.defer import Deferred
from django.conf import settings
from django.test import TestCase
from mock import Mock, patch
from evennia.objects.objects import (
DefaultObject,
DefaultCharacter,
DefaultRoom,
DefaultExit,
)
from evennia.objects.objects import DefaultObject, DefaultCharacter, DefaultRoom, DefaultExit
from evennia.accounts.accounts import DefaultAccount
from evennia.scripts.scripts import DefaultScript
from evennia.server.serversession import ServerSession

View file

@ -37,8 +37,7 @@ class TestBatchCommandProcessor(TestCase):
)
commands = batchprocessors.BATCHCMD.parse_file("foopath")
self.assertEqual(
["@create rock", "@set rock/desc =\nA big rock. You can tell is ancient."],
commands,
["@create rock", "@set rock/desc =\nA big rock. You can tell is ancient."], commands
)
@mock.patch.object(batchprocessors, "read_batchfile")
@ -64,15 +63,10 @@ class TestBatchCommandProcessor(TestCase):
),
]
commands = batchprocessors.BATCHCMD.parse_file("foopath")
self.assertEqual(
commands, ["@create sky", "@create bird", "@create cloud", "@create sun"]
)
self.assertEqual(commands, ["@create sky", "@create bird", "@create cloud", "@create sun"])
self.assertEqual(
mocked_read.mock_calls,
[
mock.call("foopath", file_ending=".ev"),
mock.call("another.ev", file_ending=".ev"),
],
[mock.call("foopath", file_ending=".ev"), mock.call("another.ev", file_ending=".ev")],
)
@mock.patch.object(batchprocessors, "read_batchfile")
@ -94,10 +88,7 @@ class TestBatchCommandProcessor(TestCase):
batchprocessors.BATCHCMD.parse_file("foopath")
self.assertEqual(
mocked_read.mock_calls,
[
mock.call("foopath", file_ending=".ev"),
mock.call("x", file_ending=".ev"),
],
[mock.call("foopath", file_ending=".ev"), mock.call("x", file_ending=".ev")],
)
@ -187,10 +178,7 @@ class TestBatchCodeProcessor(TestCase):
)
self.assertEqual(
mocked_read.mock_calls,
[
mock.call("foopath", file_ending=".py"),
mock.call("another.py", file_ending=".py"),
],
[mock.call("foopath", file_ending=".py"), mock.call("another.py", file_ending=".py")],
)
@mock.patch.object(batchprocessors, "read_batchfile")
@ -207,10 +195,7 @@ class TestBatchCodeProcessor(TestCase):
batchprocessors.BATCHCODE.parse_file("foopath")
self.assertEqual(
mocked_read.mock_calls,
[
mock.call("foopath", file_ending=".py"),
mock.call("x", file_ending=".py"),
],
[mock.call("foopath", file_ending=".py"), mock.call("x", file_ending=".py")],
)
@mock.patch("builtins.exec")
@ -223,8 +208,7 @@ class TestBatchCodeProcessor(TestCase):
@mock.patch("builtins.exec")
def test_execs_codeblock_with_extra_environ(self, mocked_exec):
err = batchprocessors.BATCHCODE.code_exec(
'# batchcode code:\n\nprint("Hello")\n',
extra_environ={"foo": "bar", "baz": True},
'# batchcode code:\n\nprint("Hello")\n', extra_environ={"foo": "bar", "baz": True}
)
self.assertIsNone(err)

View file

@ -38,9 +38,7 @@ class TestEvEditor(CommandTest):
raw_string="Second test line",
msg="02Second test line",
)
self.assertEqual(
self.char1.ndb._eveditor.get_buffer(), "First test line\nSecond test line"
)
self.assertEqual(self.char1.ndb._eveditor.get_buffer(), "First test line\nSecond test line")
self.call(
eveditor.CmdEditorGroup(),
@ -71,33 +69,18 @@ class TestEvEditor(CommandTest):
)
self.call(
eveditor.CmdEditorGroup(),
"",
cmdstring=":dd",
msg="Deleted line 3.", # delete line
eveditor.CmdEditorGroup(), "", cmdstring=":dd", msg="Deleted line 3." # delete line
)
self.assertEqual(self.char1.ndb._eveditor.get_buffer(), "First test line\nSecond test line")
self.call(eveditor.CmdEditorGroup(), "", cmdstring=":u", msg="Undid one step.") # undo
self.assertEqual(
self.char1.ndb._eveditor.get_buffer(), "First test line\nSecond test line"
self.char1.ndb._eveditor.get_buffer(), "First test line\nSecond test line\n:"
)
self.call(
eveditor.CmdEditorGroup(), "", cmdstring=":u", msg="Undid one step."
) # undo
self.call(eveditor.CmdEditorGroup(), "", cmdstring=":uu", msg="Redid one step.") # redo
self.assertEqual(self.char1.ndb._eveditor.get_buffer(), "First test line\nSecond test line")
self.call(eveditor.CmdEditorGroup(), "", cmdstring=":u", msg="Undid one step.") # undo
self.assertEqual(
self.char1.ndb._eveditor.get_buffer(),
"First test line\nSecond test line\n:",
)
self.call(
eveditor.CmdEditorGroup(), "", cmdstring=":uu", msg="Redid one step."
) # redo
self.assertEqual(
self.char1.ndb._eveditor.get_buffer(), "First test line\nSecond test line"
)
self.call(
eveditor.CmdEditorGroup(), "", cmdstring=":u", msg="Undid one step."
) # undo
self.assertEqual(
self.char1.ndb._eveditor.get_buffer(),
"First test line\nSecond test line\n:",
self.char1.ndb._eveditor.get_buffer(), "First test line\nSecond test line\n:"
)
self.call(
eveditor.CmdEditorGroup(),
@ -113,24 +96,17 @@ class TestEvEditor(CommandTest):
cmdstring=":dw", # delete by word
msg="Removed Second for lines 1-4.",
)
self.call(
eveditor.CmdEditorGroup(), "", cmdstring=":u", msg="Undid one step."
) # undo
self.call(eveditor.CmdEditorGroup(), "", cmdstring=":u", msg="Undid one step.") # undo
self.call(
eveditor.CmdEditorGroup(),
"2 Second",
cmdstring=":dw", # delete by word/line
msg="Removed Second for line 2.",
)
self.assertEqual(
self.char1.ndb._eveditor.get_buffer(), "First test line\n test line\n:"
)
self.assertEqual(self.char1.ndb._eveditor.get_buffer(), "First test line\n test line\n:")
self.call(
eveditor.CmdEditorGroup(),
"2",
cmdstring=":p",
msg="Copy buffer is empty.", # paste
eveditor.CmdEditorGroup(), "2", cmdstring=":p", msg="Copy buffer is empty." # paste
)
self.call(
eveditor.CmdEditorGroup(),
@ -145,15 +121,11 @@ class TestEvEditor(CommandTest):
msg="Pasted buffer [' test line'] to line 2.",
)
self.assertEqual(
self.char1.ndb._eveditor.get_buffer(),
"First test line\n test line\n test line\n:",
self.char1.ndb._eveditor.get_buffer(), "First test line\n test line\n test line\n:"
)
self.call(
eveditor.CmdEditorGroup(),
"3",
cmdstring=":x",
msg="Line 3, [' test line'] cut.", # cut
eveditor.CmdEditorGroup(), "3", cmdstring=":x", msg="Line 3, [' test line'] cut." # cut
)
self.call(
@ -207,8 +179,7 @@ class TestEvEditor(CommandTest):
msg="02Second 'line' .",
)
self.assertEqual(
self.char1.ndb._eveditor.get_buffer(),
"First test \"line\".\nSecond 'line'.",
self.char1.ndb._eveditor.get_buffer(), "First test \"line\".\nSecond 'line'."
)
self.call(
eveditor.CmdEditorGroup(),
@ -226,15 +197,9 @@ class TestEvEditor(CommandTest):
cmdstring=":",
msg="Line Editor []\n01\n[l:01 w:000 c:0000](:h for help)",
)
self.call(
eveditor.CmdLineInput(), "line 1.", raw_string="line 1.", msg="01line 1."
)
self.call(
eveditor.CmdLineInput(), "line 2.", raw_string="line 2.", msg="02line 2."
)
self.call(
eveditor.CmdLineInput(), "line 3.", raw_string="line 3.", msg="03line 3."
)
self.call(eveditor.CmdLineInput(), "line 1.", raw_string="line 1.", msg="01line 1.")
self.call(eveditor.CmdLineInput(), "line 2.", raw_string="line 2.", msg="02line 2.")
self.call(eveditor.CmdLineInput(), "line 3.", raw_string="line 3.", msg="03line 3.")
self.call(
eveditor.CmdEditorGroup(),
"2:3",
@ -247,18 +212,14 @@ class TestEvEditor(CommandTest):
cmdstring=":s",
msg="Search-replaced line -> LINE for lines 1-2.",
)
self.assertEqual(
self.char1.ndb._eveditor.get_buffer(), "LINE 1.\nLINE 2.\nline 3."
)
self.assertEqual(self.char1.ndb._eveditor.get_buffer(), "LINE 1.\nLINE 2.\nline 3.")
self.call(
eveditor.CmdEditorGroup(),
"line MINE",
cmdstring=":s",
msg="Search-replaced line -> MINE for lines 1-3.",
)
self.assertEqual(
self.char1.ndb._eveditor.get_buffer(), "LINE 1.\nLINE 2.\nMINE 3."
)
self.assertEqual(self.char1.ndb._eveditor.get_buffer(), "LINE 1.\nLINE 2.\nMINE 3.")
def test_eveditor_COLON_DD(self):
eveditor.EvEditor(self.char1)
@ -268,20 +229,11 @@ class TestEvEditor(CommandTest):
cmdstring=":",
msg="Line Editor []\n01\n[l:01 w:000 c:0000](:h for help)",
)
self.call(eveditor.CmdLineInput(), "line 1.", raw_string="line 1.", msg="01line 1.")
self.call(eveditor.CmdLineInput(), "line 2.", raw_string="line 2.", msg="02line 2.")
self.call(eveditor.CmdLineInput(), "line 3.", raw_string="line 3.", msg="03line 3.")
self.call(
eveditor.CmdLineInput(), "line 1.", raw_string="line 1.", msg="01line 1."
)
self.call(
eveditor.CmdLineInput(), "line 2.", raw_string="line 2.", msg="02line 2."
)
self.call(
eveditor.CmdLineInput(), "line 3.", raw_string="line 3.", msg="03line 3."
)
self.call(
eveditor.CmdEditorGroup(),
"",
cmdstring=":DD",
msg="Cleared 3 lines from buffer.",
eveditor.CmdEditorGroup(), "", cmdstring=":DD", msg="Cleared 3 lines from buffer."
)
self.assertEqual(self.char1.ndb._eveditor.get_buffer(), "")
@ -293,15 +245,8 @@ class TestEvEditor(CommandTest):
cmdstring=":",
msg="Line Editor []\n01\n[l:01 w:000 c:0000](:h for help)",
)
self.call(
eveditor.CmdLineInput(), "line 1", raw_string="line 1", msg="01line 1"
)
self.call(
eveditor.CmdEditorGroup(),
"1:2",
cmdstring=":f",
msg="Flood filled lines 1-2.",
)
self.call(eveditor.CmdLineInput(), "line 1", raw_string="line 1", msg="01line 1")
self.call(eveditor.CmdEditorGroup(), "1:2", cmdstring=":f", msg="Flood filled lines 1-2.")
self.assertEqual(self.char1.ndb._eveditor.get_buffer(), "line 1")
def test_eveditor_COLON_J(self):
@ -312,30 +257,13 @@ class TestEvEditor(CommandTest):
cmdstring=":",
msg="Line Editor []\n01\n[l:01 w:000 c:0000](:h for help)",
)
self.call(
eveditor.CmdLineInput(), "line 1", raw_string="line 1", msg="01line 1"
)
self.call(eveditor.CmdLineInput(), "line 1", raw_string="line 1", msg="01line 1")
self.call(eveditor.CmdLineInput(), "l 2", raw_string="l 2", msg="02l 2")
self.call(eveditor.CmdLineInput(), "l 3", raw_string="l 3", msg="03l 3")
self.call(eveditor.CmdLineInput(), "l 4", raw_string="l 4", msg="04l 4")
self.call(
eveditor.CmdEditorGroup(),
"2 r",
cmdstring=":j",
msg="Right-justified line 2.",
)
self.call(
eveditor.CmdEditorGroup(),
"3 c",
cmdstring=":j",
msg="Center-justified line 3.",
)
self.call(
eveditor.CmdEditorGroup(),
"4 f",
cmdstring=":j",
msg="Full-justified line 4.",
)
self.call(eveditor.CmdEditorGroup(), "2 r", cmdstring=":j", msg="Right-justified line 2.")
self.call(eveditor.CmdEditorGroup(), "3 c", cmdstring=":j", msg="Center-justified line 3.")
self.call(eveditor.CmdEditorGroup(), "4 f", cmdstring=":j", msg="Full-justified line 4.")
l1, l2, l3, l4 = tuple(self.char1.ndb._eveditor.get_buffer().split("\n"))
self.assertEqual(l1, "line 1")
self.assertEqual(l2, " " * 75 + "l 2")
@ -350,9 +278,7 @@ class TestEvEditor(CommandTest):
cmdstring=":",
msg="Line Editor []\n01\n[l:01 w:000 c:0000](:h for help)",
)
self.call(
eveditor.CmdLineInput(), "line 1.", raw_string="line 1.", msg="01line 1."
)
self.call(eveditor.CmdLineInput(), "line 1.", raw_string="line 1.", msg="01line 1.")
self.call(
eveditor.CmdEditorGroup(),
"",

View file

@ -81,9 +81,7 @@ class TestEvMenu(TestCase):
node_text = menu.test_nodetext
self.assertIsNotNone(
bool(node_text),
"node: {}: node-text is None, which was not expected.".format(
nodename
),
"node: {}: node-text is None, which was not expected.".format(nodename),
)
if isinstance(node_text, tuple):
node_text, helptext = node_text
@ -99,9 +97,7 @@ class TestEvMenu(TestCase):
self.assertEqual(
len(options),
compare_options_count,
"Not the right number of options returned from node {}.".format(
nodename
),
"Not the right number of options returned from node {}.".format(nodename),
)
compare_options = self.expected_node_options.get(nodename, None)
if compare_options:
@ -147,9 +143,7 @@ class TestEvMenu(TestCase):
if menu.close_menu.called:
# this was an end node
self._debug_output(
indent, " .. menu exited! Back to previous node."
)
self._debug_output(indent, " .. menu exited! Back to previous node.")
menu = backup_menu
menu.close_menu = MagicMock()
visited.append(nodename)
@ -162,9 +156,7 @@ class TestEvMenu(TestCase):
else:
subtree.append(nodename)
# self._debug_output( indent, " -> arrived at {} (circular call)".format(nodename))
self._debug_output(
indent, "-- {} ({}) -> {}".format(key, desc, goto)
)
self._debug_output(indent, "-- {} ({}) -> {}".format(key, desc, goto))
if subtree:
tree.append(subtree)

View file

@ -32,27 +32,7 @@ class ANSIStringTestCase(TestCase):
clean = "This isA|r testTest"
encoded = "\x1b[1m\x1b[32mThis is\x1b[1m\x1b[31mA|r test\x1b[0mTest\x1b[0m"
target = ANSIString(r"|gThis is|rA||r test|nTest|n")
char_table = [
9,
10,
11,
12,
13,
14,
15,
25,
26,
27,
28,
29,
30,
31,
32,
37,
38,
39,
40,
]
char_table = [9, 10, 11, 12, 13, 14, 15, 25, 26, 27, 28, 29, 30, 31, 32, 37, 38, 39, 40]
code_table = [
0,
1,
@ -102,9 +82,7 @@ class ANSIStringTestCase(TestCase):
result = target[:4]
self.checker(result, "\x1b[1m\x1b[32mTest\x1b[1m\x1b[31m", "Test")
result = target[:]
self.checker(
result, "\x1b[1m\x1b[32mTest\x1b[1m\x1b[31mTest\x1b[0m", "TestTest"
)
self.checker(result, "\x1b[1m\x1b[32mTest\x1b[1m\x1b[31mTest\x1b[0m", "TestTest")
result = target[:-1]
self.checker(result, "\x1b[1m\x1b[32mTest\x1b[1m\x1b[31mTes", "TestTes")
result = target[0:0]
@ -185,30 +163,7 @@ class ANSIStringTestCase(TestCase):
result = "\x1b[1m\x1b[32mTest\x1b[1m\x1b[36mString\x1b[0m"
self.checker(c, result, "TestString")
char_table = [9, 10, 11, 12, 22, 23, 24, 25, 26, 27]
code_table = [
0,
1,
2,
3,
4,
5,
6,
7,
8,
13,
14,
15,
16,
17,
18,
19,
20,
21,
28,
29,
30,
31,
]
code_table = [0, 1, 2, 3, 4, 5, 6, 7, 8, 13, 14, 15, 16, 17, 18, 19, 20, 21, 28, 29, 30, 31]
self.table_check(c, char_table, code_table)
def test_strip(self):
@ -218,12 +173,8 @@ class ANSIStringTestCase(TestCase):
a = ANSIString(" |r Test of stuff |b with spaces |n ")
b = ANSIString("|r|b")
self.assertEqual(a.strip(), ANSIString("|rTest of stuff |b with spaces|n"))
self.assertEqual(
a.lstrip(), ANSIString("|rTest of stuff |b with spaces |n ")
)
self.assertEqual(
a.rstrip(), ANSIString(" |r Test of stuff |b with spaces|n")
)
self.assertEqual(a.lstrip(), ANSIString("|rTest of stuff |b with spaces |n "))
self.assertEqual(a.rstrip(), ANSIString(" |r Test of stuff |b with spaces|n"))
self.assertEqual(b.strip(), b)
@ -279,9 +230,7 @@ class TestTextToHTMLparser(TestCase):
def test_url_chars_querystring(self):
self.assertEqual(
self.parser.convert_urls(
"https://example.com/submitform?field1=val1+val3&field2=val2"
),
self.parser.convert_urls("https://example.com/submitform?field1=val1+val3&field2=val2"),
'<a href="https://example.com/submitform?field1=val1+val3&field2=val2" target="_blank">'
"https://example.com/submitform?field1=val1+val3&field2=val2</a>",
)
@ -296,8 +245,7 @@ class TestTextToHTMLparser(TestCase):
def test_url_chars_exclam(self):
self.assertEqual(
self.parser.convert_urls(
"https://groups.google.com/forum/"
"?fromgroups#!categories/evennia/ainneve"
"https://groups.google.com/forum/" "?fromgroups#!categories/evennia/ainneve"
),
'<a href="https://groups.google.com/forum/?fromgroups#!categories/evennia/ainneve"'
' target="_blank">https://groups.google.com/forum/?fromgroups#!categories/evennia/ainneve</a>',
@ -365,9 +313,7 @@ class TestInlineFuncs(TestCase):
def test_single_func(self):
self.assertEqual(
inlinefuncs.parse_inlinefunc(
"this is a test with $pad(centered, 20) text in it."
),
inlinefuncs.parse_inlinefunc("this is a test with $pad(centered, 20) text in it."),
"this is a test with centered text in it.",
)

View file

@ -12,9 +12,7 @@ class TestText2Html(TestCase):
self.assertEqual("foo", parser.re_color("foo"))
self.assertEqual(
'<span class="color-001">red</span>foo',
parser.re_color(
ansi.ANSI_UNHILITE + ansi.ANSI_RED + "red" + ansi.ANSI_NORMAL + "foo"
),
parser.re_color(ansi.ANSI_UNHILITE + ansi.ANSI_RED + "red" + ansi.ANSI_NORMAL + "foo"),
)
self.assertEqual(
'<span class="bgcolor-001">red</span>foo',
@ -39,9 +37,7 @@ class TestText2Html(TestCase):
self.assertEqual(
# "a <strong>red</strong>foo", # TODO: why not?
"a <strong>redfoo</strong>",
parser.re_bold(
"a " + ansi.ANSI_HILITE + "red" + ansi.ANSI_UNHILITE + "foo"
),
parser.re_bold("a " + ansi.ANSI_HILITE + "red" + ansi.ANSI_UNHILITE + "foo"),
)
@unittest.skip("parser issues")
@ -149,11 +145,7 @@ class TestText2Html(TestCase):
self.assertEqual("foo", parser.sub_text(mocked_match))
mocked_match.groupdict.return_value = {"htmlchars": "", "lineend": "foo"}
self.assertEqual("<br>", parser.sub_text(mocked_match))
mocked_match.groupdict.return_value = {
"htmlchars": "",
"lineend": "",
"firstspace": "foo",
}
mocked_match.groupdict.return_value = {"htmlchars": "", "lineend": "", "firstspace": "foo"}
self.assertEqual(" &nbsp;", parser.sub_text(mocked_match))
parser.tabstop = 2
mocked_match.groupdict.return_value = {

View file

@ -26,9 +26,7 @@ class TestCrop(TestCase):
# No text, return no text
self.assertEqual("", utils.crop("", width=10, suffix="[...]"))
# Input length equal to max width, no crop
self.assertEqual(
"0123456789", utils.crop("0123456789", width=10, suffix="[...]")
)
self.assertEqual("0123456789", utils.crop("0123456789", width=10, suffix="[...]"))
# Input length greater than max width, crop (suffix included in width)
self.assertEqual("0123[...]", utils.crop("0123456789", width=9, suffix="[...]"))
# Input length less than desired width, no crop
@ -68,13 +66,10 @@ class TestListToString(TestCase):
def test_list_to_string(self):
self.assertEqual("1, 2, 3", utils.list_to_string([1, 2, 3], endsep=""))
self.assertEqual(
'"1", "2", "3"', utils.list_to_string([1, 2, 3], endsep="", addquote=True)
)
self.assertEqual('"1", "2", "3"', utils.list_to_string([1, 2, 3], endsep="", addquote=True))
self.assertEqual("1, 2 and 3", utils.list_to_string([1, 2, 3]))
self.assertEqual(
'"1", "2" and "3"',
utils.list_to_string([1, 2, 3], endsep="and", addquote=True),
'"1", "2" and "3"', utils.list_to_string([1, 2, 3], endsep="and", addquote=True)
)
@ -162,15 +157,9 @@ class TestTimeformat(TestCase):
self.assertEqual(utils.time_format(3600, 3), "1 hour, 0 minutes")
self.assertEqual(utils.time_format(3725, 3), "1 hour, 2 minutes 5 seconds")
self.assertEqual(utils.time_format(86350, 3), "23 hours, 59 minutes 10 seconds")
self.assertEqual(
utils.time_format(86800, 3), "1 day, 0 hours, 6 minutes 40 seconds"
)
self.assertEqual(
utils.time_format(130800, 3), "1 day, 12 hours, 20 minutes 0 seconds"
)
self.assertEqual(
utils.time_format(530800, 3), "6 days, 3 hours, 26 minutes 40 seconds"
)
self.assertEqual(utils.time_format(86800, 3), "1 day, 0 hours, 6 minutes 40 seconds")
self.assertEqual(utils.time_format(130800, 3), "1 day, 12 hours, 20 minutes 0 seconds")
self.assertEqual(utils.time_format(530800, 3), "6 days, 3 hours, 26 minutes 40 seconds")
def test_style_4(self):
"""Test the style 4 of time_format."""

View file

@ -30,9 +30,7 @@ class TestValidatorFuncs(TestCase):
def test_datetime_ok(self):
for dt in ["Oct 12 1:00 1492", "Jan 2 12:00 2020", "Dec 31 00:00 2018"]:
self.assertTrue(
isinstance(
validatorfuncs.datetime(dt, from_tz=pytz.UTC), datetime.datetime
)
isinstance(validatorfuncs.datetime(dt, from_tz=pytz.UTC), datetime.datetime)
)
def test_datetime_raises_ValueError(self):
@ -50,9 +48,7 @@ class TestValidatorFuncs(TestCase):
)
# values may be duplicated
self.assertEqual(
datetime.timedelta(
(1 + 7) + (6 + 12) * 365, 2 + 8, 0, 0, 3 + 9, 4 + 10, 5 + 11
),
datetime.timedelta((1 + 7) + (6 + 12) * 365, 2 + 8, 0, 0, 3 + 9, 4 + 10, 5 + 11),
validatorfuncs.duration("1d 2s 3m 4h 5w 6y 7d 8s 9m 10h 11w 12y"),
)
@ -65,9 +61,7 @@ class TestValidatorFuncs(TestCase):
year = int(datetime.datetime.utcnow().strftime("%Y"))
for f in [f"Jan 2 12:00 {year+1}", f"Dec 31 00:00 {year+1}"]:
self.assertTrue(
isinstance(
validatorfuncs.future(f, from_tz=pytz.UTC), datetime.datetime
)
isinstance(validatorfuncs.future(f, from_tz=pytz.UTC), datetime.datetime)
)
def test_future_raises_ValueError(self):

View file

@ -68,9 +68,7 @@ class TextToHTMLparser(object):
("bgcolor-013", hilite + ANSI_BACK_MAGENTA),
("bgcolor-014", hilite + ANSI_BACK_CYAN),
("bgcolor-015", hilite + ANSI_BACK_WHITE), # pure white
] + [
("bgcolor-%03i" % (i + 16), XTERM256_BG % ("%i" % (i + 16))) for i in range(240)
]
] + [("bgcolor-%03i" % (i + 16), XTERM256_BG % ("%i" % (i + 16))) for i in range(240)]
# make sure to escape [
# colorcodes = [(c, code.replace("[", r"\[")) for c, code in colorcodes]
@ -85,9 +83,7 @@ class TextToHTMLparser(object):
fgstart = "((?:\033\[1m|\033\[22m){0,1}\033\[3[0-8].*?m)"
bgstart = "((?:\033\[1m|\033\[22m){0,1}\033\[4[0-8].*?m)"
bgfgstart = (
bgstart + r"(\s*)" + "((?:\033\[1m|\033\[22m){0,1}\033\[[3-4][0-8].*?m){0,1}"
)
bgfgstart = bgstart + r"(\s*)" + "((?:\033\[1m|\033\[22m){0,1}\033\[[3-4][0-8].*?m){0,1}"
# extract color markers, tagging the start marker and the text marked
re_fgs = re.compile(fgstart + "(.*?)(?=" + fgstop + ")")
@ -95,21 +91,11 @@ class TextToHTMLparser(object):
re_bgfg = re.compile(bgfgstart + "(.*?)(?=" + bgfgstop + ")")
re_normal = re.compile(normal.replace("[", r"\["))
re_hilite = re.compile(
"(?:%s)(.*)(?=%s|%s)" % (hilite.replace("[", r"\["), fgstop, bgstop)
)
re_unhilite = re.compile(
"(?:%s)(.*)(?=%s|%s)" % (unhilite.replace("[", r"\["), fgstop, bgstop)
)
re_uline = re.compile(
"(?:%s)(.*?)(?=%s|%s)" % (underline.replace("[", r"\["), fgstop, bgstop)
)
re_blink = re.compile(
"(?:%s)(.*?)(?=%s|%s)" % (blink.replace("[", r"\["), fgstop, bgstop)
)
re_inverse = re.compile(
"(?:%s)(.*?)(?=%s|%s)" % (inverse.replace("[", r"\["), fgstop, bgstop)
)
re_hilite = re.compile("(?:%s)(.*)(?=%s|%s)" % (hilite.replace("[", r"\["), fgstop, bgstop))
re_unhilite = re.compile("(?:%s)(.*)(?=%s|%s)" % (unhilite.replace("[", r"\["), fgstop, bgstop))
re_uline = re.compile("(?:%s)(.*?)(?=%s|%s)" % (underline.replace("[", r"\["), fgstop, bgstop))
re_blink = re.compile("(?:%s)(.*?)(?=%s|%s)" % (blink.replace("[", r"\["), fgstop, bgstop))
re_inverse = re.compile("(?:%s)(.*?)(?=%s|%s)" % (inverse.replace("[", r"\["), fgstop, bgstop))
re_string = re.compile(
r"(?P<htmlchars>[<&>])|(?P<firstspace>(?<=\S) )|(?P<space> [ \t]+)|"
r"(?P<spacestart>^ )|(?P<lineend>\r\n|\r|\n)",
@ -143,17 +129,11 @@ class TextToHTMLparser(object):
def _sub_fg(self, colormatch):
code, text = colormatch.groups()
return r"""<span class="%s">%s</span>""" % (
self.fg_colormap.get(code, "err"),
text,
)
return r"""<span class="%s">%s</span>""" % (self.fg_colormap.get(code, "err"), text)
def _sub_bg(self, colormatch):
code, text = colormatch.groups()
return r"""<span class="%s">%s</span>""" % (
self.bg_colormap.get(code, "err"),
text,
)
return r"""<span class="%s">%s</span>""" % (self.bg_colormap.get(code, "err"), text)
def re_color(self, text):
"""
@ -186,9 +166,7 @@ class TextToHTMLparser(object):
"""
text = self.re_hilite.sub(r"<strong>\1</strong>", text)
return self.re_unhilite.sub(
r"\1", text
) # strip unhilite - there is no equivalent in css.
return self.re_unhilite.sub(r"\1", text) # strip unhilite - there is no equivalent in css.
def re_underline(self, text):
"""

View file

@ -97,9 +97,7 @@ def wrap(text, width=None, indent=0):
if not text:
return ""
indent = " " * indent
return to_str(
textwrap.fill(text, width, initial_indent=indent, subsequent_indent=indent)
)
return to_str(textwrap.fill(text, width, initial_indent=indent, subsequent_indent=indent))
# alias - fill
@ -156,11 +154,7 @@ def crop(text, width=None, suffix="[...]"):
return text
else:
lsuffix = len(suffix)
text = (
text[:width]
if lsuffix >= width
else "%s%s" % (text[: width - lsuffix], suffix)
)
text = text[:width] if lsuffix >= width else "%s%s" % (text[: width - lsuffix], suffix)
return to_str(text)
@ -193,8 +187,7 @@ def dedent(text, baseline_index=None):
baseline = lines[baseline_index]
spaceremove = len(baseline) - len(baseline.lstrip(" "))
return "\n".join(
line[min(spaceremove, len(line) - len(line.lstrip(" "))) :]
for line in lines
line[min(spaceremove, len(line) - len(line.lstrip(" "))) :] for line in lines
)
@ -230,9 +223,7 @@ def justify(text, width=None, align="f", indent=0):
if line_rest > 0:
if align == "l":
if line[-1] == "\n\n":
line[-1] = (
" " * (line_rest - 1) + "\n" + " " * width + "\n" + " " * width
)
line[-1] = " " * (line_rest - 1) + "\n" + " " * width + "\n" + " " * width
else:
line[-1] += " " * line_rest
elif align == "r":
@ -242,12 +233,7 @@ def justify(text, width=None, align="f", indent=0):
line[0] = pad + line[0]
if line[-1] == "\n\n":
line[-1] += (
pad
+ " " * (line_rest % 2 - 1)
+ "\n"
+ " " * width
+ "\n"
+ " " * width
pad + " " * (line_rest % 2 - 1) + "\n" + " " * width + "\n" + " " * width
)
else:
line[-1] = line[-1] + pad + " " * (line_rest % 2)
@ -391,10 +377,7 @@ def list_to_string(inlist, endsep="and", addquote=False):
if addquote:
if len(inlist) == 1:
return '"%s"' % inlist[0]
return ", ".join('"%s"' % v for v in inlist[:-1]) + "%s %s" % (
endsep,
'"%s"' % inlist[-1],
)
return ", ".join('"%s"' % v for v in inlist[:-1]) + "%s %s" % (endsep, '"%s"' % inlist[-1])
else:
if len(inlist) == 1:
return str(inlist[0])
@ -718,11 +701,7 @@ def dbref(inp, reqhash=True):
if reqhash:
num = (
int(inp.lstrip("#"))
if (
isinstance(inp, str)
and inp.startswith("#")
and inp.lstrip("#").isdigit()
)
if (isinstance(inp, str) and inp.startswith("#") and inp.lstrip("#").isdigit())
else None
)
return num if isinstance(num, int) and num > 0 else None
@ -873,9 +852,7 @@ def to_bytes(text, session=None):
except Exception:
text = repr(text)
default_encoding = (
session.protocol_flags.get("ENCODING", "utf-8") if session else "utf-8"
)
default_encoding = session.protocol_flags.get("ENCODING", "utf-8") if session else "utf-8"
try:
return text.encode(default_encoding)
except (LookupError, UnicodeEncodeError):
@ -914,9 +891,7 @@ def to_str(text, session=None):
except Exception:
return repr(text)
default_encoding = (
session.protocol_flags.get("ENCODING", "utf-8") if session else "utf-8"
)
default_encoding = session.protocol_flags.get("ENCODING", "utf-8") if session else "utf-8"
try:
return text.decode(default_encoding)
except (LookupError, UnicodeDecodeError):
@ -1021,9 +996,7 @@ def inherits_from(obj, parent):
# this is a class
obj_paths = ["%s.%s" % (mod.__module__, mod.__name__) for mod in obj.mro()]
else:
obj_paths = [
"%s.%s" % (mod.__module__, mod.__name__) for mod in obj.__class__.mro()
]
obj_paths = ["%s.%s" % (mod.__module__, mod.__name__) for mod in obj.__class__.mro()]
if isinstance(parent, str):
# a given string path, for direct matching
@ -1120,9 +1093,7 @@ def delay(timedelay, callback, *args, **kwargs):
_PPOOL = None
_PCMD = None
_PROC_ERR = (
"A process has ended with a probable error condition: process ended by signal 9."
)
_PROC_ERR = "A process has ended with a probable error condition: process ended by signal 9."
def run_async(to_execute, *args, **kwargs):
@ -1272,9 +1243,7 @@ def mod_import_from_path(path):
try:
return importlib.machinery.SourceFileLoader(modname, path).load_module()
except OSError:
logger.log_trace(
f"Could not find module '{modname}' ({modname}.py) at path '{dirpath}'"
)
logger.log_trace(f"Could not find module '{modname}' ({modname}.py) at path '{dirpath}'")
return None
@ -1355,9 +1324,7 @@ def callables_from_module(module):
if not mod:
return {}
# make sure to only return callables actually defined in this module (not imports)
members = getmembers(
mod, predicate=lambda obj: callable(obj) and getmodule(obj) == mod
)
members = getmembers(mod, predicate=lambda obj: callable(obj) and getmodule(obj) == mod)
return dict((key, val) for key, val in members if not key.startswith("_"))
@ -1397,9 +1364,7 @@ def variable_from_module(module, variable=None, default=None):
else:
# get all
result = [
val
for key, val in mod.__dict__.items()
if not (key.startswith("_") or ismodule(val))
val for key, val in mod.__dict__.items() if not (key.startswith("_") or ismodule(val))
]
if len(result) == 1:
@ -1513,9 +1478,7 @@ def class_from_module(path, defaultpaths=None):
if "." in path:
testpath, clsname = testpath.rsplit(".", 1)
else:
raise ImportError(
"the path '%s' is not on the form modulepath.Classname." % path
)
raise ImportError("the path '%s' is not on the form modulepath.Classname." % path)
try:
if not importlib.util.find_spec(testpath, package="evennia"):
@ -1559,9 +1522,7 @@ def init_new_account(account):
"""
from evennia.utils import logger
logger.log_dep(
"evennia.utils.utils.init_new_account is DEPRECATED and should not be used."
)
logger.log_dep("evennia.utils.utils.init_new_account is DEPRECATED and should not be used.")
def string_similarity(string1, string2):
@ -1586,8 +1547,7 @@ def string_similarity(string1, string2):
vec2 = [string2.count(v) for v in vocabulary]
try:
return float(sum(vec1[i] * vec2[i] for i in range(len(vocabulary)))) / (
math.sqrt(sum(v1 ** 2 for v1 in vec1))
* math.sqrt(sum(v2 ** 2 for v2 in vec2))
math.sqrt(sum(v1 ** 2 for v1 in vec1)) * math.sqrt(sum(v2 ** 2 for v2 in vec2))
)
except ZeroDivisionError:
# can happen if empty-string cmdnames appear for some reason.
@ -1960,11 +1920,7 @@ def at_search_result(matches, caller, query="", quiet=False, **kwargs):
for num, result in enumerate(matches):
# we need to consider Commands, where .aliases is a list
aliases = (
result.aliases.all()
if hasattr(result.aliases, "all")
else result.aliases
)
aliases = result.aliases.all() if hasattr(result.aliases, "all") else result.aliases
error += _MULTIMATCH_TEMPLATE.format(
number=num + 1,
name=result.get_display_name(caller)
@ -2055,9 +2011,7 @@ def get_game_dir_path():
return gpath
else:
os.chdir(os.pardir)
raise RuntimeError(
"server/conf/settings.py not found: Must start from inside game dir."
)
raise RuntimeError("server/conf/settings.py not found: Must start from inside game dir.")
def get_all_typeclasses(parent=None):
@ -2142,9 +2096,7 @@ def interactive(func):
)
get_input(caller, value, _process_input, generator=generator)
else:
raise ValueError(
"yield(val) in a @pausable method must have an int/float as arg."
)
raise ValueError("yield(val) in a @pausable method must have an int/float as arg.")
def decorator(*args, **kwargs):
argnames = inspect.getfullargspec(func).args

View file

@ -114,9 +114,7 @@ def duration(entry, option_key="Duration", **kwargs):
elif _re.match(r"^[\d]+y$", interval):
days += int(interval.rstrip("y")) * 365
else:
raise ValueError(
f"Could not convert section '{interval}' to a {option_key}."
)
raise ValueError(f"Could not convert section '{interval}' to a {option_key}.")
return _dt.timedelta(days, seconds, 0, 0, minutes, hours, weeks)
@ -124,9 +122,7 @@ def duration(entry, option_key="Duration", **kwargs):
def future(entry, option_key="Future Datetime", from_tz=None, **kwargs):
time = datetime(entry, option_key, from_tz=from_tz)
if time < _dt.datetime.utcnow().replace(tzinfo=_dt.timezone.utc):
raise ValueError(
f"That {option_key} is in the past! Must give a Future datetime!"
)
raise ValueError(f"That {option_key} is in the past! Must give a Future datetime!")
return time
@ -136,9 +132,7 @@ def signed_integer(entry, option_key="Signed Integer", **kwargs):
try:
num = int(entry)
except ValueError:
raise ValueError(
f"Could not convert '{entry}' to a whole number for {option_key}!"
)
raise ValueError(f"Could not convert '{entry}' to a whole number for {option_key}!")
return num
@ -152,9 +146,7 @@ def positive_integer(entry, option_key="Positive Integer", **kwargs):
def unsigned_integer(entry, option_key="Unsigned Integer", **kwargs):
num = signed_integer(entry, option_key)
if not num >= 0:
raise ValueError(
f"{option_key} must be a whole number greater than or equal to 0!"
)
raise ValueError(f"{option_key} must be a whole number greater than or equal to 0!")
return num
@ -222,9 +214,7 @@ def lock(entry, option_key="locks", access_options=None, **kwargs):
raise ValueError("Must enter an access type!")
if access_options:
if access_type not in access_options:
raise ValueError(
f"Access type must be one of: {', '.join(access_options)}"
)
raise ValueError(f"Access type must be one of: {', '.join(access_options)}")
if not lockfunc:
raise ValueError("Lock func not entered.")
return entry