mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
[#1928] PR feedback, documentation, error handling
This commit is contained in:
parent
186bc09b4d
commit
ba3db1731d
2 changed files with 77 additions and 32 deletions
|
|
@ -1570,7 +1570,7 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
set <obj>/<attr> = <value>
|
||||
set <obj>/<attr> =
|
||||
set <obj>/<attr>
|
||||
set *<account>/attr = <value>
|
||||
set *<account>/<attr> = <value>
|
||||
|
||||
Switch:
|
||||
edit: Open the line editor (string values only)
|
||||
|
|
@ -1585,7 +1585,7 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
Sets attributes on objects. The second example form above clears a
|
||||
previously set attribute while the third form inspects the current value of
|
||||
the attribute (if any). The last one (with the star) is a shortcut for
|
||||
operatin on a player Account rather than an Object.
|
||||
operating on a player Account rather than an Object.
|
||||
|
||||
The most common data to save with this command are strings and
|
||||
numbers. You can however also set Python primitives such as lists,
|
||||
|
|
@ -1593,8 +1593,10 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
the functionality of certain custom objects). This is indicated
|
||||
by you starting your value with one of |c'|n, |c"|n, |c(|n, |c[|n
|
||||
or |c{ |n.
|
||||
Note that you should leave a space after starting a dictionary ('{ ')
|
||||
so as to not confuse the dictionary start with a colour code like \{g.
|
||||
|
||||
Once you have stored a Python primative as noted above, you can include
|
||||
|c[<key>]|n in <attr> to reference nested values.
|
||||
|
||||
Remember that if you use Python primitives like this, you must
|
||||
write proper Python syntax too - notably you must include quotes
|
||||
around your strings or you will get an error.
|
||||
|
|
@ -1680,20 +1682,26 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
"""
|
||||
Look up the value of an attribute and return a string displaying it.
|
||||
"""
|
||||
nested = False
|
||||
for key, nested_keys in self.split_nested_attr(attr):
|
||||
nested = True
|
||||
if obj.attributes.has(key):
|
||||
val = obj.attributes.get(key)
|
||||
val = self.do_nested_lookup(val, *nested_keys)
|
||||
if val is not self.not_found:
|
||||
return "\nAttribute %s/%s = %s" % (obj.name, attr, val)
|
||||
else:
|
||||
return "\n%s has no attribute '%s'." % (obj.name, attr)
|
||||
error = "\n%s has no attribute '%s'." % (obj.name, attr)
|
||||
if nested:
|
||||
error += ' (Nested lookups attempted)'
|
||||
return error
|
||||
|
||||
def rm_attr(self, obj, attr):
|
||||
"""
|
||||
Remove an attribute from the object, or a nested data structure, and report back.
|
||||
"""
|
||||
nested = False
|
||||
for key, nested_keys in self.split_nested_attr(attr):
|
||||
nested = True
|
||||
if obj.attributes.has(key):
|
||||
if nested_keys:
|
||||
del_key = nested_keys[-1]
|
||||
|
|
@ -1709,7 +1717,10 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
exists = obj.attributes.has(key)
|
||||
obj.attributes.remove(attr)
|
||||
return "\nDeleted attribute '%s' (= %s) from %s." % (attr, exists, obj.name)
|
||||
return "\n%s has no attribute '%s'." % (obj.name, attr)
|
||||
error = "\n%s has no attribute '%s'." % (obj.name, attr)
|
||||
if nested:
|
||||
error += ' (Nested lookups attempted)'
|
||||
return error
|
||||
|
||||
def set_attr(self, obj, attr, value):
|
||||
done = False
|
||||
|
|
@ -1720,9 +1731,9 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
deep = self.do_nested_lookup(lookup_value, *nested_keys[:-1])
|
||||
if deep is not self.not_found:
|
||||
# To support appending and inserting to lists
|
||||
# a key that starts with @ will insert a new item at that
|
||||
# a key that starts with LIST_APPEND_CHAR will insert a new item at that
|
||||
# location, and move the other elements down.
|
||||
# Just '@' will append to the list
|
||||
# Using LIST_APPEND_CHAR alone will append to the list
|
||||
if isinstance(acc_key, str) and acc_key[0] == LIST_APPEND_CHAR:
|
||||
try:
|
||||
if len(acc_key) > 1:
|
||||
|
|
@ -1730,7 +1741,7 @@ class CmdSetAttribute(ObjManipCommand):
|
|||
deep.insert(where, value)
|
||||
else:
|
||||
deep.append(value)
|
||||
except AttributeError:
|
||||
except (ValueError, AttributeError):
|
||||
pass
|
||||
else:
|
||||
value = lookup_value
|
||||
|
|
|
|||
|
|
@ -545,40 +545,65 @@ class TestBuilding(CommandTest):
|
|||
self.call(building.CmdSetAttribute(), "Obj/test1[0]", "Attribute Obj/test1[0] = 99")
|
||||
# list delete
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/test1[0] =", "Deleted attribute 'test1[0]' (= nested) from Obj.")
|
||||
"Obj/test1[0] =",
|
||||
"Deleted attribute 'test1[0]' (= nested) from Obj.")
|
||||
self.call(building.CmdSetAttribute(), "Obj/test1[0]", "Attribute Obj/test1[0] = 2")
|
||||
self.call(building.CmdSetAttribute(), "Obj/test1[1]", "Obj has no attribute 'test1[1]'.")
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/test1[1]",
|
||||
"Obj has no attribute 'test1[1]'. (Nested lookups attempted)")
|
||||
# Delete non-existent
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/test1[5] =", "Obj has no attribute 'test1[5]'.")
|
||||
"Obj/test1[5] =",
|
||||
"Obj has no attribute 'test1[5]'. (Nested lookups attempted)")
|
||||
# Append
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/test1[+] = 42", "Modified attribute Obj/test1 = [2, 42]")
|
||||
"Obj/test1[+] = 42",
|
||||
"Modified attribute Obj/test1 = [2, 42]")
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/test1[+0] = -1", "Modified attribute Obj/test1 = [-1, 2, 42]")
|
||||
"Obj/test1[+0] = -1",
|
||||
"Modified attribute Obj/test1 = [-1, 2, 42]")
|
||||
|
||||
# dict - removing white space proves real parsing
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/test2={ 'one': 1, 'two': 2 }", "Created attribute Obj/test2 = {'one': 1, 'two': 2}")
|
||||
"Obj/test2={ 'one': 1, 'two': 2 }",
|
||||
"Created attribute Obj/test2 = {'one': 1, 'two': 2}")
|
||||
self.call(building.CmdSetAttribute(), "Obj/test2", "Attribute Obj/test2 = {'one': 1, 'two': 2}")
|
||||
self.call(building.CmdSetAttribute(), "Obj/test2['one']", "Attribute Obj/test2['one'] = 1")
|
||||
self.call(building.CmdSetAttribute(), "Obj/test2['one]", "Attribute Obj/test2['one] = 1")
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/test2['one']=99", "Modified attribute Obj/test2 = {'one': 99, 'two': 2}")
|
||||
"Obj/test2['one']=99",
|
||||
"Modified attribute Obj/test2 = {'one': 99, 'two': 2}")
|
||||
self.call(building.CmdSetAttribute(), "Obj/test2['one']", "Attribute Obj/test2['one'] = 99")
|
||||
self.call(building.CmdSetAttribute(), "Obj/test2['two']", "Attribute Obj/test2['two'] = 2")
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/test2['three']=3", "Modified attribute Obj/test2 = {'one': 99, 'two': 2, 'three': 3}")
|
||||
"Obj/test2[+'three']",
|
||||
"Obj has no attribute 'test2[+'three']'. (Nested lookups attempted)")
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/test2[+'three'] = 3",
|
||||
"Modified attribute Obj/test2 = {'one': 99, 'two': 2, \"+'three'\": 3}")
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/test2[+'three'] =",
|
||||
"Deleted attribute 'test2[+'three']' (= nested) from Obj.")
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/test2['three']=3",
|
||||
"Modified attribute Obj/test2 = {'one': 99, 'two': 2, 'three': 3}")
|
||||
# Dict delete
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/test2['two'] =", "Deleted attribute 'test2['two']' (= nested) from Obj.")
|
||||
self.call(building.CmdSetAttribute(), "Obj/test2['two']", "Obj has no attribute 'test2['two']'.")
|
||||
"Obj/test2['two'] =",
|
||||
"Deleted attribute 'test2['two']' (= nested) from Obj.")
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/test2['two']",
|
||||
"Obj has no attribute 'test2['two']'. (Nested lookups attempted)")
|
||||
self.call(building.CmdSetAttribute(), "Obj/test2", "Attribute Obj/test2 = {'one': 99, 'three': 3}")
|
||||
self.call(building.CmdSetAttribute(), "Obj/test2[0]", "Obj has no attribute 'test2[0]'.")
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/test2['five'] =", "Obj has no attribute 'test2['five']'.")
|
||||
"Obj/test2[0]",
|
||||
"Obj has no attribute 'test2[0]'. (Nested lookups attempted)")
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/test2[+]=42", "Modified attribute Obj/test2 = {'one': 99, 'three': 3, '+': 42}")
|
||||
"Obj/test2['five'] =",
|
||||
"Obj has no attribute 'test2['five']'. (Nested lookups attempted)")
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/test2[+]=42",
|
||||
"Modified attribute Obj/test2 = {'one': 99, 'three': 3, '+': 42}")
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/test2[+1]=33",
|
||||
"Modified attribute Obj/test2 = {'one': 99, 'three': 3, '+': 42, '+1': 33}")
|
||||
|
|
@ -586,31 +611,39 @@ class TestBuilding(CommandTest):
|
|||
# tuple
|
||||
self.call(building.CmdSetAttribute(), "Obj/tup = (1,2)", "Created attribute Obj/tup = (1, 2)")
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/tup[1] = 99", "'tuple' object does not support item assignment - (1, 2)")
|
||||
"Obj/tup[1] = 99",
|
||||
"'tuple' object does not support item assignment - (1, 2)")
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/tup[+] = 99", "'tuple' object does not support item assignment - (1, 2)")
|
||||
"Obj/tup[+] = 99",
|
||||
"'tuple' object does not support item assignment - (1, 2)")
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/tup[+1] = 99", "'tuple' object does not support item assignment - (1, 2)")
|
||||
"Obj/tup[+1] = 99",
|
||||
"'tuple' object does not support item assignment - (1, 2)")
|
||||
self.call(building.CmdSetAttribute(),
|
||||
# Special case for tuple, could have a better message
|
||||
"Obj/tup[1] = ", "Obj has no attribute 'tup[1]'.")
|
||||
"Obj/tup[1] = ",
|
||||
"Obj has no attribute 'tup[1]'. (Nested lookups attempted)")
|
||||
|
||||
# Deaper nesting
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/test3=[{'one': 1}]", "Created attribute Obj/test3 = [{'one': 1}]")
|
||||
"Obj/test3=[{'one': 1}]",
|
||||
"Created attribute Obj/test3 = [{'one': 1}]")
|
||||
self.call(building.CmdSetAttribute(), "Obj/test3[0]['one']", "Attribute Obj/test3[0]['one'] = 1")
|
||||
self.call(building.CmdSetAttribute(), "Obj/test3[0]", "Attribute Obj/test3[0] = {'one': 1}")
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/test3[0]['one'] =", "Deleted attribute 'test3[0]['one']' (= nested) from Obj.")
|
||||
"Obj/test3[0]['one'] =",
|
||||
"Deleted attribute 'test3[0]['one']' (= nested) from Obj.")
|
||||
self.call(building.CmdSetAttribute(), "Obj/test3[0]", "Attribute Obj/test3[0] = {}")
|
||||
self.call(building.CmdSetAttribute(), "Obj/test3", "Attribute Obj/test3 = [{}]")
|
||||
|
||||
# Naughty keys
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/test4[0]='foo'", "Created attribute Obj/test4[0] = 'foo'")
|
||||
"Obj/test4[0]='foo'",
|
||||
"Created attribute Obj/test4[0] = 'foo'")
|
||||
self.call(building.CmdSetAttribute(), "Obj/test4[0]", "Attribute Obj/test4[0] = foo")
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/test4=[{'one': 1}]", "Created attribute Obj/test4 = [{'one': 1}]")
|
||||
"Obj/test4=[{'one': 1}]",
|
||||
"Created attribute Obj/test4 = [{'one': 1}]")
|
||||
self.call(building.CmdSetAttribute(), "Obj/test4[0]['one']", "Attribute Obj/test4[0]['one'] = 1")
|
||||
# Prefer nested items
|
||||
self.call(building.CmdSetAttribute(), "Obj/test4[0]", "Attribute Obj/test4[0] = {'one': 1}")
|
||||
|
|
@ -619,7 +652,8 @@ class TestBuilding(CommandTest):
|
|||
self.call(building.CmdWipe(), "Obj/test4", "Wiped attributes test4 on Obj.")
|
||||
self.call(building.CmdSetAttribute(), "Obj/test4[0]", "Attribute Obj/test4[0] = foo")
|
||||
self.call(building.CmdSetAttribute(),
|
||||
"Obj/test4[0]['one']", "Obj has no attribute 'test4[0]['one']'.")
|
||||
"Obj/test4[0]['one']",
|
||||
"Obj has no attribute 'test4[0]['one']'.")
|
||||
|
||||
def test_split_nested_attr(self):
|
||||
split_nested_attr = building.CmdSetAttribute().split_nested_attr
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue