mirror of
https://github.com/evennia/evennia.git
synced 2026-04-04 15:07:16 +02:00
Fixes @set to be more accepting of various Python structures. It will now instead convert to string on a ValueError (commonly because a string was not enclosed in quotes) while giving a error string to the user informing of this. This should fix Issue 256.
This commit is contained in:
parent
23ba17debe
commit
a30029472b
1 changed files with 33 additions and 16 deletions
|
|
@ -19,6 +19,13 @@ __all__ = ("ObjManipCommand", "CmdSetObjAlias", "CmdCopy",
|
|||
"CmdLock", "CmdExamine", "CmdFind", "CmdTeleport",
|
||||
"CmdScript")
|
||||
|
||||
try:
|
||||
# used by @set
|
||||
from ast import literal_eval as _LITERAL_EVAL
|
||||
except ImportError:
|
||||
# literal_eval is not available before Python 2.6
|
||||
_LITERAL_EVAL = None
|
||||
|
||||
# used by @find
|
||||
CHAR_TYPECLASS = settings.BASE_CHARACTER_TYPECLASS
|
||||
|
||||
|
|
@ -1176,11 +1183,19 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
def convert_from_string(self, strobj):
|
||||
"""
|
||||
Converts a single object in *string form* to its equivalent python
|
||||
type. Handles floats, ints, and limited nested lists and dicts
|
||||
type.
|
||||
|
||||
Python earlier than 2.6:
|
||||
Handles floats, ints, and limited nested lists and dicts
|
||||
(can't handle lists in a dict, for example, this is mainly due to
|
||||
the complexity of parsing this rather than any technical difficulty -
|
||||
if there is a need for @set-ing such complex structures on the
|
||||
command line we might consider adding it).
|
||||
Python 2.6 and later:
|
||||
Supports all Python structures through literal_eval as long as they
|
||||
are valid Python syntax. If they are not (such as [test, test2], ie
|
||||
withtout the quotes around the strings), the entire structure will
|
||||
be converted to a string and a warning will be given.
|
||||
|
||||
We need to convert like this since all data being sent over the
|
||||
telnet connection by the Player is text - but we will want to
|
||||
|
|
@ -1191,7 +1206,8 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
|
||||
def rec_convert(obj):
|
||||
"""
|
||||
Helper function of recursive conversion calls.
|
||||
Helper function of recursive conversion calls. This is only
|
||||
used for Python <=2.5. After that literal_eval is available.
|
||||
"""
|
||||
# simple types
|
||||
try: return int(obj)
|
||||
|
|
@ -1211,18 +1227,20 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
for pair in obj[1:-1].split(',') if ":" in pair])
|
||||
# if nothing matches, return as-is
|
||||
return obj
|
||||
if strobj.strip() and strobj.strip()[0] in ("'", '"', "(", "{ ", "["):
|
||||
# this is a structure starting with a proper python structure,
|
||||
# so treat it as such.
|
||||
|
||||
if _LITERAL_EVAL:
|
||||
# Use literal_eval to parse python structure exactly.
|
||||
try:
|
||||
# under python 2.6, literal_eval can do this for us.
|
||||
from ast import literal_eval
|
||||
return literal_eval(strobj)
|
||||
except ImportError:
|
||||
# fall back to old recursive solution (don't support nested lists/dicts)
|
||||
return rec_convert(strobj.strip())
|
||||
return _LITERAL_EVAL(strobj)
|
||||
except ValueError:
|
||||
# treat as string
|
||||
string = "{RNote: Value was converted to string. If you don't want this, "
|
||||
string += "use proper Python syntax, like enclosing strings in quotes.{n"
|
||||
self.caller.msg(string)
|
||||
return utils.to_str(strobj)
|
||||
else:
|
||||
return strobj
|
||||
# fall back to old recursive solution (does not support nested lists/dicts)
|
||||
return rec_convert(strobj.strip())
|
||||
|
||||
def func(self):
|
||||
"Implement the set attribute - a limited form of @py."
|
||||
|
|
@ -1272,10 +1290,9 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
string += "\nCreated attribute %s/%s = %s" % (obj.name, attr, value)
|
||||
except SyntaxError:
|
||||
# this means literal_eval tried to parse a faulty string
|
||||
string = "{RPython syntax error in your value. By assigning a value starting with"
|
||||
string += "\none of {r'{R, {r\"{R, {r[{R, {r({R or {r{{R we assume you are entering a proper Python"
|
||||
string += "\nprimitive such as a list or a dictionary. You must then also use correct"
|
||||
string += "\nPython syntax. Remember especially to put quotes around all strings.{n"
|
||||
string = "{RCritical Python syntax error in your value. Only primitive Python structures"
|
||||
string += "\nare allowed. You also need to use correct Python syntax. Remember especially"
|
||||
string += "\nto put quotes around all strings inside lists and dicts.{n"
|
||||
# send feedback
|
||||
caller.msg(string.strip('\n'))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue