Change validation syntax, spawn mechanism not working

This commit is contained in:
Griatch 2018-03-10 14:43:11 +01:00
parent ed355e6096
commit 610399e233
2 changed files with 33 additions and 14 deletions

View file

@ -14,7 +14,7 @@ from evennia.utils.utils import inherits_from, class_from_module
from evennia.utils.eveditor import EvEditor
from evennia.utils.evmore import EvMore
from evennia.utils.spawner import (spawn, search_prototype, list_prototypes,
store_prototype, build_metaproto)
store_prototype, build_metaproto, validate_prototype)
from evennia.utils.ansi import raw
COMMAND_DEFAULT_CLASS = class_from_module(settings.COMMAND_DEFAULT_CLASS)
@ -2806,6 +2806,11 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
self.caller.msg("Spawn aborted: You don't have access to "
"use the 'exec' prototype key.")
return None
try:
validate_prototype(prototype)
except RuntimeError as err:
self.caller.msg(str(err))
return
return prototype
def _search_show_prototype(query, metaprots=None):

View file

@ -370,7 +370,7 @@ def list_prototypes(caller, key=None, tags=None, show_non_use=False, show_non_ed
prototypes = [(prototype.key, prototype.desc,
"{}/{}".format('Y' if prototype.access(caller, "use") else 'N',
'Y' if prototype.access(caller, "edit") else 'N'),
",".join(prototype.tags.get(category="persistent_prototype")))
",".join(prototype.tags.get(category="persistent_prototype", return_list=True)))
for prototype in sorted(prototypes, key=lambda o: o.key)]
prototypes = prototypes + readonly_prototypes
@ -403,32 +403,45 @@ def _handle_dbref(inp):
return dbid_to_obj(inp, ObjectDB)
def _validate_prototype(key, prototype, protparents, visited):
def validate_prototype(prototype, protkey=None, protparents=None, _visited=None):
"""
Run validation on a prototype, checking for inifinite regress.
Args:
prototype (dict): Prototype to validate.
protkey (str, optional): The name of the prototype definition, if any.
protpartents (dict, optional): The available prototype parent library. If
note given this will be determined from settings/database.
_visited (list, optional): This is an internal work array and should not be set manually.
Raises:
RuntimeError: If prototype has invalid structure.
"""
print("validate_prototype {}, {}, {}, {}".format(key, prototype, protparents, visited))
print("validate_prototype {}, {}, {}, {}".format(protkey, prototype, protparents, _visited))
if not protparents:
protparents = get_protparents()
if _visited is None:
_visited = []
assert isinstance(prototype, dict)
if id(prototype) in visited:
raise RuntimeError("%s has infinite nesting of prototypes." % key or prototype)
visited.append(id(prototype))
if id(prototype) in _visited:
raise RuntimeError("%s has infinite nesting of prototypes." % protkey or prototype)
_visited.append(id(prototype))
protstrings = prototype.get("prototype")
if protstrings:
for protstring in make_iter(protstrings):
if key is not None and protstring == key:
raise RuntimeError("%s tries to prototype itself." % key or prototype)
if protkey is not None and protstring == protkey:
raise RuntimeError("%s tries to prototype itself." % protkey or prototype)
protparent = protparents.get(protstring)
if not protparent:
raise RuntimeError(
"%s's prototype '%s' was not found." % (key or prototype, protstring))
_validate_prototype(protstring, protparent, protparents, visited)
"%s's prototype '%s' was not found." % (protkey or prototype, protstring))
validate_prototype(protparent, protstring, protparents, _visited)
def _get_prototype(dic, prot, protparents):
"""
Recursively traverse a prototype dictionary, including multiple
inheritance. Use _validate_prototype before this, we don't check
inheritance. Use validate_prototype before this, we don't check
for infinite recursion here.
"""
@ -509,6 +522,7 @@ def _batch_create_object(*objparams):
objs.append(obj)
return objs
def spawn(*prototypes, **kwargs):
"""
Spawn a number of prototyped objects.
@ -535,7 +549,7 @@ def spawn(*prototypes, **kwargs):
# overload module's protparents with specifically given protparents
protparents.update(kwargs.get("prototype_parents", {}))
for key, prototype in protparents.items():
_validate_prototype(key.lower(), prototype, protparents, [])
validate_prototype(prototype, key.lower(), protparents)
if "return_prototypes" in kwargs:
# only return the parents
@ -544,7 +558,7 @@ def spawn(*prototypes, **kwargs):
objsparams = []
for prototype in prototypes:
_validate_prototype(None, prototype, protparents, [])
validate_prototype(prototype, None, protparents)
prot = _get_prototype(prototype, {}, protparents)
if not prot:
continue