From ae88d67548ef778c66fc4e6a399bd2e63a90cbf3 Mon Sep 17 00:00:00 2001 From: Griatch Date: Fri, 15 May 2015 18:43:04 +0200 Subject: [PATCH] Updated docstrings for a few modules, adopting to styles as per #709. --- evennia/commands/cmdhandler.py | 157 +++++++++++++++++++------------- evennia/commands/cmdparser.py | 159 ++++++++++++++++++++------------- 2 files changed, 190 insertions(+), 126 deletions(-) diff --git a/evennia/commands/cmdhandler.py b/evennia/commands/cmdhandler.py index d6f328008b..8599b06831 100644 --- a/evennia/commands/cmdhandler.py +++ b/evennia/commands/cmdhandler.py @@ -2,35 +2,35 @@ Command handler This module contains the infrastructure for accepting commands on the -command line. The process is as follows: +command line. The processing of a command works as follows: -1) The calling object (caller) inputs a string and triggers the command parsing system. -2) The system checks the state of the caller - loggedin or not -3) If no command string was supplied, we search the merged cmdset for system command CMD_NOINPUT - and branches to execute that. --> Finished -4) Cmdsets are gathered from different sources (in order of dropping priority): - channels - all available channel names are auto-created into a cmdset, to allow - for giving the channel name and have the following immediately - sent to the channel. The sending is performed by the CMD_CHANNEL - system command. - object cmdsets - all objects at caller's location are scanned for non-empty - cmdsets. This includes cmdsets on exits. - caller - the caller is searched for its own currently active cmdset. - player - lastly the cmdsets defined on caller.player are added. -5) All the gathered cmdsets (if more than one) are merged into one using the cmdset priority rules. -6) If merged cmdset is empty, raise NoCmdSet exception (this should not happen, at least the - player should have a default cmdset available at all times). --> Finished -7) The raw input string is parsed using the parser defined by settings.COMMAND_PARSER. It - uses the available commands from the merged cmdset to know which commands to look for and - returns one or many matches. -8) If match list is empty, branch to system command CMD_NOMATCH --> Finished -9) If match list has more than one element, branch to system command CMD_MULTIMATCH --> Finished -10) A single match was found. If this is a channel-command (i.e. the command name is that of a channel), - branch to CMD_CHANNEL --> Finished -11) At this point we have found a normal command. We assign useful variables to it that - will be available to the command coder at run-time. -12) We have a unique cmdobject, primed for use. Call all hooks: - at_pre_cmd(), cmdobj.parse(), cmdobj.func() and finally at_post_cmd(). +1. The calling object (caller) is analyzed based on its callertype. +2. Cmdsets are gathered from different sources: + - channels: all available channel names are auto-created into a cmdset, to allow + for giving the channel name and have the following immediately + sent to the channel. The sending is performed by the CMD_CHANNEL + system command. + - object cmdsets: all objects at caller's location are scanned for non-empty + cmdsets. This includes cmdsets on exits. + - caller: the caller is searched for its own currently active cmdset. + - player: lastly the cmdsets defined on caller.player are added. +3. The collected cmdsets are merged together to a combined, current cmdset. +4. If the input string is empty -> check for CMD_NOINPUT command in + current cmdset or fallback to error message. Exit. +5. The Command Parser is triggered, using the current cmdset to analyze the + input string for possible command matches. +6. If multiple matches are found -> check for CMD_MULTIMATCH in current + cmdset, or fallback to error message. Exit. +7. If no match was found -> check for CMD_NOMATCH in current cmdset or + fallback to error message. Exit. +8. A single match was found. If this is a channel-command (i.e. the + ommand name is that of a channel), --> check for CMD_CHANNEL in + current cmdset or use channelhandler default. Exit. +9. At this point we have found a normal command. We assign useful variables to it that + will be available to the command coder at run-time. +12. We have a unique cmdobject, primed for use. Call all hooks: + `at_pre_cmd()`, `cmdobj.parse()`, `cmdobj.func()` and finally `at_post_cmd()`. +13. Return deferred that will fire with the return from `cmdobj.func()` (unused by default). """ @@ -128,24 +128,37 @@ def get_and_merge_cmdsets(caller, session, player, obj, """ Gather all relevant cmdsets and merge them. - callertype is one of "session", "player" or "object" dependin - on which level the cmdhandler is invoked. Session includes the - cmdsets available to Session, Player and its eventual puppeted Object. - Player-level include cmdsets on Player and Object, while calling - the handler on an Object only includes cmdsets on itself. + Args: + caller (Session, Player or Object): The entity executing the command. Which + type of object this is depends on the current game state; for example + when the user is not logged in, this will be a Session, when being OOC + it will be a Player and when puppeting an object this will (often) be + a Character Object. In the end it depends on where the cmdset is stored. + session (Session or None): The Session associated with caller, if any. + player (Player or None): The calling Player associated with caller, if any. + obj (Object or None): The Object associated with caller, if any. + callertype (str): This identifies caller as either "player", "object" or "session" + to avoid having to do this check internally. + sessid (int, optional): Session ID. This is not used at the moment. - The cdmsets are merged in order generality, so that the Object's - cmdset is merged last (and will thus take precedence over - same-named and same-prio commands on Player and Session). + Returns: + cmdset (Deferred): This deferred fires with the merged cmdset + result once merger finishes. + + Notes: + The cdmsets are merged in order or generality, so that the + Object's cmdset is merged last (and will thus take precedence + over same-named and same-prio commands on Player and Session). - Note that this function returns a deferred! """ try: local_obj_cmdsets = [None] @inlineCallbacks def _get_channel_cmdsets(player, player_cmdset): - "Channel-cmdsets" + """ + Helper-method; Get channel-cmdsets + """ # Create cmdset for all player's available channels try: channel_cmdset = None @@ -159,7 +172,9 @@ def get_and_merge_cmdsets(caller, session, player, obj, @inlineCallbacks def _get_local_obj_cmdsets(obj, obj_cmdset): - "Object-level cmdsets" + """ + Helper-method; Get Object-level cmdsets + """ # Gather cmdsets from location, objects in location or carried try: local_obj_cmdsets = [None] @@ -202,7 +217,10 @@ def get_and_merge_cmdsets(caller, session, player, obj, @inlineCallbacks def _get_cmdset(obj): - "Get cmdset, triggering all hooks" + """ + Helper method; Get cmdset while making sure to trigger all + hooks safely. + """ try: yield obj.at_cmdset_get() except Exception: @@ -307,43 +325,54 @@ def get_and_merge_cmdsets(caller, session, player, obj, @inlineCallbacks def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sessid=None, **kwargs): """ - This is the main function to handle any string sent to the engine. + This is the main mechanism that handles any string sent to the engine. - called_by - object on which this was called from. This is either a Session, a Player or an Object. - raw_string - the command string given on the command line - _testing - if we should actually execute the command or not. - if True, the command instance will be returned instead. - callertype - this is one of "session", "player" or "object", in decending - order. So when the Session is the caller, it will merge its - own cmdset into cmdsets from both Player and eventual puppeted - Object (and cmdsets in its room etc). A Player will only - include its own cmdset and the Objects and so on. Merge order - is the same order, so that Object cmdsets are merged in last, - giving them precendence for same-name and same-prio commands. - sessid - Relevant if callertype is "player" - the session id will help - retrieve the correct cmdsets from puppeted objects. - **kwargs - other keyword arguments will be assigned as named variables on the - retrieved command object *before* it is executed. This is unuesed - in default Evennia but may be used by code to set custom flags or - special operating conditions for a command as it executes. + Args: + called_by (Session, Player or Object): Object from which this + command was called. which this was called from. What this is + depends on the game state. + raw_string (str): The command string as given on the command line. + _testing (bool, optional): Used for debug purposes and decides if we + should actually execute the command or not. If True, the + command instance will be returned. + callertype (str, optional): One of "session", "player" or + "object". These are treated in decending order, so when the + Session is the caller, it will merge its own cmdset into + cmdsets from both Player and eventual puppeted Object (and + cmdsets in its room etc). A Player will only include its own + cmdset and the Objects and so on. Merge order is the same + order, so that Object cmdsets are merged in last, giving them + precendence for same-name and same-prio commands. + sessid (int, optional): Relevant if callertype is "player" - the session id will help + retrieve the correct cmdsets from puppeted objects. + + Kwargs: + kwargs (any): other keyword arguments will be assigned as named variables on the + retrieved command object *before* it is executed. This is unused + in default Evennia but may be used by code to set custom flags or + special operating conditions for a command as it executes. + + Returns: + deferred (Deferred): This deferred is fired with the return + value of the command's `func` method. This is not used in + default Evennia. - Note that this function returns a deferred! """ @inlineCallbacks def _run_command(cmd, cmdname, args): """ - This initializes and runs the Command instance once the parser - has identified it as either a normal command or one of the - system commands. + Helper function: This initializes and runs the Command + instance once the parser has identified it as either a normal + command or one of the system commands. Args: cmd (Command): command object cmdname (str): name of command args (str): extra text entered after the identified command Returns: - deferred (Deferred): this will fire when the func() method - returns. + deferred (Deferred): this will fire with the return of the + command's `func` method. """ try: # Assign useful variables to the instance diff --git a/evennia/commands/cmdparser.py b/evennia/commands/cmdparser.py index 7efbb1645d..97ce52ce2a 100644 --- a/evennia/commands/cmdparser.py +++ b/evennia/commands/cmdparser.py @@ -1,8 +1,9 @@ """ The default command parser. Use your own by assigning -settings.COMMAND_PARSER to a Python path to a module containing the -replacing cmdparser function. The replacement parser must matches -on the sme form as the default cmdparser. +`settings.COMMAND_PARSER` to a Python path to a module containing the +replacing cmdparser function. The replacement parser must accept the +same inputs as the default one. + """ from django.utils.translation import ugettext as _ @@ -13,32 +14,50 @@ def cmdparser(raw_string, cmdset, caller, match_index=None): This function is called by the cmdhandler once it has gathered and merged all valid cmdsets valid for this particular parsing. - raw_string - the unparsed text entered by the caller. - cmdset - the merged, currently valid cmdset - caller - the caller triggering this parsing - match_index - an optional integer index to pick a given match in a - list of same-named command matches. + Args: + raw_string (str): The unparsed text entered by the caller. + cmdset (CmdSet): The merged, currently valid cmdset + caller (Session, Player or Object): The caller triggering this parsing. + match_index (int, optional): Index to pick a given match in a + list of same-named command matches. If this is given, it suggests + this is not the first time this function was called: normally + the first run resulted in a multimatch, and the index is given + to select between the results for the second run. - The cmdparser understand the following command combinations (where - [] marks optional parts. + Notes: + The cmdparser understand the following command combinations (where + [] marks optional parts. - [cmdname[ cmdname2 cmdname3 ...] [the rest] + ``` + [cmdname[ cmdname2 cmdname3 ...] [the rest] + ``` - A command may consist of any number of space-separated words of any - length, and contain any character. It may also be empty. + A command may consist of any number of space-separated words of any + length, and contain any character. It may also be empty. + + The parser makes use of the cmdset to find command candidates. The + parser return a list of matches. Each match is a tuple with its + first three elements being the parsed cmdname (lower case), + the remaining arguments, and the matched cmdobject from the cmdset. - The parser makes use of the cmdset to find command candidates. The - parser return a list of matches. Each match is a tuple with its - first three elements being the parsed cmdname (lower case), - the remaining arguments, and the matched cmdobject from the cmdset. """ def create_match(cmdname, string, cmdobj): """ - Evaluates the quality of a match by counting how many chars of cmdname - matches string (counting from beginning of string). We also calculate - a ratio from 0-1 describing how much cmdname matches string. - We return a tuple (cmdname, count, ratio, args, cmdobj). + Builds a command match by splitting the incoming string and + evaluating the quality of the match. + + Args: + cmdname (str): Name of command to check for. + string (str): The string to match against. + cmdobj (str): The full Command instance. + + Returns: + match (tuple): This is on the form (cmdname, args, cmdobj, cmdlen, mratio), where + `cmdname` is the command's name and `args` the rest of the incoming string, + without said command name. `cmdobj` is the Command instance, the cmdlen is + the same as len(cmdname) and mratio is a measure of how big a part of the + full input string the cmdname takes up - an exact match would be 1.0. """ cmdlen, strlen = len(cmdname), len(string) @@ -126,27 +145,31 @@ def at_search_result(msg_obj, ostring, results, global_search=False, nofound_string=None, multimatch_string=None, quiet=False): """ Called by search methods after a result of any type has been found. + Takes a search result (a list) and formats eventual errors. - Takes a search result (a list) and - formats eventual errors. - - msg_obj - object to receive feedback. - ostring - original search string - results - list of found matches (0, 1 or more) - global_search - if this was a global_search or not - (if it is, there might be an idea of supplying - dbrefs instead of only numbers) - nofound_string - optional custom string for not-found error message. - multimatch_string - optional custom string for multimatch error header - quiet - work normally, but don't echo to caller, just return the + Args: + msg_obj (Object): Object to receive feedback. + ostring (str): Original search string + results (list): List of found matches (0, 1 or more) + global_search (bool, optional): I this was a global_search or not (if it + is, there might be an idea of supplying dbrefs instead of only + numbers) + nofound_string (str, optional): Custom string for not-found error message. + multimatch_string (str, optional): Custom string for multimatch error header + quiet (bool, optional): Work normally, but don't echo to caller, just return the results. - Multiple matches are returned to the searching object - as - 1-object - 2-object - 3-object - etc + Returns: + result (Object or None): The filtered object. If None, it suggests a + nofound/multimatch error and the error message was sent directly to `msg_obj`. If + the `multimatch_strin` was not given, the multimatch error will be returned as + + ``` + 1-object + 2-object + 3-object + etc + ``` """ string = "" @@ -202,33 +225,36 @@ def at_multimatch_input(ostring): if the user wants to differentiate between multiple matches (usually found during a previous search). - This method should separate out any identifiers from the search - string used to differentiate between same-named objects. The - result should be a tuple (index, search_string) where the index - gives which match among multiple matches should be used (1 being - the lowest number, rather than 0 as in Python). + Args: + ostring (str): The search criterion. The parser will specifically + understand input on a form like `2-object` to separate + multimatches from each other. - This parser version will identify search strings on the following - forms + Returns: + selection (tuple): This is on the form (index, ostring). - 2-object + Notes: + This method should separate out any identifiers from the search + string used to differentiate between same-named objects. The + result should be a tuple (index, search_string) where the index + gives which match among multiple matches should be used (1 being + the lowest number, rather than 0 as in Python). - This will be parsed to (2, "object") and, if applicable, will tell - the engine to pick the second from a list of same-named matches of - objects called "object". + This will be parsed to (2, "object") and, if applicable, will tell + the engine to pick the second from a list of same-named matches of + objects called "object". - Ex for use in a game session: - - > look - You see: ball, ball, ball and ball. - > get ball - There where multiple matches for ball: - 1-ball - 2-ball - 3-ball - 4-ball - > get 3-ball - You get the ball. + Example: + > look + You see: ball, ball, ball and ball. + > get ball + There where multiple matches for ball: + 1-ball + 2-ball + 3-ball + 4-ball + > get 3-ball + You get the ball. """ @@ -250,6 +276,15 @@ def at_multimatch_input(ostring): def at_multimatch_cmd(caller, matches): """ Format multiple command matches to a useful error. + + Args: + caller (Object): Calling object. + matches (list): A list of matchtuples `(num, Command)`. + + Returns: + formatted (str): A nicely formatted string, including + eventual errors. + """ string = "There were multiple matches:" for num, match in enumerate(matches):