Remove tests from api doc

This commit is contained in:
Griatch 2020-07-10 18:04:55 +02:00
parent b1cae35e34
commit 2208a3030c
27 changed files with 298 additions and 320 deletions

View file

@ -12,7 +12,7 @@ SPHINXMULTIVERSION ?= sphinx-multiversion
SPHINXAPIDOC ?= sphinx-apidoc
SPHINXAPIDOCOPTS = --tocfile evennia-api --module-first --force -d 6 --separate --templatedir=$(SOURCEDIR)/_templates/
SPHINXAPIDOCENV = members,undoc-members,show-inheritance
SPHINXAPIDOCEXCLUDE = ../*/migrations/* ../evennia/game_template/* ../*/*/tests/*
SPHINXAPIDOCEXCLUDE = ../*/migrations/* ../evennia/game_template/* ../evennia/*/tests/* ../evennia/*/tests.py
EVDIR ?= $(realpath ../evennia)
EVGAMEDIR ?= $(realpath ../../gamedir)

View file

@ -17,4 +17,3 @@ Modules
evennia.accounts.bots
evennia.accounts.manager
evennia.accounts.models
evennia.accounts.tests

View file

@ -1,7 +0,0 @@
evennia.accounts.tests
=============================
.. automodule:: evennia.accounts.tests
:members:
:undoc-members:
:show-inheritance:

View file

@ -17,7 +17,6 @@ Modules
evennia.commands.cmdset
evennia.commands.cmdsethandler
evennia.commands.command
evennia.commands.tests
Packages/folders
----------------

View file

@ -1,7 +0,0 @@
evennia.commands.tests
=============================
.. automodule:: evennia.commands.tests
:members:
:undoc-members:
:show-inheritance:

View file

@ -17,4 +17,3 @@ Modules
evennia.comms.comms
evennia.comms.managers
evennia.comms.models
evennia.comms.tests

View file

@ -1,7 +0,0 @@
evennia.comms.tests
==========================
.. automodule:: evennia.comms.tests
:members:
:undoc-members:
:show-inheritance:

View file

@ -36,7 +36,6 @@ Modules
evennia.contrib.slow_exit
evennia.contrib.talking_npc
evennia.contrib.test_traits
evennia.contrib.tests
evennia.contrib.traits
evennia.contrib.tree_select
evennia.contrib.unixcommand

View file

@ -1,7 +0,0 @@
evennia.contrib.tests
============================
.. automodule:: evennia.contrib.tests
:members:
:undoc-members:
:show-inheritance:

View file

@ -14,4 +14,3 @@ Modules
evennia.locks.lockfuncs
evennia.locks.lockhandler
evennia.locks.tests

View file

@ -1,7 +0,0 @@
evennia.locks.tests
==========================
.. automodule:: evennia.locks.tests
:members:
:undoc-members:
:show-inheritance:

View file

@ -16,4 +16,3 @@ Modules
evennia.objects.manager
evennia.objects.models
evennia.objects.objects
evennia.objects.tests

View file

@ -1,7 +0,0 @@
evennia.objects.tests
============================
.. automodule:: evennia.objects.tests
:members:
:undoc-members:
:show-inheritance:

View file

@ -16,4 +16,3 @@ Modules
evennia.prototypes.protfuncs
evennia.prototypes.prototypes
evennia.prototypes.spawner
evennia.prototypes.tests

View file

@ -1,7 +0,0 @@
evennia.prototypes.tests
===============================
.. automodule:: evennia.prototypes.tests
:members:
:undoc-members:
:show-inheritance:

View file

@ -19,5 +19,4 @@ Modules
evennia.scripts.scripthandler
evennia.scripts.scripts
evennia.scripts.taskhandler
evennia.scripts.tests
evennia.scripts.tickerhandler

View file

@ -1,7 +0,0 @@
evennia.scripts.tests
============================
.. automodule:: evennia.scripts.tests
:members:
:undoc-members:
:show-inheritance:

View file

@ -17,4 +17,3 @@ Modules
evennia.typeclasses.managers
evennia.typeclasses.models
evennia.typeclasses.tags
evennia.typeclasses.tests

View file

@ -1,7 +0,0 @@
evennia.typeclasses.tests
================================
.. automodule:: evennia.typeclasses.tests
:members:
:undoc-members:
:show-inheritance:

View file

@ -255,11 +255,28 @@ def autodoc_post_process_docstring(app, what, name, obj, options, lines):
return "::\n\n {}".format(
"\n ".join(lne for lne in code.split("\n")))
underline_map = {
1: "-",
2: "=",
3: '^',
4: '"',
}
def _sub_header(match):
# add underline to convert a markdown #header to ReST
groupdict = match.groupdict()
hashes, title = groupdict["hashes"], groupdict["title"]
title = title.strip()
lvl = min(max(1, len(hashes)), 4)
return f"{title}\n" + (underline_map[lvl] * len(title))
doc = "\n".join(lines)
doc = re.sub(r"```python\s*\n+(.*?)```", _sub_codeblock, doc,
flags=re.MULTILINE + re.DOTALL)
doc = re.sub(r"```", "", doc, flags=re.MULTILINE)
doc = re.sub(r"`{1}", "**", doc, flags=re.MULTILINE)
doc = re.sub(r"^(?P<hashes>#{1,2})\s*?(?P<title>.*?)$", _sub_header, doc, flags=re.MULTILINE)
newlines = doc.split("\n")
# we must modify lines in-place
lines[:] = newlines[:]

View file

@ -4,12 +4,12 @@ sessions of users connecting to the server.
There are two similar but separate stores of sessions:
- ServerSessionHandler - this stores generic game sessions
for the game. These sessions has no knowledge about
how they are connected to the world.
- PortalSessionHandler - this stores sessions created by
twisted protocols. These are dumb connectors that
handle network communication but holds no game info.
- ServerSessionHandler - this stores generic game sessions
for the game. These sessions has no knowledge about
how they are connected to the world.
- PortalSessionHandler - this stores sessions created by
twisted protocols. These are dumb connectors that
handle network communication but holds no game info.
"""
import time
@ -156,21 +156,20 @@ class SessionHandler(dict):
Args:
session (Session): The relevant session instance.
kwargs (dict) Each keyword represents a
send-instruction, with the keyword itself being the name
kwargs (dict) Each keyword represents a send-instruction, with the keyword itself being the name
of the instruction (like "text"). Suitable values for each
keyword are:
- arg -> [[arg], {}]
- [args] -> [[args], {}]
- {kwargs} -> [[], {kwargs}]
- [args, {kwargs}] -> [[arg], {kwargs}]
- [[args], {kwargs}] -> [[args], {kwargs}]
- arg -> [[arg], {}]
- [args] -> [[args], {}]
- {kwargs} -> [[], {kwargs}]
- [args, {kwargs}] -> [[arg], {kwargs}]
- [[args], {kwargs}] -> [[args], {kwargs}]
Returns:
kwargs (dict): A cleaned dictionary of cmdname:[[args],{kwargs}] pairs,
where the keys, args and kwargs have all been converted to
send-safe entities (strings or numbers), and inlinefuncs have been
applied.
where the keys, args and kwargs have all been converted to
send-safe entities (strings or numbers), and inlinefuncs have been
applied.
"""
options = kwargs.pop("options", None) or {}
@ -809,9 +808,9 @@ class ServerSessionHandler(SessionHandler):
def call_inputfuncs(self, session, **kwargs):
"""
Split incoming data into its inputfunc counterparts.
This should be called by the serversession.data_in
as sessionhandler.call_inputfunc(self, **kwargs).
Split incoming data into its inputfunc counterparts. This should be
called by the `serversession.data_in` as
`sessionhandler.call_inputfunc(self, **kwargs)`.
We also intercept OOB communication here.
@ -819,8 +818,8 @@ class ServerSessionHandler(SessionHandler):
sessions (Session): Session.
Keyword args:
kwargs (any): Incoming data from protocol on
the form `{"commandname": ((args), {kwargs}),...}`
any (tuple): Incoming data from protocol, each
on the form `commandname=((args), {kwargs})`.
"""

View file

@ -1,21 +1,23 @@
"""
This module brings Django Signals into Evennia. These are events that
can be subscribed to by importing a given Signal and using the
following code.
This module brings Django Signals into Evennia. These are events that can be
subscribed to by importing a given Signal and using the following code.
```python
THIS_SIGNAL.connect(callback, sender_object)
```
When other code calls THIS_SIGNAL.send(sender, **kwargs), the callback
will be triggered.
When other code calls `THIS_SIGNAL.send(sender, **kwargs)`, the callback will
be triggered.
Callbacks must be in the following format:
Callbacks must be on the following format:
```python
def my_callback(sender, **kwargs):
...
# ...
```
This is used on top of hooks to make certain features easier to
add to contribs without necessitating a full takeover of hooks
that may be in high demand.
This is used on top of hooks to make certain features easier to add to contribs
without necessitating a full takeover of hooks that may be in high demand.
"""
from django.dispatch import Signal

View file

@ -578,36 +578,38 @@ class IAttributeBackend:
def do_batch_finish(self, attr_objs):
"""
Called only by batch_add. Used for handling database operations and/or caching complications.
Called only by batch_add. Used for handling database operations and/or
caching complications.
Args:
attr_objs (list of IAttribute): The Attributes created/updated thus far.
"""
raise NotImplementedError()
def batch_add(self, *args, **kwargs):
"""
Batch-version of `add()`. This is more efficient than
repeat-calling add when having many Attributes to add.
Batch-version of `.add()`. This is more efficient than repeat-calling
`.add` when having many Attributes to add.
Args:
indata (list): List of tuples of varying length representing the
*args (tuple): Tuples of varying length representing the
Attribute to add to this object. Supported tuples are
- `(key, value)`
- `(key, value, category)`
- `(key, value, category, lockstring)`
- `(key, value, category, lockstring, default_access)`
- (key, value)
- (key, value, category)
- (key, value, category, lockstring)
- (key, value, category, lockstring, default_access)
Raises:
RuntimeError: If trying to pass a non-iterable as argument.
Notes:
The indata tuple order matters, so if you want a lockstring
but no category, set the category to `None`. This method
does not have the ability to check editing permissions like
normal .add does, and is mainly used internally. It does not
use the normal self.add but apply the Attributes directly
to the database.
The indata tuple order matters, so if you want a lockstring but no
category, set the category to `None`. This method does not have the
ability to check editing permissions and is mainly used internally.
It does not use the normal `self.add` but applies the Attributes
directly to the database.
"""
new_attrobjs = []
@ -1092,12 +1094,13 @@ class AttributeHandler:
repeat-calling add when having many Attributes to add.
Args:
indata (list): List of tuples of varying length representing the
*args (tuple): Tuples of varying length representing the
Attribute to add to this object. Supported tuples are
- `(key, value)`
- `(key, value, category)`
- `(key, value, category, lockstring)`
- `(key, value, category, lockstring, default_access)`
- (key, value)
- (key, value, category)
- (key, value, category, lockstring)
- (key, value, category, lockstring, default_access)
Keyword args:
strattr (bool): If `True`, value must be a string. This
@ -1306,12 +1309,12 @@ def initialize_nick_templates(in_template, out_template):
Returns:
regex (regex): Regex to match against strings
template (str): Template with markers {arg1}, {arg2}, etc for
replacement using the standard .format method.
template (str): Template with markers ``{arg1}, {arg2}``, etc for
replacement using the standard .format method.
Raises:
NickTemplateInvalid: If the in/out template does not have a matching
number of $args.
number of `$args`.
"""

View file

@ -34,14 +34,12 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
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
those criteria.
Return Attribute objects by key, by category, by value, by strvalue, by
object (it is stored on) or with a combination of those criteria.
Attrs:
Args:
key (str, optional): The attribute's key to search for
category (str, optional): The category of the attribute(s)
to search for.
category (str, optional): The category of the attribute(s) to search for.
value (str, optional): The attribute value to search for.
Note that this is not a very efficient operation since it
will query for a pickled entity. Mutually exclusive to
@ -55,10 +53,10 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
attrype (str, optional): An attribute-type to search for.
By default this is either `None` (normal Attributes) or
`"nick"`.
kwargs (any): Currently unused. Reserved for future use.
**kwargs (any): Currently unused. Reserved for future use.
Returns:
attributes (list): The matching Attributes.
list: The matching Attributes.
"""
dbmodel = self.model.__dbclass__.__name__.lower()
@ -84,7 +82,7 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
"""
Get a nick, in parallel to `get_attribute`.
Attrs:
Args:
key (str, optional): The nicks's key to search for
category (str, optional): The category of the nicks(s) to search for.
value (str, optional): The attribute value to search for. Note that this
@ -170,13 +168,13 @@ class TypedObjectManager(idmapper.manager.SharedMemoryManager):
Return Tag objects by key, by category, by object (it is
stored on) or with a combination of those criteria.
Attrs:
Args:
key (str, optional): The Tag's key to search for
category (str, optional): The Tag of the attribute(s)
to search for.
obj (Object, optional): On which object the Tag to
search for is.
tagtype (str, optional): One of None (normal tags),
tagtype (str, optional): One of `None` (normal tags),
"alias" or "permission"
global_search (bool, optional): Include all possible tags,
not just tags on this object

View file

@ -578,7 +578,7 @@ class TypedObject(SharedMemoryModel):
superuser lock bypass (be careful with this one).
Keyword args:
kwargs (any): Ignored, but is there to make the api
kwar (any): Ignored, but is there to make the api
consistent with the object-typeclass method access, which
use it to feed to its hook methods.
@ -667,14 +667,19 @@ class TypedObject(SharedMemoryModel):
def __db_get(self):
"""
Attribute handler wrapper. Allows for the syntax
```python
obj.db.attrname = value
and
# and
value = obj.db.attrname
and
# and
del obj.db.attrname
and
all_attr = obj.db.all() (unless there is an attribute
named 'all', in which case that will be returned instead).
# and
all_attr = obj.db.all()
# (unless there is an attribute
# named 'all', in which case that will be returned instead).
```
"""
try:
return self._db_holder
@ -844,26 +849,32 @@ class TypedObject(SharedMemoryModel):
Returns the URI path for a View that allows users to view details for
this object.
ex. Oscar (Character) = '/characters/oscar/1/'
For this to work, the developer must have defined a named view somewhere
in urls.py that follows the format 'modelname-action', so in this case
a named view of 'character-detail' would be referenced by this method.
ex.
url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/$',
CharDetailView.as_view(), name='character-detail')
If no View has been created and defined in urls.py, returns an
HTML anchor.
This method is naive and simply returns a path. Securing access to
the actual view and limiting who can view this object is the developer's
responsibility.
Returns:
path (str): URI path to object detail page, if defined.
Examples:
```python
Oscar (Character) = '/characters/oscar/1/'
```
For this to work, the developer must have defined a named view somewhere
in urls.py that follows the format 'modelname-action', so in this case
a named view of 'character-detail' would be referenced by this method.
```python
url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/$',
CharDetailView.as_view(), name='character-detail')
```
If no View has been created and defined in urls.py, returns an
HTML anchor.
This method is naive and simply returns a path. Securing access to
the actual view and limiting who can view this object is the
developer's responsibility.
"""
try:
return reverse(
@ -878,25 +889,31 @@ class TypedObject(SharedMemoryModel):
Returns the URI path for a View that allows users to puppet a specific
object.
ex. Oscar (Character) = '/characters/oscar/1/puppet/'
For this to work, the developer must have defined a named view somewhere
in urls.py that follows the format 'modelname-action', so in this case
a named view of 'character-puppet' would be referenced by this method.
ex.
url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/puppet/$',
CharPuppetView.as_view(), name='character-puppet')
If no View has been created and defined in urls.py, returns an
HTML anchor.
This method is naive and simply returns a path. Securing access to
the actual view and limiting who can view this object is the developer's
responsibility.
Returns:
path (str): URI path to object puppet page, if defined.
str: URI path to object puppet page, if defined.
Examples:
```python
Oscar (Character) = '/characters/oscar/1/puppet/'
```
For this to work, the developer must have defined a named view somewhere
in urls.py that follows the format 'modelname-action', so in this case
a named view of 'character-puppet' would be referenced by this method.
```python
url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/puppet/$',
CharPuppetView.as_view(), name='character-puppet')
```
If no View has been created and defined in urls.py, returns an
HTML anchor.
This method is naive and simply returns a path. Securing access to
the actual view and limiting who can view this object is the developer's
responsibility.
"""
try:
@ -912,25 +929,31 @@ class TypedObject(SharedMemoryModel):
Returns the URI path for a View that allows users to update this
object.
ex. Oscar (Character) = '/characters/oscar/1/change/'
For this to work, the developer must have defined a named view somewhere
in urls.py that follows the format 'modelname-action', so in this case
a named view of 'character-update' would be referenced by this method.
ex.
url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/change/$',
CharUpdateView.as_view(), name='character-update')
If no View has been created and defined in urls.py, returns an
HTML anchor.
This method is naive and simply returns a path. Securing access to
the actual view and limiting who can modify objects is the developer's
responsibility.
Returns:
path (str): URI path to object update page, if defined.
str: URI path to object update page, if defined.
Examples:
```python
Oscar (Character) = '/characters/oscar/1/change/'
```
For this to work, the developer must have defined a named view somewhere
in urls.py that follows the format 'modelname-action', so in this case
a named view of 'character-update' would be referenced by this method.
```python
url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/change/$',
CharUpdateView.as_view(), name='character-update')
```
If no View has been created and defined in urls.py, returns an
HTML anchor.
This method is naive and simply returns a path. Securing access to
the actual view and limiting who can modify objects is the developer's
responsibility.
"""
try:
@ -945,26 +968,33 @@ class TypedObject(SharedMemoryModel):
"""
Returns the URI path for a View that allows users to delete this object.
ex. Oscar (Character) = '/characters/oscar/1/delete/'
For this to work, the developer must have defined a named view somewhere
in urls.py that follows the format 'modelname-action', so in this case
a named view of 'character-detail' would be referenced by this method.
ex.
url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/delete/$',
CharDeleteView.as_view(), name='character-delete')
If no View has been created and defined in urls.py, returns an
HTML anchor.
This method is naive and simply returns a path. Securing access to
the actual view and limiting who can delete this object is the developer's
responsibility.
Returns:
path (str): URI path to object deletion page, if defined.
Examples:
```python
Oscar (Character) = '/characters/oscar/1/delete/'
```
For this to work, the developer must have defined a named view
somewhere in urls.py that follows the format 'modelname-action', so
in this case a named view of 'character-detail' would be referenced
by this method.
```python
url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/delete/$',
CharDeleteView.as_view(), name='character-delete')
```
If no View has been created and defined in urls.py, returns an HTML
anchor.
This method is naive and simply returns a path. Securing access to
the actual view and limiting who can delete this object is the
developer's responsibility.
"""
try:
return reverse(

View file

@ -5,9 +5,12 @@ Use the codes defined in ANSIPARSER in your text
to apply colour to text according to the ANSI standard.
Examples:
This is |rRed text|n and this is normal again.
Mostly you should not need to call parse_ansi() explicitly;
```python
"This is |rRed text|n and this is normal again."
```
Mostly you should not need to call `parse_ansi()` explicitly;
it is run by Evennia just before returning data to/from the
user. Depreciated example forms are available by extending
the ansi mapping.
@ -982,13 +985,11 @@ class ANSIString(str, metaclass=ANSIMeta):
sep (str): The separator to split the string on.
reverse (boolean): Whether to split the string on the last
occurrence of the separator rather than the first.
Returns:
result (tuple):
prefix (ANSIString): The part of the string before the
separator
sep (ANSIString): The separator itself
postfix (ANSIString): The part of the string after the
separator.
ANSIString: The part of the string before the separator
ANSIString: The separator itself
ANSIString: The part of the string after the separator.
"""
if hasattr(sep, "_clean_string"):
@ -1288,18 +1289,21 @@ class ANSIString(str, metaclass=ANSIMeta):
one.
NOTE: This should always be used for joining strings when ANSIStrings
are involved. Otherwise color information will be discarded by
python, due to details in the C implementation of strings.
are involved. Otherwise color information will be discarded by python,
due to details in the C implementation of strings.
Args:
iterable (list of strings): A list of strings to join together
Returns:
result (ANSIString): A single string with all of the iterable's
contents concatenated, with this string between each. For
example:
ANSIString(', ').join(['up', 'right', 'left', 'down'])
...Would return:
ANSIString('up, right, left, down')
ANSIString: A single string with all of the iterable's
contents concatenated, with this string between each.
Examples:
::
>>> ANSIString(', ').join(['up', 'right', 'left', 'down'])
ANSIString('up, right, left, down')
"""
result = ANSIString("")

View file

@ -1,23 +1,21 @@
"""
This module contains the core methods for the Batch-command- and
Batch-code-processors respectively. In short, these are two different
ways to build a game world using a normal text-editor without having
to do so 'on the fly' in-game. They also serve as an automatic backup
so you can quickly recreate a world also after a server reset. The
functions in this module is meant to form the backbone of a system
called and accessed through game commands.
Batch-code-processors respectively. In short, these are two different ways to
build a game world using a normal text-editor without having to do so 'on the
fly' in-game. They also serve as an automatic backup so you can quickly
recreate a world also after a server reset. The functions in this module is
meant to form the backbone of a system called and accessed through game
commands.
The Batch-command processor is the simplest. It simply runs a list of
in-game commands in sequence by reading them from a text file. The
advantage of this is that the builder only need to remember the normal
in-game commands. They are also executing with full permission checks
etc, making it relatively safe for builders to use. The drawback is
that in-game there is really a builder-character walking around
building things, and it can be important to create rooms and objects
in the right order, so the character can move between them. Also
objects that affects players (such as mobs, dark rooms etc) will
affect the building character too, requiring extra care to turn
off/on.
The Batch-command processor is the simplest. It simply runs a list of in-game
commands in sequence by reading them from a text file. The advantage of this is
that the builder only need to remember the normal in-game commands. They are
also executing with full permission checks etc, making it relatively safe for
builders to use. The drawback is that in-game there is really a
builder-character walking around building things, and it can be important to
create rooms and objects in the right order, so the character can move between
them. Also objects that affects players (such as mobs, dark rooms etc) will
affect the building character too, requiring extra care to turn off/on.
The Batch-code processor is a more advanced system that accepts full
Python code, executing in chunks. The advantage of this is much more
@ -31,7 +29,7 @@ etc. You also need to know Python and Evennia's API. Hence it's
recommended that the batch-code processor is limited only to
superusers or highly trusted staff.
Batch-command processor file syntax
# Batch-command processor file syntax
The batch-command processor accepts 'batchcommand files' e.g
`batch.ev`, containing a sequence of valid Evennia commands in a
@ -41,64 +39,64 @@ had been run at the game prompt.
Each Evennia command must be delimited by a line comment to mark its
end.
```
#INSERT path.batchcmdfile - this as the first entry on a line will
import and run a batch.ev file in this position, as if it was
written in this file.
```
::
look
# delimiting comment
create/drop box
# another required comment
One can also inject another batchcmdfile:
::
#INSERT path.batchcmdfile
This way entire game worlds can be created and planned offline; it is
especially useful in order to create long room descriptions where a
real offline text editor is often much better than any online text
editor or prompt.
Example of batch.ev file:
----------------------------
## Example of batch.ev file:
```
# batch file
# all lines starting with # are comments; they also indicate
# that a command definition is over.
::
@create box
# batch file
# all lines starting with # are comments; they also indicate
# that a command definition is over.
# this comment ends the @create command.
create box
@set box/desc = A large box.
# this comment ends the @create command.
Inside are some scattered piles of clothing.
set box/desc = A large box.
Inside are some scattered piles of clothing.
It seems the bottom of the box is a bit loose.
It seems the bottom of the box is a bit loose.
# Again, this comment indicates the @set command is over. Note how
# the description could be freely added. Excess whitespace on a line
# is ignored. An empty line in the command definition is parsed as a \n
# (so two empty lines becomes a new paragraph).
# Again, this comment indicates the @set command is over. Note how
# the description could be freely added. Excess whitespace on a line
# is ignored. An empty line in the command definition is parsed as a \n
# (so two empty lines becomes a new paragraph).
@teleport #221
teleport #221
# (Assuming #221 is a warehouse or something.)
# (remember, this comment ends the @teleport command! Don'f forget it)
# (Assuming #221 is a warehouse or something.)
# (remember, this comment ends the @teleport command! Don'f forget it)
# Example of importing another file at this point.
#IMPORT examples.batch
# Example of importing another file at this point.
#IMPORT examples.batch
@drop box
drop box
# Done, the box is in the warehouse! (this last comment is not necessary to
# close the @drop command since it's the end of the file)
```
-------------------------
# Done, the box is in the warehouse! (this last comment is not necessary to
# close the drop command since it's the end of the file)
An example batch file is `contrib/examples/batch_example.ev`.
==========================================================================
Batch-code processor file syntax
# Batch-code processor file syntax
The Batch-code processor accepts full python modules (e.g. `batch.py`)
that looks identical to normal Python files. The difference from
@ -113,62 +111,61 @@ the code and re-run sections of it easily during development.
Code blocks are marked by commented tokens alone on a line:
#HEADER - This denotes code that should be pasted at the top of all
other code. Multiple HEADER statements - regardless of where
it exists in the file - is the same as one big block.
Observe that changes to variables made in one block is not
preserved between blocks!
#CODE - This designates a code block that will be executed like a
stand-alone piece of code together with any HEADER(s)
defined. It is mainly used as a way to mark stop points for
the interactive mode of the batchprocessor. If no CODE block
is defined in the module, the entire module (including HEADERS)
is assumed to be a CODE block.
#INSERT path.filename - This imports another batch_code.py file and
runs it in the given position. The inserted file will retain
its own HEADERs which will not be mixed with the headers of
this file.
- `#HEADER` - This denotes code that should be pasted at the top of all
other code. Multiple HEADER statements - regardless of where
it exists in the file - is the same as one big block.
Observe that changes to variables made in one block is not
preserved between blocks!
- `#CODE` - This designates a code block that will be executed like a
stand-alone piece of code together with any HEADER(s)
defined. It is mainly used as a way to mark stop points for
the interactive mode of the batchprocessor. If no CODE block
is defined in the module, the entire module (including HEADERS)
is assumed to be a CODE block.
- `#INSERT path.filename` - This imports another batch_code.py file and
runs it in the given position. The inserted file will retain
its own HEADERs which will not be mixed with the headers of
this file.
Importing works as normal. The following variables are automatically
made available in the script namespace.
- `caller` - The object executing the batchscript
- `caller` - The object executing the batchscript
- `DEBUG` - This is a boolean marking if the batchprocessor is running
in debug mode. It can be checked to e.g. delete created objects
when running a CODE block multiple times during testing.
(avoids creating a slew of same-named db objects)
## Example batch.py file
Example batch.py file
-----------------------------------
::
```
#HEADER
#HEADER
from django.conf import settings
from evennia.utils import create
from types import basetypes
from django.conf import settings
from evennia.utils import create
from types import basetypes
GOLD = 10
GOLD = 10
#CODE
#CODE
obj = create.create_object(basetypes.Object)
obj2 = create.create_object(basetypes.Object)
obj.location = caller.location
obj.db.gold = GOLD
caller.msg("The object was created!")
obj = create.create_object(basetypes.Object)
obj2 = create.create_object(basetypes.Object)
obj.location = caller.location
obj.db.gold = GOLD
caller.msg("The object was created!")
if DEBUG:
obj.delete()
obj2.delete()
if DEBUG:
obj.delete()
obj2.delete()
#INSERT another_batch_file
#INSERT another_batch_file
#CODE
#CODE
script = create.create_script()
script = create.create_script()
```
"""
import re
import codecs