Updated docstrings for a few modules, adopting to styles as per #709.

This commit is contained in:
Griatch 2015-05-15 18:43:04 +02:00
parent 809116aabc
commit ae88d67548
2 changed files with 190 additions and 126 deletions

View file

@ -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

View file

@ -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):