Format code with black. Add makefile to run fmt/tests

This commit is contained in:
Griatch 2019-09-28 18:18:11 +02:00
parent d00bce9288
commit c2c7fa311a
299 changed files with 19037 additions and 11611 deletions

View file

@ -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