Lots of bug fixes, still issues in prototype-update from menu

This commit is contained in:
Griatch 2018-09-21 00:05:23 +02:00
parent 0a86618fd8
commit bed96328a9
4 changed files with 60 additions and 20 deletions

View file

@ -350,12 +350,14 @@ def set_trace(debugger="auto", term_size=(140, 40)):
"""
import sys
dbg = None
pudb_mode = False
if debugger in ('auto', 'pudb'):
try:
from pudb import debugger
dbg = debugger.Debugger(stdout=sys.__stdout__,
term_size=term_size)
pudb_mode = True
except ImportError:
if debugger == 'pudb':
raise
@ -364,7 +366,12 @@ def set_trace(debugger="auto", term_size=(140, 40)):
if not dbg:
import pdb
dbg = pdb.Pdb(stdout=sys.__stdout__)
pudb_mode = False
# Start debugger, forcing it up one stack frame (otherwise `set_trace` will start # debugger at
# this point, not the actual code location)
dbg.set_trace(sys._getframe().f_back)
if pudb_mode:
# Stopped at breakpoint. Press 'n' to continue into the code.
dbg.set_trace()
else:
# Start debugger, forcing it up one stack frame (otherwise `set_trace` will start debugger
# this point, not the actual code location)
dbg.set_trace(sys._getframe().f_back)

View file

@ -200,9 +200,8 @@ def _wizard_options(curr_node, prev_node, next_node, color="|W", search=False):
color=color, node=next_node.replace("_", "-")),
"goto": "node_{}".format(next_node)})
if "index" not in (prev_node, next_node):
options.append({"key": ("|wI|Wndex", "i"),
"goto": "node_index"})
options.append({"key": ("|wI|Wndex", "i"),
"goto": "node_index"})
if curr_node:
options.append({"key": ("|wV|Walidate prototype", "validate", "v"),
@ -319,7 +318,7 @@ def _get_current_value(caller, keyname, comparer=None, formatter=str, only_inher
if keyname in flat_prot:
out = formatter(comparer(prot[keyname], flat_prot[keyname]))
if only_inherit:
if out:
if str(out).strip():
return "|WCurrent|n {} |W(|binherited|W):|n {}".format(keyname, out)
return ""
else:
@ -1953,14 +1952,12 @@ def _keep_diff(caller, **kwargs):
tmp[path[-1]] = "KEEP"
def _format_diff_text_and_options(diff, exclude=None):
def _format_diff_text_and_options(diff):
"""
Reformat the diff in a way suitable for the olc menu.
Args:
diff (dict): A diff as produced by `prototype_diff`.
exclude (list, optional): List of root keys to skip, regardless
of diff instruction.
Returns:
options (list): List of options dict.
@ -2051,8 +2048,7 @@ def node_apply_diff(caller, **kwargs):
base_obj = choice(update_objects)
# from evennia import set_trace
diff, obj_prototype = spawner.prototype_diff_from_object(
prototype, base_obj, exceptions={"location": "KEEP"})
diff, obj_prototype = spawner.prototype_diff_from_object(prototype, base_obj)
helptext = """
This will go through all existing objects and apply the changes you accept.
@ -2069,7 +2065,10 @@ def node_apply_diff(caller, **kwargs):
Note that the `location` will never be auto-adjusted because it's so rare to want to
homogenize the location of all object instances."""
txt, options = _format_diff_text_and_options(diff, exclude=['location'] if custom_location else None)
if not custom_location:
diff.pop("location", None)
txt, options = _format_diff_text_and_options(diff)
if options:
text = ["Suggested changes to {} objects. ".format(len(update_objects)),
@ -2261,7 +2260,7 @@ def node_prototype_spawn(caller, **kwargs):
options.append(
{"desc": "Spawn in prototype's defined location ({loc})".format(loc=location),
"goto": (_spawn,
dict(prototype=prototype))})
dict(prototype=prototype, location=location, custom_location=True))})
caller_loc = caller.location
if location != caller_loc:
options.append(

View file

@ -16,7 +16,7 @@ from evennia.utils.utils import (
get_all_typeclasses, to_str, dbref, justify)
from evennia.locks.lockhandler import validate_lockstring, check_lockstring
from evennia.utils import logger
from evennia.utils import inlinefuncs
from evennia.utils import inlinefuncs, dbserialize
from evennia.utils.evtable import EvTable
@ -102,9 +102,18 @@ class DbPrototype(DefaultScript):
"""
def at_script_creation(self):
self.key = "empty prototype" # prototype_key
self.desc = "A prototype" # prototype_desc
self.desc = "A prototype" # prototype_desc (.tags are used for prototype_tags)
self.db.prototype = {} # actual prototype
@property
def prototype(self):
"Make sure to decouple from db!"
return dbserialize.deserialize(self.attributes.get('prototype', {}))
@prototype.setter
def prototype(self, prototype):
self.attributes.add('prototype', prototype)
# Prototype manager functions
@ -152,7 +161,7 @@ def save_prototype(**kwargs):
# make sure meta properties are included with defaults
stored_prototype = DbPrototype.objects.filter(db_key=prototype_key)
prototype = dict(stored_prototype[0].db.prototype) if stored_prototype else {}
prototype = stored_prototype[0].prototype if stored_prototype else {}
kwargs['prototype_desc'] = kwargs.get("prototype_desc", prototype.get("prototype_desc", ""))
prototype_locks = kwargs.get(
@ -185,7 +194,7 @@ def save_prototype(**kwargs):
DbPrototype, key=prototype_key, desc=prototype['prototype_desc'], persistent=True,
locks=prototype_locks, tags=prototype['prototype_tags'],
attributes=[("prototype", prototype)])
return stored_prototype.db.prototype
return stored_prototype.prototype
create_prototype = save_prototype # alias
@ -279,7 +288,7 @@ def search_prototype(key=None, tags=None):
# exact or partial match on key
db_matches = db_matches.filter(db_key=key) or db_matches.filter(db_key__icontains=key)
# return prototype
db_prototypes = [dict(dbprot.attributes.get("prototype", {})) for dbprot in db_matches]
db_prototypes = [dbprot.prototype for dbprot in db_matches]
matches = db_prototypes + module_prototypes
nmatches = len(matches)

View file

@ -29,7 +29,7 @@ except ImportError:
from pickle import dumps, loads
from django.core.exceptions import ObjectDoesNotExist
from django.contrib.contenttypes.models import ContentType
from evennia.utils.utils import to_str, uses_database
from evennia.utils.utils import to_str, uses_database, is_iter
from evennia.utils import logger
__all__ = ("to_pickle", "from_pickle", "do_pickle", "do_unpickle",
@ -364,6 +364,31 @@ class _SaverDeque(_SaverMutable):
def rotate(self, *args):
self._data.rotate(*args)
_DESERIALIZE_MAPPING = {_SaverList.__name__: list, _SaverDict.__name__: dict,
_SaverSet.__name__: set, _SaverOrderedDict.__name__: OrderedDict,
_SaverDeque.__name__: deque}
def deserialize(obj):
"""
Make sure to *fully* decouple a structure from the database, by turning all _Saver*-mutables
inside it back into their normal Python forms.
"""
def _iter(obj):
typ = type(obj)
tname = typ.__name__
if tname in ('_SaverDict', 'dict'):
return {_iter(key): _iter(val) for key, val in obj.items()}
elif tname in _DESERIALIZE_MAPPING:
return _DESERIALIZE_MAPPING[tname](_iter(val) for val in obj)
elif is_iter(obj):
return typ(_iter(val) for val in obj)
return obj
return _iter(obj)
#
# serialization helpers