Format code with black. Add makefile to run fmt/tests
This commit is contained in:
parent
d00bce9288
commit
c2c7fa311a
299 changed files with 19037 additions and 11611 deletions
|
|
@ -44,12 +44,10 @@ from evennia.server.signals import SIGNAL_TYPED_OBJECT_POST_RENAME
|
|||
|
||||
from evennia.typeclasses import managers
|
||||
from evennia.locks.lockhandler import LockHandler
|
||||
from evennia.utils.utils import (
|
||||
is_iter, inherits_from, lazy_property,
|
||||
class_from_module)
|
||||
from evennia.utils.utils import is_iter, inherits_from, lazy_property, class_from_module
|
||||
from evennia.utils.logger import log_trace
|
||||
|
||||
__all__ = ("TypedObject", )
|
||||
__all__ = ("TypedObject",)
|
||||
|
||||
TICKER_HANDLER = None
|
||||
|
||||
|
|
@ -61,6 +59,7 @@ _SA = object.__setattr__
|
|||
|
||||
# signal receivers. Connected in __new__
|
||||
|
||||
|
||||
def call_at_first_save(sender, instance, created, **kwargs):
|
||||
"""
|
||||
Receives a signal just after the object is saved.
|
||||
|
|
@ -107,9 +106,11 @@ class TypeclassBase(SharedMemoryModelBase):
|
|||
|
||||
# typeclass proxy setup
|
||||
if "Meta" not in attrs:
|
||||
|
||||
class Meta(object):
|
||||
proxy = True
|
||||
app_label = attrs.get("__applabel__", "typeclasses")
|
||||
|
||||
attrs["Meta"] = Meta
|
||||
attrs["Meta"].proxy = True
|
||||
|
||||
|
|
@ -124,27 +125,29 @@ class TypeclassBase(SharedMemoryModelBase):
|
|||
class DbHolder(object):
|
||||
"Holder for allowing property access of attributes"
|
||||
|
||||
def __init__(self, obj, name, manager_name='attributes'):
|
||||
def __init__(self, obj, name, manager_name="attributes"):
|
||||
_SA(self, name, _GA(obj, manager_name))
|
||||
_SA(self, 'name', name)
|
||||
_SA(self, "name", name)
|
||||
|
||||
def __getattribute__(self, attrname):
|
||||
if attrname == 'all':
|
||||
if attrname == "all":
|
||||
# we allow to overload our default .all
|
||||
attr = _GA(self, _GA(self, 'name')).get("all")
|
||||
attr = _GA(self, _GA(self, "name")).get("all")
|
||||
return attr if attr else _GA(self, "all")
|
||||
return _GA(self, _GA(self, 'name')).get(attrname)
|
||||
return _GA(self, _GA(self, "name")).get(attrname)
|
||||
|
||||
def __setattr__(self, attrname, value):
|
||||
_GA(self, _GA(self, 'name')).add(attrname, value)
|
||||
_GA(self, _GA(self, "name")).add(attrname, value)
|
||||
|
||||
def __delattr__(self, attrname):
|
||||
_GA(self, _GA(self, 'name')).remove(attrname)
|
||||
_GA(self, _GA(self, "name")).remove(attrname)
|
||||
|
||||
def get_all(self):
|
||||
return _GA(self, _GA(self, 'name')).all()
|
||||
return _GA(self, _GA(self, "name")).all()
|
||||
|
||||
all = property(get_all)
|
||||
|
||||
|
||||
#
|
||||
# Main TypedObject abstraction
|
||||
#
|
||||
|
|
@ -180,21 +183,32 @@ class TypedObject(SharedMemoryModel):
|
|||
|
||||
# Main identifier of the object, for searching. Is accessed with self.key
|
||||
# or self.name
|
||||
db_key = models.CharField('key', max_length=255, db_index=True)
|
||||
db_key = models.CharField("key", max_length=255, db_index=True)
|
||||
# This is the python path to the type class this object is tied to. The
|
||||
# typeclass is what defines what kind of Object this is)
|
||||
db_typeclass_path = models.CharField('typeclass', max_length=255, null=True,
|
||||
help_text="this defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass.")
|
||||
db_typeclass_path = models.CharField(
|
||||
"typeclass",
|
||||
max_length=255,
|
||||
null=True,
|
||||
help_text="this defines what 'type' of entity this is. This variable holds a Python path to a module with a valid Evennia Typeclass.",
|
||||
)
|
||||
# Creation date. This is not changed once the object is created.
|
||||
db_date_created = models.DateTimeField('creation date', editable=False, auto_now_add=True)
|
||||
db_date_created = models.DateTimeField("creation date", editable=False, auto_now_add=True)
|
||||
# Lock storage
|
||||
db_lock_storage = models.TextField('locks', blank=True,
|
||||
help_text="locks limit access to an entity. A lock is defined as a 'lock string' on the form 'type:lockfunctions', defining what functionality is locked and how to determine access. Not defining a lock means no access is granted.")
|
||||
db_lock_storage = models.TextField(
|
||||
"locks",
|
||||
blank=True,
|
||||
help_text="locks limit access to an entity. A lock is defined as a 'lock string' on the form 'type:lockfunctions', defining what functionality is locked and how to determine access. Not defining a lock means no access is granted.",
|
||||
)
|
||||
# many2many relationships
|
||||
db_attributes = models.ManyToManyField(Attribute,
|
||||
help_text='attributes on this object. An attribute can hold any pickle-able python object (see docs for special cases).')
|
||||
db_tags = models.ManyToManyField(Tag,
|
||||
help_text='tags on this object. Tags are simple string markers to identify, group and alias objects.')
|
||||
db_attributes = models.ManyToManyField(
|
||||
Attribute,
|
||||
help_text="attributes on this object. An attribute can hold any pickle-able python object (see docs for special cases).",
|
||||
)
|
||||
db_tags = models.ManyToManyField(
|
||||
Tag,
|
||||
help_text="tags on this object. Tags are simple string markers to identify, group and alias objects.",
|
||||
)
|
||||
|
||||
# Database manager
|
||||
objects = managers.TypedObjectManager()
|
||||
|
|
@ -207,7 +221,9 @@ class TypedObject(SharedMemoryModel):
|
|||
def set_class_from_typeclass(self, typeclass_path=None):
|
||||
if typeclass_path:
|
||||
try:
|
||||
self.__class__ = class_from_module(typeclass_path, defaultpaths=settings.TYPECLASS_PATHS)
|
||||
self.__class__ = class_from_module(
|
||||
typeclass_path, defaultpaths=settings.TYPECLASS_PATHS
|
||||
)
|
||||
except Exception:
|
||||
log_trace()
|
||||
try:
|
||||
|
|
@ -241,7 +257,10 @@ class TypedObject(SharedMemoryModel):
|
|||
self.__class__ = class_from_module("evennia.objects.objects.DefaultObject")
|
||||
self.__dbclass__ = class_from_module("evennia.objects.models.ObjectDB")
|
||||
self.db_typeclass_path = "evennia.objects.objects.DefaultObject"
|
||||
log_trace("Critical: Class %s of %s is not a valid typeclass!\nTemporarily falling back to %s." % (err_class, self, self.__class__))
|
||||
log_trace(
|
||||
"Critical: Class %s of %s is not a valid typeclass!\nTemporarily falling back to %s."
|
||||
% (err_class, self, self.__class__)
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""
|
||||
|
|
@ -307,9 +326,10 @@ class TypedObject(SharedMemoryModel):
|
|||
"""
|
||||
Django setup info.
|
||||
"""
|
||||
|
||||
abstract = True
|
||||
verbose_name = "Evennia Database Object"
|
||||
ordering = ['-db_date_created', 'id', 'db_typeclass_path', 'db_key']
|
||||
ordering = ["-db_date_created", "id", "db_typeclass_path", "db_key"]
|
||||
|
||||
# wrapper
|
||||
# Wrapper properties to easily set database fields. These are
|
||||
|
|
@ -329,6 +349,7 @@ class TypedObject(SharedMemoryModel):
|
|||
|
||||
def __name_del(self):
|
||||
raise Exception("Cannot delete name")
|
||||
|
||||
name = property(__name_get, __name_set, __name_del)
|
||||
|
||||
# key property (overrides's the idmapper's db_key for the at_rename hook)
|
||||
|
|
@ -366,7 +387,7 @@ class TypedObject(SharedMemoryModel):
|
|||
def __repr__(self):
|
||||
return "%s" % self.db_key
|
||||
|
||||
#@property
|
||||
# @property
|
||||
def __dbid_get(self):
|
||||
"""
|
||||
Caches and returns the unique id of the object.
|
||||
|
|
@ -379,9 +400,10 @@ class TypedObject(SharedMemoryModel):
|
|||
|
||||
def __dbid_del(self):
|
||||
raise Exception("dbid cannot be deleted!")
|
||||
|
||||
dbid = property(__dbid_get, __dbid_set, __dbid_del)
|
||||
|
||||
#@property
|
||||
# @property
|
||||
def __dbref_get(self):
|
||||
"""
|
||||
Returns the object's dbref on the form #NN.
|
||||
|
|
@ -393,6 +415,7 @@ class TypedObject(SharedMemoryModel):
|
|||
|
||||
def __dbref_del(self):
|
||||
raise Exception("dbref cannot be deleted!")
|
||||
|
||||
dbref = property(__dbref_get, __dbref_set, __dbref_del)
|
||||
|
||||
def at_idmapper_flush(self):
|
||||
|
|
@ -455,7 +478,9 @@ class TypedObject(SharedMemoryModel):
|
|||
|
||||
"""
|
||||
if isinstance(typeclass, str):
|
||||
typeclass = [typeclass] + ["%s.%s" % (prefix, typeclass) for prefix in settings.TYPECLASS_PATHS]
|
||||
typeclass = [typeclass] + [
|
||||
"%s.%s" % (prefix, typeclass) for prefix in settings.TYPECLASS_PATHS
|
||||
]
|
||||
else:
|
||||
typeclass = [typeclass.path]
|
||||
|
||||
|
|
@ -465,10 +490,18 @@ class TypedObject(SharedMemoryModel):
|
|||
return selfpath in typeclass
|
||||
else:
|
||||
# check parent chain
|
||||
return any(hasattr(cls, "path") and cls.path in typeclass for cls in self.__class__.mro())
|
||||
return any(
|
||||
hasattr(cls, "path") and cls.path in typeclass for cls in self.__class__.mro()
|
||||
)
|
||||
|
||||
def swap_typeclass(self, new_typeclass, clean_attributes=False,
|
||||
run_start_hooks="all", no_default=True, clean_cmdsets=False):
|
||||
def swap_typeclass(
|
||||
self,
|
||||
new_typeclass,
|
||||
clean_attributes=False,
|
||||
run_start_hooks="all",
|
||||
no_default=True,
|
||||
clean_cmdsets=False,
|
||||
):
|
||||
"""
|
||||
This performs an in-situ swap of the typeclass. This means
|
||||
that in-game, this object will suddenly be something else.
|
||||
|
|
@ -513,9 +546,11 @@ class TypedObject(SharedMemoryModel):
|
|||
|
||||
if inherits_from(self, "evennia.scripts.models.ScriptDB"):
|
||||
if self.interval > 0:
|
||||
raise RuntimeError("Cannot use swap_typeclass on time-dependent "
|
||||
"Script '%s'.\nStop and start a new Script of the "
|
||||
"right type instead." % self.key)
|
||||
raise RuntimeError(
|
||||
"Cannot use swap_typeclass on time-dependent "
|
||||
"Script '%s'.\nStop and start a new Script of the "
|
||||
"right type instead." % self.key
|
||||
)
|
||||
|
||||
self.typeclass_path = new_typeclass.path
|
||||
self.__class__ = new_typeclass
|
||||
|
|
@ -536,7 +571,7 @@ class TypedObject(SharedMemoryModel):
|
|||
self.cmdset.clear()
|
||||
self.cmdset.remove_default()
|
||||
|
||||
if run_start_hooks == 'all':
|
||||
if run_start_hooks == "all":
|
||||
# fake this call to mimic the first save
|
||||
self.at_first_save()
|
||||
elif run_start_hooks:
|
||||
|
|
@ -547,7 +582,9 @@ class TypedObject(SharedMemoryModel):
|
|||
# Lock / permission methods
|
||||
#
|
||||
|
||||
def access(self, accessing_obj, access_type='read', default=False, no_superuser_bypass=False, **kwargs):
|
||||
def access(
|
||||
self, accessing_obj, access_type="read", default=False, no_superuser_bypass=False, **kwargs
|
||||
):
|
||||
"""
|
||||
Determines if another object has permission to access this one.
|
||||
|
||||
|
|
@ -565,8 +602,12 @@ class TypedObject(SharedMemoryModel):
|
|||
use it to feed to its hook methods.
|
||||
|
||||
"""
|
||||
return self.locks.check(accessing_obj, access_type=access_type, default=default,
|
||||
no_superuser_bypass=no_superuser_bypass)
|
||||
return self.locks.check(
|
||||
accessing_obj,
|
||||
access_type=access_type,
|
||||
default=default,
|
||||
no_superuser_bypass=no_superuser_bypass,
|
||||
)
|
||||
|
||||
def check_permstring(self, permstring):
|
||||
"""
|
||||
|
|
@ -581,7 +622,11 @@ class TypedObject(SharedMemoryModel):
|
|||
|
||||
"""
|
||||
if hasattr(self, "account"):
|
||||
if self.account and self.account.is_superuser and not self.account.attributes.get("_quell"):
|
||||
if (
|
||||
self.account
|
||||
and self.account.is_superuser
|
||||
and not self.account.attributes.get("_quell")
|
||||
):
|
||||
return True
|
||||
else:
|
||||
if self.is_superuser and not self.attributes.get("_quell"):
|
||||
|
|
@ -597,8 +642,11 @@ class TypedObject(SharedMemoryModel):
|
|||
if perm in _PERMISSION_HIERARCHY:
|
||||
# check if we have a higher hierarchy position
|
||||
ppos = _PERMISSION_HIERARCHY.index(perm)
|
||||
return any(True for hpos, hperm in enumerate(_PERMISSION_HIERARCHY)
|
||||
if hperm in perms and hpos > ppos)
|
||||
return any(
|
||||
True
|
||||
for hpos, hperm in enumerate(_PERMISSION_HIERARCHY)
|
||||
if hperm in perms and hpos > ppos
|
||||
)
|
||||
# we ignore pluralization (english only)
|
||||
if perm.endswith("s"):
|
||||
return self.check_permstring(perm[:-1])
|
||||
|
|
@ -634,7 +682,7 @@ class TypedObject(SharedMemoryModel):
|
|||
# Attribute storage
|
||||
#
|
||||
|
||||
#@property db
|
||||
# @property db
|
||||
def __db_get(self):
|
||||
"""
|
||||
Attribute handler wrapper. Allows for the syntax
|
||||
|
|
@ -650,27 +698,28 @@ class TypedObject(SharedMemoryModel):
|
|||
try:
|
||||
return self._db_holder
|
||||
except AttributeError:
|
||||
self._db_holder = DbHolder(self, 'attributes')
|
||||
self._db_holder = DbHolder(self, "attributes")
|
||||
return self._db_holder
|
||||
|
||||
#@db.setter
|
||||
# @db.setter
|
||||
def __db_set(self, value):
|
||||
"Stop accidentally replacing the db object"
|
||||
string = "Cannot assign directly to db object! "
|
||||
string += "Use db.attr=value instead."
|
||||
raise Exception(string)
|
||||
|
||||
#@db.deleter
|
||||
# @db.deleter
|
||||
def __db_del(self):
|
||||
"Stop accidental deletion."
|
||||
raise Exception("Cannot delete the db object!")
|
||||
|
||||
db = property(__db_get, __db_set, __db_del)
|
||||
|
||||
#
|
||||
# Non-persistent (ndb) storage
|
||||
#
|
||||
|
||||
#@property ndb
|
||||
# @property ndb
|
||||
def __ndb_get(self):
|
||||
"""
|
||||
A non-attr_obj store (ndb: NonDataBase). Everything stored
|
||||
|
|
@ -681,20 +730,21 @@ class TypedObject(SharedMemoryModel):
|
|||
try:
|
||||
return self._ndb_holder
|
||||
except AttributeError:
|
||||
self._ndb_holder = DbHolder(self, "nattrhandler", manager_name='nattributes')
|
||||
self._ndb_holder = DbHolder(self, "nattrhandler", manager_name="nattributes")
|
||||
return self._ndb_holder
|
||||
|
||||
#@db.setter
|
||||
# @db.setter
|
||||
def __ndb_set(self, value):
|
||||
"Stop accidentally replacing the ndb object"
|
||||
string = "Cannot assign directly to ndb object! "
|
||||
string += "Use ndb.attr=value instead."
|
||||
raise Exception(string)
|
||||
|
||||
#@db.deleter
|
||||
# @db.deleter
|
||||
def __ndb_del(self):
|
||||
"Stop accidental deletion."
|
||||
raise Exception("Cannot delete the ndb object!")
|
||||
|
||||
ndb = property(__ndb_get, __ndb_set, __ndb_del)
|
||||
|
||||
def get_display_name(self, looker, **kwargs):
|
||||
|
|
@ -719,7 +769,7 @@ class TypedObject(SharedMemoryModel):
|
|||
builders.
|
||||
|
||||
"""
|
||||
if self.access(looker, access_type='controls'):
|
||||
if self.access(looker, access_type="controls"):
|
||||
return "{}(#{})".format(self.name, self.id)
|
||||
return self.name
|
||||
|
||||
|
|
@ -773,8 +823,9 @@ class TypedObject(SharedMemoryModel):
|
|||
|
||||
"""
|
||||
content_type = ContentType.objects.get_for_model(self.__class__)
|
||||
return reverse("admin:%s_%s_change" % (content_type.app_label,
|
||||
content_type.model), args=(self.id,))
|
||||
return reverse(
|
||||
"admin:%s_%s_change" % (content_type.app_label, content_type.model), args=(self.id,)
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def web_get_create_url(cls):
|
||||
|
|
@ -803,9 +854,9 @@ class TypedObject(SharedMemoryModel):
|
|||
|
||||
"""
|
||||
try:
|
||||
return reverse('%s-create' % slugify(cls._meta.verbose_name))
|
||||
return reverse("%s-create" % slugify(cls._meta.verbose_name))
|
||||
except:
|
||||
return '#'
|
||||
return "#"
|
||||
|
||||
def web_get_detail_url(self):
|
||||
"""
|
||||
|
|
@ -834,10 +885,12 @@ class TypedObject(SharedMemoryModel):
|
|||
|
||||
"""
|
||||
try:
|
||||
return reverse('%s-detail' % slugify(self._meta.verbose_name),
|
||||
kwargs={'pk': self.pk, 'slug': slugify(self.name)})
|
||||
return reverse(
|
||||
"%s-detail" % slugify(self._meta.verbose_name),
|
||||
kwargs={"pk": self.pk, "slug": slugify(self.name)},
|
||||
)
|
||||
except:
|
||||
return '#'
|
||||
return "#"
|
||||
|
||||
def web_get_puppet_url(self):
|
||||
"""
|
||||
|
|
@ -866,10 +919,12 @@ class TypedObject(SharedMemoryModel):
|
|||
|
||||
"""
|
||||
try:
|
||||
return reverse('%s-puppet' % slugify(self._meta.verbose_name),
|
||||
kwargs={'pk': self.pk, 'slug': slugify(self.name)})
|
||||
return reverse(
|
||||
"%s-puppet" % slugify(self._meta.verbose_name),
|
||||
kwargs={"pk": self.pk, "slug": slugify(self.name)},
|
||||
)
|
||||
except:
|
||||
return '#'
|
||||
return "#"
|
||||
|
||||
def web_get_update_url(self):
|
||||
"""
|
||||
|
|
@ -898,10 +953,12 @@ class TypedObject(SharedMemoryModel):
|
|||
|
||||
"""
|
||||
try:
|
||||
return reverse('%s-update' % slugify(self._meta.verbose_name),
|
||||
kwargs={'pk': self.pk, 'slug': slugify(self.name)})
|
||||
return reverse(
|
||||
"%s-update" % slugify(self._meta.verbose_name),
|
||||
kwargs={"pk": self.pk, "slug": slugify(self.name)},
|
||||
)
|
||||
except:
|
||||
return '#'
|
||||
return "#"
|
||||
|
||||
def web_get_delete_url(self):
|
||||
"""
|
||||
|
|
@ -929,10 +986,12 @@ class TypedObject(SharedMemoryModel):
|
|||
|
||||
"""
|
||||
try:
|
||||
return reverse('%s-delete' % slugify(self._meta.verbose_name),
|
||||
kwargs={'pk': self.pk, 'slug': slugify(self.name)})
|
||||
return reverse(
|
||||
"%s-delete" % slugify(self._meta.verbose_name),
|
||||
kwargs={"pk": self.pk, "slug": slugify(self.name)},
|
||||
)
|
||||
except:
|
||||
return '#'
|
||||
return "#"
|
||||
|
||||
# Used by Django Sites/Admin
|
||||
get_absolute_url = web_get_detail_url
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue