Make @lazy_property handlers read/write protected to avoid common newbie mistakes, like assigning obj.locks = []

This commit is contained in:
Griatch 2021-10-09 14:33:40 +02:00
parent a7b99a605b
commit 71092f17f7
2 changed files with 23 additions and 1 deletions

View file

@ -95,6 +95,9 @@ Up requirements to Django 3.2+, Twisted 21+
- Add validation question to default account creation.
- Add `LOCALECHO` client option to add server-side echo for clients that does
not support this (useful for getting a complete log).
- Make `@lazy_property` decorator create read/delete-protected properties. This is
because it's used for handlers, and e.g. self.locks=[] is a common beginner mistake.
### Evennia 0.9.5 (2019-2020)

View file

@ -2064,7 +2064,8 @@ class lazy_property:
```
Once initialized, the `AttributeHandler` will be available as a
property "attributes" on the object.
property "attributes" on the object. This is read-only since
this functionality is pretty much exclusively used by handlers.
"""
@ -2085,6 +2086,24 @@ class lazy_property:
obj.__dict__[self.__name__] = value
return value
def __set__(self, obj, value):
"""Protect against setting"""
handlername = self.__name__
raise AttributeError(
_("{obj}.{handlername} is a handler and can't be set directly. "
"To add values, use `{obj}.{handlername}.add()` instead.").format(
obj=obj, handlername=handlername)
)
def __delete__(self, obj):
"""Protect against deleting"""
handlername = self.__name__
raise AttributeError(
_("{obj}.{handlername} is a handler and can't be deleted directly. "
"To remove values, use `{obj}.{handlername}.remove()` instead.").format(
obj=obj, handlername=handlername)
)
_STRIP_ANSI = None
_RE_CONTROL_CHAR = re.compile(