diff --git a/evennia/commands/cmdset.py b/evennia/commands/cmdset.py index 4437ac7a6c..fe7812aaa9 100644 --- a/evennia/commands/cmdset.py +++ b/evennia/commands/cmdset.py @@ -358,14 +358,18 @@ class CmdSet(object, metaclass=_CmdSetMeta): """ perm = "perm" if self.permanent else "non-perm" - options = ", ".join([ - "{}:{}".format(opt, "T" if getattr(self, opt) else "F") - for opt in ("no_exits", "no_objs", "no_channels", "duplicates") - if getattr(self, opt) is not None - ]) + options = ", ".join( + [ + "{}:{}".format(opt, "T" if getattr(self, opt) else "F") + for opt in ("no_exits", "no_objs", "no_channels", "duplicates") + if getattr(self, opt) is not None + ] + ) options = (", " + options) if options else "" - return f": " + ", ".join( - [str(cmd) for cmd in sorted(self.commands, key=lambda o: o.key)]) + return ( + f": " + + ", ".join([str(cmd) for cmd in sorted(self.commands, key=lambda o: o.key)]) + ) def __iter__(self): """ diff --git a/evennia/commands/cmdsethandler.py b/evennia/commands/cmdsethandler.py index 51853e8256..84ac1e8e83 100644 --- a/evennia/commands/cmdsethandler.py +++ b/evennia/commands/cmdsethandler.py @@ -331,7 +331,7 @@ class CmdSetHandler(object): if mergelist: # current is a result of mergers - mergelist="+".join(mergelist) + mergelist = "+".join(mergelist) strings.append(f" : {self.current}") else: # current is a single cmdset diff --git a/evennia/commands/command.py b/evennia/commands/command.py index 79bc5915c8..0540952c16 100644 --- a/evennia/commands/command.py +++ b/evennia/commands/command.py @@ -509,7 +509,7 @@ Command {self} has no defined `func()` - showing on-command variables: "SCREENWIDTH", {0: settings.CLIENT_DEFAULT_WIDTH} )[0] return settings.CLIENT_DEFAULT_WIDTH - + def client_height(self): """ Get the client screenheight for the session using this command. diff --git a/evennia/commands/default/building.py b/evennia/commands/default/building.py index babf583391..a159a67d28 100644 --- a/evennia/commands/default/building.py +++ b/evennia/commands/default/building.py @@ -2516,12 +2516,14 @@ class CmdExamine(ObjManipCommand): def _format_options(cmdset): """helper for cmdset-option display""" + def _truefalse(string, value): if value is None: return "" if value: return f"{string}: T" return f"{string}: F" + options = ", ".join( _truefalse(opt, getattr(cmdset, opt)) for opt in ("no_exits", "no_objs", "no_channels", "duplicates") @@ -2538,7 +2540,8 @@ class CmdExamine(ObjManipCommand): continue options = _format_options(cmdset) stored.append( - f"{cmdset.path} [{cmdset.key}] ({cmdset.mergetype}, prio {cmdset.priority}{options})") + f"{cmdset.path} [{cmdset.key}] ({cmdset.mergetype}, prio {cmdset.priority}{options})" + ) output["Stored Cmdset(s)"] = "\n " + "\n ".join(stored) # this gets all components of the currently merged set @@ -2576,13 +2579,15 @@ class CmdExamine(ObjManipCommand): # the resulting merged cmdset options = _format_options(current_cmdset) merged = [ - f" ({current_cmdset.mergetype} prio {current_cmdset.priority}{options})"] + f" ({current_cmdset.mergetype} prio {current_cmdset.priority}{options})" + ] # the merge stack for cmdset in all_cmdsets: options = _format_options(cmdset) merged.append( - f"{cmdset.path} [{cmdset.key}] ({cmdset.mergetype} prio {cmdset.priority}{options})") + f"{cmdset.path} [{cmdset.key}] ({cmdset.mergetype} prio {cmdset.priority}{options})" + ) output["Merged Cmdset(s)"] = "\n " + "\n ".join(merged) # list the commands available to this object diff --git a/evennia/commands/default/comms.py b/evennia/commands/default/comms.py index d984854389..81d966b31b 100644 --- a/evennia/commands/default/comms.py +++ b/evennia/commands/default/comms.py @@ -833,7 +833,7 @@ class CmdPage(COMMAND_DEFAULT_CLASS): receiver = f"|n,{clr}".join([obj.name for obj in page.receivers]) if sending: template = to_template - sender = f"{sender} " if multi_send else "" + sender = f"{sender} " if multi_send else "" receiver = f" {receiver}" if multi_recv else f" {receiver}" else: template = from_template @@ -848,7 +848,6 @@ class CmdPage(COMMAND_DEFAULT_CLASS): receiver=receiver, message=page.message, ) - ) lastpages = "\n ".join(listing) diff --git a/evennia/commands/default/general.py b/evennia/commands/default/general.py index 6b739e022b..9b6b600216 100644 --- a/evennia/commands/default/general.py +++ b/evennia/commands/default/general.py @@ -379,10 +379,13 @@ class CmdInventory(COMMAND_DEFAULT_CLASS): string = "You are not carrying anything." else: from evennia.utils.ansi import raw as raw_ansi + table = self.styled_table(border="header") for item in items: - table.add_row(f"|C{item.name}|n", - "{}|n".format(utils.crop(raw_ansi(item.db.desc), width=50) or "")) + table.add_row( + f"|C{item.name}|n", + "{}|n".format(utils.crop(raw_ansi(item.db.desc), width=50) or ""), + ) string = f"|wYou are carrying:\n{table}" self.caller.msg(string) diff --git a/evennia/commands/default/help.py b/evennia/commands/default/help.py index 234b724a4b..4c2091dfc1 100644 --- a/evennia/commands/default/help.py +++ b/evennia/commands/default/help.py @@ -222,8 +222,11 @@ class CmdHelp(Command): # system, but not be displayed in the table, or be displayed differently. for cmd in all_cmds: if self.should_list_cmd(cmd, caller): - key = (cmd.auto_help_display_key - if hasattr(cmd, "auto_help_display_key") else cmd.key) + key = ( + cmd.auto_help_display_key + if hasattr(cmd, "auto_help_display_key") + else cmd.key + ) hdict_cmd[cmd.help_category].append(key) [hdict_topic[topic.help_category].append(topic.key) for topic in all_topics] # report back @@ -271,10 +274,7 @@ class CmdHelp(Command): cmd = match[0] key = cmd.auto_help_display_key if hasattr(cmd, "auto_help_display_key") else cmd.key formatted = self.format_help_entry( - key, - cmd.get_help(caller, cmdset), - aliases=cmd.aliases, - suggested=suggestions, + key, cmd.get_help(caller, cmdset), aliases=cmd.aliases, suggested=suggestions, ) self.msg_help(formatted) return @@ -294,10 +294,16 @@ class CmdHelp(Command): # try to see if a category name was entered if query in all_categories: self.msg_help( - self.format_help_list({ - query: [ - cmd.auto_help_display_key if hasattr(cmd, "auto_help_display_key") else cmd.key - for cmd in all_cmds if cmd.help_category == query]}, + self.format_help_list( + { + query: [ + cmd.auto_help_display_key + if hasattr(cmd, "auto_help_display_key") + else cmd.key + for cmd in all_cmds + if cmd.help_category == query + ] + }, {query: [topic.key for topic in all_topics if topic.help_category == query]}, ) ) diff --git a/evennia/commands/default/tests.py b/evennia/commands/default/tests.py index 0ad9a932fc..c7a57c6ba9 100644 --- a/evennia/commands/default/tests.py +++ b/evennia/commands/default/tests.py @@ -971,8 +971,11 @@ class TestBuilding(CommandTest): self.call(building.CmdSetHome(), "Obj = Room2", "Home location of Obj was set to Room") def test_list_cmdsets(self): - self.call(building.CmdListCmdSets(), "", - " stack:\n :") + self.call( + building.CmdListCmdSets(), + "", + " stack:\n :", + ) self.call(building.CmdListCmdSets(), "NotFound", "Could not find 'NotFound'") def test_typeclass(self): diff --git a/evennia/commands/tests.py b/evennia/commands/tests.py index bb508a31c9..88e4616d9e 100644 --- a/evennia/commands/tests.py +++ b/evennia/commands/tests.py @@ -339,7 +339,7 @@ class TestOptionTransferTrue(TestCase): b.no_objs = False d.duplicates = False # higher-prio sets will change the option up the chain - cmdset_f = d + c + b + a # reverse, high prio + cmdset_f = d + c + b + a # reverse, high prio self.assertTrue(cmdset_f.no_exits) self.assertTrue(cmdset_f.no_objs) self.assertTrue(cmdset_f.no_channels) @@ -407,7 +407,7 @@ class TestOptionTransferTrue(TestCase): c.priority = 1 d.priority = 2 c.no_exits = False - c.no_channels = None # passthrough + c.no_channels = None # passthrough b.no_objs = False d.duplicates = False # higher-prio sets will change the option up the chain @@ -639,7 +639,7 @@ class TestOptionTransferFalse(TestCase): b.no_objs = True d.duplicates = True # higher-prio sets will change the option up the chain - cmdset_f = d + c + b + a # reverse, high prio + cmdset_f = d + c + b + a # reverse, high prio self.assertFalse(cmdset_f.no_exits) self.assertFalse(cmdset_f.no_objs) self.assertFalse(cmdset_f.no_channels) @@ -663,7 +663,7 @@ class TestOptionTransferFalse(TestCase): b.no_objs = True d.duplicates = True # higher-prio sets will change the option up the chain - cmdset_f = a + b + c + d # forward, high prio, never happens + cmdset_f = a + b + c + d # forward, high prio, never happens self.assertFalse(cmdset_f.no_exits) self.assertFalse(cmdset_f.no_objs) self.assertFalse(cmdset_f.no_channels) @@ -707,7 +707,7 @@ class TestOptionTransferFalse(TestCase): c.priority = 1 d.priority = 2 c.no_exits = True - c.no_channels = None # passthrough + c.no_channels = None # passthrough b.no_objs = True d.duplicates = True # higher-prio sets will change the option up the chain @@ -908,6 +908,7 @@ class TestOptionTransferReplace(TestCase): """ Test option transfer through more complex merge types. """ + def setUp(self): super().setUp() self.cmdset_a = _CmdSetA() diff --git a/evennia/comms/tests.py b/evennia/comms/tests.py index 5ff7377447..a32ae01801 100644 --- a/evennia/comms/tests.py +++ b/evennia/comms/tests.py @@ -21,7 +21,9 @@ class ObjectCreationTest(EvenniaTest): class ChannelWholistTests(EvenniaTest): def setUp(self): super().setUp() - self.default_channel, _ = DefaultChannel.create("coffeetalk", description="A place to talk about coffee.") + self.default_channel, _ = DefaultChannel.create( + "coffeetalk", description="A place to talk about coffee." + ) self.default_channel.connect(self.obj1) def test_wholist_shows_subscribed_objects(self): @@ -31,7 +33,9 @@ class ChannelWholistTests(EvenniaTest): def test_wholist_shows_none_when_empty(self): # No one hates dogs - empty_channel, _ = DefaultChannel.create("doghaters", description="A place where dog haters unite.") + empty_channel, _ = DefaultChannel.create( + "doghaters", description="A place where dog haters unite." + ) expected = "" result = empty_channel.wholist self.assertEqual(expected, result) diff --git a/evennia/contrib/tutorial_world/objects.py b/evennia/contrib/tutorial_world/objects.py index 8d08a945af..ca4147a715 100644 --- a/evennia/contrib/tutorial_world/objects.py +++ b/evennia/contrib/tutorial_world/objects.py @@ -1158,7 +1158,8 @@ class WeaponRack(TutorialObject): |wstab/thrust/pierce |n - poke at the enemy. More damage but harder to hit. |wslash/chop/bash |n - swipe at the enemy. Less damage but easier to hit. |wdefend/parry|n - protect yourself and make yourself harder to hit.) - """).strip() + """ + ).strip() self.db.no_more_weapons_msg = "you find nothing else of use." self.db.available_weapons = ["knife", "dagger", "sword", "club"] diff --git a/evennia/contrib/tutorial_world/rooms.py b/evennia/contrib/tutorial_world/rooms.py index 16eae80a1d..534d6aad77 100644 --- a/evennia/contrib/tutorial_world/rooms.py +++ b/evennia/contrib/tutorial_world/rooms.py @@ -78,6 +78,7 @@ class CmdTutorial(Command): helptext += "\n\n (Write 'give up' if you want to abandon your quest.)" caller.msg(helptext) + # for the @detail command we inherit from MuxCommand, since # we want to make use of MuxCommand's pre-parsing of '=' in the # argument. @@ -202,22 +203,26 @@ class CmdTutorialLook(default_cmds.CmdLook): looking_at_obj.at_desc(looker=caller) return + class CmdTutorialGiveUp(default_cmds.MuxCommand): """ Give up the tutorial-world quest and return to Limbo, the start room of the server. """ + key = "give up" - aliases = ['abort'] + aliases = ["abort"] def func(self): outro_room = OutroRoom.objects.all() if outro_room: outro_room = outro_room[0] else: - self.caller.msg("That didn't work (seems like a bug). " - "Try to use the |wteleport|n command instead.") + self.caller.msg( + "That didn't work (seems like a bug). " + "Try to use the |wteleport|n command instead." + ) return self.caller.move_to(outro_room) @@ -385,6 +390,7 @@ SUPERUSER_WARNING = ( # # ------------------------------------------------------------- + class CmdEvenniaIntro(Command): """ Start the Evennia intro wizard. @@ -393,10 +399,12 @@ class CmdEvenniaIntro(Command): intro """ + key = "intro" def func(self): from .intro_menu import init_menu + # quell also superusers if self.caller.account: self.caller.account.execute_cmd("quell") @@ -452,6 +460,7 @@ class IntroRoom(TutorialRoom): character.account.execute_cmd("quell") character.msg("(Auto-quelling while in tutorial-world)") + # ------------------------------------------------------------- # # Bridge - unique room @@ -1165,4 +1174,3 @@ class OutroRoom(TutorialRoom): def at_object_leave(self, character, destination): if character.account: character.account.execute_cmd("unquell") - diff --git a/evennia/objects/objects.py b/evennia/objects/objects.py index 7e0caec3a3..542a89997b 100644 --- a/evennia/objects/objects.py +++ b/evennia/objects/objects.py @@ -1940,7 +1940,9 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase): # whisper mode msg_type = "whisper" msg_self = ( - '{self} whisper to {all_receivers}, "|n{speech}|n"' if msg_self is True else msg_self + '{self} whisper to {all_receivers}, "|n{speech}|n"' + if msg_self is True + else msg_self ) msg_receivers = msg_receivers or '{object} whispers: "|n{speech}|n"' msg_location = None diff --git a/evennia/typeclasses/managers.py b/evennia/typeclasses/managers.py index 88c35d2122..1521c8ca27 100644 --- a/evennia/typeclasses/managers.py +++ b/evennia/typeclasses/managers.py @@ -31,8 +31,8 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager): # Attribute manager methods def get_attribute( - self, key=None, category=None, value=None, strvalue=None, - obj=None, attrtype=None, **kwargs): + self, key=None, category=None, value=None, strvalue=None, obj=None, attrtype=None, **kwargs + ): """ Return Attribute objects by key, by category, by value, by `strvalue`, by object (it is stored on) or with a combination of diff --git a/evennia/utils/evmenu.py b/evennia/utils/evmenu.py index f6e09c8174..b015406374 100644 --- a/evennia/utils/evmenu.py +++ b/evennia/utils/evmenu.py @@ -1660,9 +1660,7 @@ def get_input(caller, prompt, callback, session=None, *args, **kwargs): _RE_NODE = re.compile(r"##\s*?NODE\s+?(?P\S[\S\s]*?)$", re.I + re.M) _RE_OPTIONS_SEP = re.compile(r"##\s*?OPTIONS\s*?$", re.I + re.M) _RE_CALLABLE = re.compile(r"\S+?\(\)", re.I + re.M) -_RE_CALLABLE = re.compile( - r"(?P\S+?)(?:\((?P[\S\s]+?)\)|\(\))", re.I + re.M -) +_RE_CALLABLE = re.compile(r"(?P\S+?)(?:\((?P[\S\s]+?)\)|\(\))", re.I + re.M) _HELP_NO_OPTION_MATCH = _("Choose an option or try 'help'.") @@ -1676,8 +1674,8 @@ _OPTION_COMMENT_START = "#" # Input/option/goto handler functions that allows for dynamically generated # nodes read from the menu template. -def _process_callable(caller, goto, goto_callables, raw_string, - current_nodename, kwargs): + +def _process_callable(caller, goto, goto_callables, raw_string, current_nodename, kwargs): """ Central helper for parsing a goto-callable (`funcname(**kwargs)`) out of the right-hand-side of the template options and map this to an actual @@ -1693,12 +1691,18 @@ def _process_callable(caller, goto, goto_callables, raw_string, for kwarg in gotokwargs.split(","): if kwarg and "=" in kwarg: key, value = [part.strip() for part in kwarg.split("=", 1)] - if key in ("evmenu_goto", "evmenu_gotomap", "_current_nodename", - "evmenu_current_nodename", "evmenu_goto_callables"): + if key in ( + "evmenu_goto", + "evmenu_gotomap", + "_current_nodename", + "evmenu_current_nodename", + "evmenu_goto_callables", + ): raise RuntimeError( f"EvMenu template error: goto-callable '{goto}' uses a " f"kwarg ({kwarg}) that is reserved for the EvMenu templating " - "system. Rename the kwarg.") + "system. Rename the kwarg." + ) try: key = literal_eval(key) except ValueError: @@ -1725,8 +1729,7 @@ def _generated_goto_func(caller, raw_string, **kwargs): goto = kwargs["evmenu_goto"] goto_callables = kwargs["evmenu_goto_callables"] current_nodename = kwargs["evmenu_current_nodename"] - return _process_callable(caller, goto, goto_callables, raw_string, - current_nodename, kwargs) + return _process_callable(caller, goto, goto_callables, raw_string, current_nodename, kwargs) def _generated_input_goto_func(caller, raw_string, **kwargs): @@ -1746,13 +1749,15 @@ def _generated_input_goto_func(caller, raw_string, **kwargs): # start with glob patterns for pattern, goto in gotomap.items(): if fnmatch(raw_string.lower(), pattern): - return _process_callable(caller, goto, goto_callables, raw_string, - current_nodename, kwargs) + return _process_callable( + caller, goto, goto_callables, raw_string, current_nodename, kwargs + ) # no glob pattern match; try regex for pattern, goto in gotomap.items(): if pattern and re.match(pattern, raw_string.lower(), flags=re.I + re.M): - return _process_callable(caller, goto, goto_callables, raw_string, - current_nodename, kwargs) + return _process_callable( + caller, goto, goto_callables, raw_string, current_nodename, kwargs + ) # no match, show error raise EvMenuGotoAbortMessage(_HELP_NO_OPTION_MATCH) @@ -1783,6 +1788,7 @@ def parse_menu_template(caller, menu_template, goto_callables=None): dict: A `{"node": nodefunc}` menutree suitable to pass into EvMenu. """ + def _validate_kwarg(goto, kwarg): """ Validate goto-callable kwarg is on correct form. @@ -1792,14 +1798,21 @@ def parse_menu_template(caller, menu_template, goto_callables=None): f"EvMenu template error: goto-callable '{goto}' has a " f"non-kwarg argument ({kwarg}). All callables in the " "template must have only keyword-arguments, or no " - "args at all.") + "args at all." + ) key, _ = [part.strip() for part in kwarg.split("=", 1)] - if key in ("evmenu_goto", "evmenu_gotomap", "_current_nodename", - "evmenu_current_nodename", "evmenu_goto_callables"): + if key in ( + "evmenu_goto", + "evmenu_gotomap", + "_current_nodename", + "evmenu_current_nodename", + "evmenu_goto_callables", + ): raise RuntimeError( f"EvMenu template error: goto-callable '{goto}' uses a " f"kwarg ({kwarg}) that is reserved for the EvMenu templating " - "system. Rename the kwarg.") + "system. Rename the kwarg." + ) def _parse_options(nodename, optiontxt, goto_callables): """ @@ -1829,7 +1842,7 @@ def parse_menu_template(caller, menu_template, goto_callables=None): if match: kwargs = match.group("kwargs") if kwargs: - for kwarg in kwargs.split(','): + for kwarg in kwargs.split(","): _validate_kwarg(goto, kwarg) # parse key [;aliases|pattern] @@ -1841,7 +1854,7 @@ def parse_menu_template(caller, menu_template, goto_callables=None): if main_key.startswith(_OPTION_INPUT_MARKER): # if we have a pattern, build the arguments for _default later - pattern = main_key[len(_OPTION_INPUT_MARKER):].strip() + pattern = main_key[len(_OPTION_INPUT_MARKER) :].strip() inputparsemap[pattern] = goto else: # a regular goto string/callable target @@ -1902,12 +1915,7 @@ def parse_menu_template(caller, menu_template, goto_callables=None): def template2menu( - caller, - menu_template, - goto_callables=None, - startnode="start", - persistent=False, - **kwargs, + caller, menu_template, goto_callables=None, startnode="start", persistent=False, **kwargs, ): """ Helper function to generate and start an EvMenu based on a menu template @@ -1932,9 +1940,4 @@ def template2menu( """ goto_callables = goto_callables or {} menu_tree = parse_menu_template(caller, menu_template, goto_callables) - return EvMenu( - caller, - menu_tree, - persistent=persistent, - **kwargs, - ) + return EvMenu(caller, menu_tree, persistent=persistent, **kwargs,) diff --git a/evennia/utils/tests/test_evmenu.py b/evennia/utils/tests/test_evmenu.py index 190afce564..dc440a3f37 100644 --- a/evennia/utils/tests/test_evmenu.py +++ b/evennia/utils/tests/test_evmenu.py @@ -321,8 +321,7 @@ class TestMenuTemplateParse(EvenniaTest): def test_parse_menu_template(self): """EvMenu template testing""" - menutree = evmenu.parse_menu_template(self.char1, self.menu_template, - self.goto_callables) + menutree = evmenu.parse_menu_template(self.char1, self.menu_template, self.goto_callables) self.assertEqual(menutree, {"start": Anything, "node1": Anything, "node2": Anything}) def test_template2menu(self):