Continuing work on API, making local-use class properties _private to make things easier to explore.

This commit is contained in:
Griatch 2012-03-31 13:06:29 +02:00
parent 1ce5c6b84a
commit fc156b5a54
5 changed files with 308 additions and 328 deletions

View file

@ -21,7 +21,7 @@ from django.contrib.contenttypes.models import ContentType
from src.utils.idmapper.models import SharedMemoryModel from src.utils.idmapper.models import SharedMemoryModel
from src.typeclasses.models import Attribute, TypedObject, TypeNick, TypeNickHandler from src.typeclasses.models import Attribute, TypedObject, TypeNick, TypeNickHandler
from src.typeclasses.models import get_cache, set_cache, del_cache from src.typeclasses.models import _get_cache, _set_cache, _del_cache
from src.typeclasses.typeclass import TypeClass from src.typeclasses.typeclass import TypeClass
from src.objects.manager import ObjectManager from src.objects.manager import ObjectManager
from src.players.models import PlayerDB from src.players.models import PlayerDB
@ -34,11 +34,11 @@ from src.utils.utils import make_iter, to_unicode, to_str, mod_import
#PlayerDB = ContentType.objects.get(app_label="players", model="playerdb").model_class() #PlayerDB = ContentType.objects.get(app_label="players", model="playerdb").model_class()
AT_SEARCH_RESULT = mod_import(*settings.SEARCH_AT_RESULT.rsplit('.', 1)) _AT_SEARCH_RESULT = mod_import(*settings.SEARCH_AT_RESULT.rsplit('.', 1))
GA = object.__getattribute__ _GA = object.__getattribute__
SA = object.__setattr__ _SA = object.__setattr__
DA = object.__delattr__ _DA = object.__delattr__
#------------------------------------------------------------ #------------------------------------------------------------
# #
@ -214,10 +214,10 @@ class ObjectDB(TypedObject):
def aliases_get(self): def aliases_get(self):
"Getter. Allows for value = self.aliases" "Getter. Allows for value = self.aliases"
try: try:
return GA(self, "_cached_aliases") return _GA(self, "_cached_aliases")
except AttributeError: except AttributeError:
aliases = list(Alias.objects.filter(db_obj=self).values_list("db_key", flat=True)) aliases = list(Alias.objects.filter(db_obj=self).values_list("db_key", flat=True))
SA(self, "_cached_aliases", aliases) _SA(self, "_cached_aliases", aliases)
return aliases return aliases
#@aliases.setter #@aliases.setter
def aliases_set(self, aliases): def aliases_set(self, aliases):
@ -225,13 +225,13 @@ class ObjectDB(TypedObject):
for alias in make_iter(aliases): for alias in make_iter(aliases):
new_alias = Alias(db_key=alias, db_obj=self) new_alias = Alias(db_key=alias, db_obj=self)
new_alias.save() new_alias.save()
SA(self, "_cached_aliases", aliases) _SA(self, "_cached_aliases", aliases)
#@aliases.deleter #@aliases.deleter
def aliases_del(self): def aliases_del(self):
"Deleter. Allows for del self.aliases" "Deleter. Allows for del self.aliases"
for alias in Alias.objects.filter(db_obj=self): for alias in Alias.objects.filter(db_obj=self):
alias.delete() alias.delete()
DA(self, "_cached_aliases") _DA(self, "_cached_aliases")
aliases = property(aliases_get, aliases_set, aliases_del) aliases = property(aliases_get, aliases_set, aliases_del)
# player property (wraps db_player) # player property (wraps db_player)
@ -242,26 +242,26 @@ class ObjectDB(TypedObject):
We have to be careful here since Player is also We have to be careful here since Player is also
a TypedObject, so as to not create a loop. a TypedObject, so as to not create a loop.
""" """
return get_cache(self, "player") return _get_cache(self, "player")
#@player.setter #@player.setter
def player_set(self, player): def player_set(self, player):
"Setter. Allows for self.player = value" "Setter. Allows for self.player = value"
if isinstance(player, TypeClass): if isinstance(player, TypeClass):
player = player.dbobj player = player.dbobj
set_cache(self, "player", player) _set_cache(self, "player", player)
#@player.deleter #@player.deleter
def player_del(self): def player_del(self):
"Deleter. Allows for del self.player" "Deleter. Allows for del self.player"
self.db_player = None self.db_player = None
self.save() self.save()
del_cache(self, "player") _del_cache(self, "player")
player = property(player_get, player_set, player_del) player = property(player_get, player_set, player_del)
# location property (wraps db_location) # location property (wraps db_location)
#@property #@property
def location_get(self): def location_get(self):
"Getter. Allows for value = self.location." "Getter. Allows for value = self.location."
loc = get_cache(self, "location") loc = _get_cache(self, "location")
if loc: if loc:
return loc.typeclass return loc.typeclass
return None return None
@ -281,7 +281,7 @@ class ObjectDB(TypedObject):
loc = location.dbobj loc = location.dbobj
else: else:
loc = location.dbobj loc = location.dbobj
set_cache(self, "location", loc) _set_cache(self, "location", loc)
except Exception: except Exception:
string = "Cannot set location: " string = "Cannot set location: "
string += "%s is not a valid location." string += "%s is not a valid location."
@ -293,14 +293,14 @@ class ObjectDB(TypedObject):
"Deleter. Allows for del self.location" "Deleter. Allows for del self.location"
self.db_location = None self.db_location = None
self.save() self.save()
del_cache() _del_cache(self, "location")
location = property(location_get, location_set, location_del) location = property(location_get, location_set, location_del)
# home property (wraps db_home) # home property (wraps db_home)
#@property #@property
def home_get(self): def home_get(self):
"Getter. Allows for value = self.home" "Getter. Allows for value = self.home"
home = get_cache(self, "home") home = _get_cache(self, "home")
if home: if home:
return home.typeclass return home.typeclass
return None return None
@ -318,7 +318,7 @@ class ObjectDB(TypedObject):
hom = home.dbobj hom = home.dbobj
else: else:
hom = home.dbobj hom = home.dbobj
set_cache(self, "home", hom) _set_cache(self, "home", hom)
except Exception: except Exception:
string = "Cannot set home: " string = "Cannot set home: "
string += "%s is not a valid home." string += "%s is not a valid home."
@ -330,14 +330,14 @@ class ObjectDB(TypedObject):
"Deleter. Allows for del self.home." "Deleter. Allows for del self.home."
self.db_home = None self.db_home = None
self.save() self.save()
del_cache(self, "home") _del_cache(self, "home")
home = property(home_get, home_set, home_del) home = property(home_get, home_set, home_del)
# destination property (wraps db_destination) # destination property (wraps db_destination)
#@property #@property
def destination_get(self): def destination_get(self):
"Getter. Allows for value = self.destination." "Getter. Allows for value = self.destination."
dest = get_cache(self, "destination") dest = _get_cache(self, "destination")
if dest: if dest:
return dest.typeclass return dest.typeclass
return None return None
@ -357,7 +357,7 @@ class ObjectDB(TypedObject):
dest = destination.dbobj dest = destination.dbobj
else: else:
dest = destination.dbobj dest = destination.dbobj
set_cache(self, "destination", dest) _set_cache(self, "destination", dest)
except Exception: except Exception:
string = "Cannot set destination: " string = "Cannot set destination: "
string += "%s is not a valid destination." string += "%s is not a valid destination."
@ -369,7 +369,7 @@ class ObjectDB(TypedObject):
"Deleter. Allows for del self.destination" "Deleter. Allows for del self.destination"
self.db_destination = None self.db_destination = None
self.save() self.save()
del_cache(self, "destination") _del_cache(self, "destination")
destination = property(destination_get, destination_set, destination_del) destination = property(destination_get, destination_set, destination_del)
# cmdset_storage property. # cmdset_storage property.
@ -403,17 +403,10 @@ class ObjectDB(TypedObject):
# #
# this is required to properly handle attributes and typeclass loading. # this is required to properly handle attributes and typeclass loading.
#attribute_model_path = "src.objects.models" _typeclass_paths = settings.OBJECT_TYPECLASS_PATHS
#attribute_model_name = "ObjAttribute" _attribute_class = ObjAttribute
typeclass_paths = settings.OBJECT_TYPECLASS_PATHS _db_model_name = "objectdb" # used by attributes to safely store objects
attribute_class = ObjAttribute _default_typeclass_path = settings.BASE_OBJECT_TYPECLASS or "src.objects.objects.Object"
db_model_name = "objectdb" # used by attributes to safely store objects
# this is used by all typedobjects as a fallback
try:
default_typeclass_path = settings.BASE_OBJECT_TYPECLASS
except Exception:
default_typeclass_path = "src.objects.objects.Object"
#@property #@property
def sessions_get(self): def sessions_get(self):
@ -533,7 +526,7 @@ class ObjectDB(TypedObject):
if ignore_errors: if ignore_errors:
return results return results
# this import is cache after the first call. # this import is cache after the first call.
return AT_SEARCH_RESULT(self, ostring, results, global_search) return _AT_SEARCH_RESULT(self, ostring, results, global_search)
# #
# Execution/action methods # Execution/action methods

View file

@ -53,7 +53,7 @@ from src.utils import logger, utils
from src.commands.cmdsethandler import CmdSetHandler from src.commands.cmdsethandler import CmdSetHandler
from src.commands import cmdhandler from src.commands import cmdhandler
AT_SEARCH_RESULT = utils.mod_import(*settings.SEARCH_AT_RESULT.rsplit('.', 1)) _AT_SEARCH_RESULT = utils.mod_import(*settings.SEARCH_AT_RESULT.rsplit('.', 1))
#------------------------------------------------------------ #------------------------------------------------------------
# #
@ -257,18 +257,11 @@ class PlayerDB(TypedObject):
def __unicode__(self): def __unicode__(self):
return u"%s(player#%i)" % (self.name, self.id) return u"%s(player#%i)" % (self.name, self.id)
# this is used by all typedobjects as a fallback
try:
default_typeclass_path = settings.BASE_PLAYER_TYPECLASS
except Exception:
default_typeclass_path = "src.players.player.Player"
# this is required to properly handle attributes and typeclass loading # this is required to properly handle attributes and typeclass loading
#attribute_model_path = "src.players.models" _typeclass_paths = settings.PLAYER_TYPECLASS_PATHS
#attribute_model_name = "PlayerAttribute" _attribute_class = PlayerAttribute
typeclass_paths = settings.PLAYER_TYPECLASS_PATHS _db_model_name = "playerdb" # used by attributes to safely store objects
attribute_class = PlayerAttribute _default_typeclass_path = settings.BASE_PLAYER_TYPECLASS or "src.players.player.Player"
db_model_name = "playerdb" # used by attributes to safely store objects
# name property (wraps self.user.username) # name property (wraps self.user.username)
#@property #@property
@ -384,6 +377,5 @@ class PlayerDB(TypedObject):
ObjectDB = ContentType.objects.get(app_label="objects", model="objectdb").model_class() ObjectDB = ContentType.objects.get(app_label="objects", model="objectdb").model_class()
matches = ObjectDB.objects.object_search(ostring, caller=self, global_search=global_search) matches = ObjectDB.objects.object_search(ostring, caller=self, global_search=global_search)
# deal with results # deal with results
matches = AT_SEARCH_RESULT(self, ostring, matches, global_search=global_search) matches = _AT_SEARCH_RESULT(self, ostring, matches, global_search=global_search)
return matches return matches

View file

@ -245,17 +245,10 @@ class ScriptDB(TypedObject):
# #
# this is required to properly handle attributes and typeclass loading # this is required to properly handle attributes and typeclass loading
#attribute_model_path = "src.scripts.models" _typeclass_paths = settings.SCRIPT_TYPECLASS_PATHS
#attribute_model_name = "ScriptAttribute" _attribute_class = ScriptAttribute
typeclass_paths = settings.SCRIPT_TYPECLASS_PATHS _db_model_name = "scriptdb" # used by attributes to safely store objects
attribute_class = ScriptAttribute _default_typeclass_path = settings.BASE_SCRIPT_TYPECLASS or "src.scripts.scripts.DoNothing"
db_model_name = "scriptdb" # used by attributes to safely store objects
# this is used by all typedobjects as a fallback
try:
default_typeclass_path = settings.BASE_SCRIPT_TYPECLASS
except:
default_typeclass_path = "src.scripts.scripts.DoNothing"
def at_typeclass_error(self): def at_typeclass_error(self):
""" """

View file

@ -43,35 +43,35 @@ from src.locks.lockhandler import LockHandler
from src.utils import logger, utils from src.utils import logger, utils
from src.utils.utils import make_iter, is_iter, has_parent, to_unicode, to_str from src.utils.utils import make_iter, is_iter, has_parent, to_unicode, to_str
PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY] _PERMISSION_HIERARCHY = [p.lower() for p in settings.PERMISSION_HIERARCHY]
CTYPEGET = ContentType.objects.get _CTYPEGET = ContentType.objects.get
GA = object.__getattribute__ _GA = object.__getattribute__
SA = object.__setattr__ _SA = object.__setattr__
DA = object.__delattr__ _DA = object.__delattr__
PLOADS = pickle.loads _PLOADS = pickle.loads
PDUMPS = pickle.dumps _PDUMPS = pickle.dumps
# Property Cache mechanism. # Property Cache mechanism.
def get_cache(obj, name): def _get_cache(obj, name):
"On-model Cache handler." "On-model Cache handler."
try: try:
return GA(obj, "_cached_db_%s" % name) return _GA(obj, "_cached_db_%s" % name)
except AttributeError: except AttributeError:
val = GA(obj, "db_%s" % name) val = _GA(obj, "db_%s" % name)
if val: SA(obj, "_cached_db_%s" % name, val) if val: _SA(obj, "_cached_db_%s" % name, val)
return val return val
def set_cache(obj, name, val): def _set_cache(obj, name, val):
"On-model Cache setter" "On-model Cache setter"
SA(obj, "db_%s" % name, val) _SA(obj, "db_%s" % name, val)
GA(obj, "save")() _GA(obj, "save")()
SA(obj, "_cached_db_%s" % name, val) _SA(obj, "_cached_db_%s" % name, val)
def del_cache(obj, name): def _del_cache(obj, name):
"On-model cache deleter" "On-model cache deleter"
try: try:
DA(obj, "_cached_db_%s" % name) _DA(obj, "_cached_db_%s" % name)
except AttributeError: except AttributeError:
pass pass
@ -290,61 +290,61 @@ class Attribute(SharedMemoryModel):
# key property (wraps db_key) # key property (wraps db_key)
#@property #@property
def key_get(self): def __key_get(self):
"Getter. Allows for value = self.key" "Getter. Allows for value = self.key"
return get_cache(self, "key") return _get_cache(self, "key")
#@key.setter #@key.setter
def key_set(self, value): def __key_set(self, value):
"Setter. Allows for self.key = value" "Setter. Allows for self.key = value"
set_cache(self, "key", value) _set_cache(self, "key", value)
#@key.deleter #@key.deleter
def key_del(self): def __key_del(self):
"Deleter. Allows for del self.key" "Deleter. Allows for del self.key"
raise Exception("Cannot delete attribute key!") raise Exception("Cannot delete attribute key!")
key = property(key_get, key_set, key_del) key = property(__key_get, __key_set, __key_del)
# obj property (wraps db_obj) # obj property (wraps db_obj)
#@property #@property
def obj_get(self): def __obj_get(self):
"Getter. Allows for value = self.obj" "Getter. Allows for value = self.obj"
return get_cache(self, "obj") return _get_cache(self, "obj")
#@obj.setter #@obj.setter
def obj_set(self, value): def __obj_set(self, value):
"Setter. Allows for self.obj = value" "Setter. Allows for self.obj = value"
set_cache(self, "obj", value) _set_cache(self, "obj", value)
#@obj.deleter #@obj.deleter
def obj_del(self): def __obj_del(self):
"Deleter. Allows for del self.obj" "Deleter. Allows for del self.obj"
self.db_obj = None self.db_obj = None
self.save() self.save()
del_cache(self, "obj") _del_cache(self, "obj")
obj = property(obj_get, obj_set, obj_del) obj = property(__obj_get, __obj_set, __obj_del)
# date_created property (wraps db_date_created) # date_created property (wraps db_date_created)
#@property #@property
def date_created_get(self): def __date_created_get(self):
"Getter. Allows for value = self.date_created" "Getter. Allows for value = self.date_created"
return get_cache(self, "date_created") return _get_cache(self, "date_created")
#@date_created.setter #@date_created.setter
def date_created_set(self, value): def __date_created_set(self, value):
"Setter. Allows for self.date_created = value" "Setter. Allows for self.date_created = value"
raise Exception("Cannot edit date_created!") raise Exception("Cannot edit date_created!")
#@date_created.deleter #@date_created.deleter
def date_created_del(self): def __date_created_del(self):
"Deleter. Allows for del self.date_created" "Deleter. Allows for del self.date_created"
raise Exception("Cannot delete date_created!") raise Exception("Cannot delete date_created!")
date_created = property(date_created_get, date_created_set, date_created_del) date_created = property(__date_created_get, __date_created_set, __date_created_del)
# value property (wraps db_value) # value property (wraps db_value)
#@property #@property
def value_get(self): def __value_get(self):
""" """
Getter. Allows for value = self.value. Reads from cache if possible. Getter. Allows for value = self.value. Reads from cache if possible.
""" """
if self.no_cache: if self.no_cache:
# re-create data from database and cache it # re-create data from database and cache it
try: try:
value = self.from_attr(PLOADS(to_str(self.db_value))) value = self.__from_attr(_PLOADS(to_str(self.db_value)))
except pickle.UnpicklingError: except pickle.UnpicklingError:
value = self.db_value value = self.db_value
self.cached_value = value self.cached_value = value
@ -355,36 +355,36 @@ class Attribute(SharedMemoryModel):
return self.cached_value return self.cached_value
#@value.setter #@value.setter
def value_set(self, new_value): def __value_set(self, new_value):
""" """
Setter. Allows for self.value = value. We make sure to cache everything. Setter. Allows for self.value = value. We make sure to cache everything.
""" """
new_value = self.to_attr(new_value) new_value = self.__to_attr(new_value)
self.cached_value = self.from_attr(new_value) self.cached_value = self.__from_attr(new_value)
self.no_cache = False self.no_cache = False
self.db_value = to_unicode(PDUMPS(to_str(new_value))) self.db_value = to_unicode(_PDUMPS(to_str(new_value)))
self.save() self.save()
#@value.deleter #@value.deleter
def value_del(self): def __value_del(self):
"Deleter. Allows for del attr.value. This removes the entire attribute." "Deleter. Allows for del attr.value. This removes the entire attribute."
self.delete() self.delete()
value = property(value_get, value_set, value_del) value = property(__value_get, __value_set, __value_del)
# lock_storage property (wraps db_lock_storage) # lock_storage property (wraps db_lock_storage)
#@property #@property
def lock_storage_get(self): def __lock_storage_get(self):
"Getter. Allows for value = self.lock_storage" "Getter. Allows for value = self.lock_storage"
return get_cache(self, "lock_storage") return _get_cache(self, "lock_storage")
#@lock_storage.setter #@lock_storage.setter
def lock_storage_set(self, value): def __lock_storage_set(self, value):
"""Saves the lock_storage. This is usually not called directly, but through self.lock()""" """Saves the lock_storage. This is usually not called directly, but through self.lock()"""
self.db_lock_storage = value self.db_lock_storage = value
self.save() self.save()
#@lock_storage.deleter #@lock_storage.deleter
def lock_storage_del(self): def __lock_storage_del(self):
"Deleter is disabled. Use the lockhandler.delete (self.lock.delete) instead""" "Deleter is disabled. Use the lockhandler.delete (self.lock.delete) instead"""
logger.log_errmsg("Lock_Storage (on %s) cannot be deleted. Use obj.lock.delete() instead." % self) logger.log_errmsg("Lock_Storage (on %s) cannot be deleted. Use obj.lock.delete() instead." % self)
lock_storage = property(lock_storage_get, lock_storage_set, lock_storage_del) lock_storage = property(__lock_storage_get, __lock_storage_set, __lock_storage_del)
# #
@ -401,7 +401,7 @@ class Attribute(SharedMemoryModel):
# operators on various data # operators on various data
def to_attr(self, data): def __to_attr(self, data):
""" """
Convert data to proper attr data format before saving Convert data to proper attr data format before saving
@ -434,10 +434,10 @@ class Attribute(SharedMemoryModel):
dtype = type(item) dtype = type(item)
if dtype in (basestring, int, float): # check the most common types first, for speed if dtype in (basestring, int, float): # check the most common types first, for speed
return item return item
elif hasattr(item, "id") and hasattr(item, "db_model_name") and hasattr(item, "db_key"): elif hasattr(item, "id") and hasattr(item, "_db_model_name") and hasattr(item, "db_key"):
db_model_name = item.db_model_name db_model_name = item._db_model_name # don't use _GA here, could be typeclass
if db_model_name == "typeclass": if db_model_name == "typeclass":
db_model_name = GA(item.dbobj, "db_model_name") db_model_name = _GA(item.dbobj, "_db_model_name")
return PackedDBobject(item.id, db_model_name, item.db_key) return PackedDBobject(item.id, db_model_name, item.db_key)
elif dtype == tuple: elif dtype == tuple:
return tuple(iter_db2id(val) for val in item) return tuple(iter_db2id(val) for val in item)
@ -452,13 +452,13 @@ class Attribute(SharedMemoryModel):
if dtype in (basestring, int, float): if dtype in (basestring, int, float):
return ("simple",data) return ("simple",data)
elif hasattr(data, "id") and hasattr(data, "db_model_name") and hasattr(data, 'db_key'): elif hasattr(data, "id") and hasattr(data, "_db_model_name") and hasattr(data, 'db_key'):
# all django models (objectdb,scriptdb,playerdb,channel,msg,typeclass) # all django models (objectdb,scriptdb,playerdb,channel,msg,typeclass)
# have the protected property db_model_name hardcoded on themselves for speed. # have the protected property _db_model_name hardcoded on themselves for speed.
db_model_name = data.db_model_name db_model_name = data._db_model_name # don't use _GA here, could be typeclass
if db_model_name == "typeclass": if db_model_name == "typeclass":
# typeclass cannot help us, we want the actual child object model name # typeclass cannot help us, we want the actual child object model name
db_model_name = GA(data.dbobj, "db_model_name") db_model_name = _GA(data.dbobj,"_db_model_name")
return ("dbobj", PackedDBobject(data.id, db_model_name, data.db_key)) return ("dbobj", PackedDBobject(data.id, db_model_name, data.db_key))
elif hasattr(data, "__iter__"): elif hasattr(data, "__iter__"):
return ("iter", iter_db2id(data)) return ("iter", iter_db2id(data))
@ -466,7 +466,7 @@ class Attribute(SharedMemoryModel):
return ("simple", data) return ("simple", data)
def from_attr(self, datatuple): def __from_attr(self, datatuple):
""" """
Retrieve data from a previously stored attribute. This Retrieve data from a previously stored attribute. This
is always a dict with keys type and data. is always a dict with keys type and data.
@ -488,7 +488,7 @@ class Attribute(SharedMemoryModel):
""" """
Convert db-stored dbref back to object Convert db-stored dbref back to object
""" """
mclass = CTYPEGET(model=data.db_model).model_class() mclass = _CTYPEGET(model=data.db_model).model_class()
try: try:
return mclass.objects.dbref_search(data.id) return mclass.objects.dbref_search(data.id)
@ -636,9 +636,11 @@ class TypeNickHandler(object):
# remove the found nick(s) # remove the found nick(s)
query.delete() query.delete()
def get(self, nick=None, nick_type="inputline", obj=None): def get(self, nick=None, nick_type="inputline", obj=None):
"""Retrieves a given nick (with a specified nick_type) on an object. If no nick is given, returns a list """
Retrieves a given nick (with a specified nick_type) on an object. If no nick is given, returns a list
of all nicks on the object, or the empty list. of all nicks on the object, or the empty list.
Defaults to searching the current object.""" Defaults to searching the current object.
"""
if not obj: if not obj:
# defaults to the current object # defaults to the current object
obj = self.obj obj = self.obj
@ -739,101 +741,101 @@ class TypedObject(SharedMemoryModel):
# key property (wraps db_key) # key property (wraps db_key)
#@property #@property
def key_get(self): def __key_get(self):
"Getter. Allows for value = self.key" "Getter. Allows for value = self.key"
return get_cache(self, "key") return _get_cache(self, "key")
#@key.setter #@key.setter
def key_set(self, value): def __key_set(self, value):
"Setter. Allows for self.key = value" "Setter. Allows for self.key = value"
set_cache(self, "key", value) _set_cache(self, "key", value)
#@key.deleter #@key.deleter
def key_del(self): def __key_del(self):
"Deleter. Allows for del self.key" "Deleter. Allows for del self.key"
raise Exception("Cannot delete objectdb key!") raise Exception("Cannot delete objectdb key!")
key = property(key_get, key_set, key_del) key = property(__key_get, __key_set, __key_del)
# name property (wraps db_key too - alias to self.key) # name property (wraps db_key too - alias to self.key)
#@property #@property
def name_get(self): def __name_get(self):
"Getter. Allows for value = self.name" "Getter. Allows for value = self.name"
return get_cache(self, "key") return _get_cache(self, "key")
#@name.setter #@name.setter
def name_set(self, value): def __name_set(self, value):
"Setter. Allows for self.name = value" "Setter. Allows for self.name = value"
set_cache(self, "key", value) _set_cache(self, "key", value)
#@name.deleter #@name.deleter
def name_del(self): def __name_del(self):
"Deleter. Allows for del self.name" "Deleter. Allows for del self.name"
raise Exception("Cannot delete name!") raise Exception("Cannot delete name!")
name = property(name_get, name_set, name_del) name = property(__name_get, __name_set, __name_del)
# typeclass_path property # typeclass_path property
#@property #@property
def typeclass_path_get(self): def __typeclass_path_get(self):
"Getter. Allows for value = self.typeclass_path" "Getter. Allows for value = self.typeclass_path"
return get_cache(self, "typeclass_path") return _get_cache(self, "typeclass_path")
#@typeclass_path.setter #@typeclass_path.setter
def typeclass_path_set(self, value): def __typeclass_path_set(self, value):
"Setter. Allows for self.typeclass_path = value" "Setter. Allows for self.typeclass_path = value"
set_cache(self, "typeclass_path", value) _set_cache(self, "typeclass_path", value)
#@typeclass_path.deleter #@typeclass_path.deleter
def typeclass_path_del(self): def __typeclass_path_del(self):
"Deleter. Allows for del self.typeclass_path" "Deleter. Allows for del self.typeclass_path"
self.db_typeclass_path = "" self.db_typeclass_path = ""
self.save() self.save()
del_cache(self, "typeclass_path") _del_cache(self, "typeclass_path")
typeclass_path = property(typeclass_path_get, typeclass_path_set, typeclass_path_del) typeclass_path = property(__typeclass_path_get, __typeclass_path_set, __typeclass_path_del)
# date_created property # date_created property
#@property #@property
def date_created_get(self): def __date_created_get(self):
"Getter. Allows for value = self.date_created" "Getter. Allows for value = self.date_created"
return get_cache(self, "date_created") return _get_cache(self, "date_created")
#@date_created.setter #@date_created.setter
def date_created_set(self, value): def __date_created_set(self, value):
"Setter. Allows for self.date_created = value" "Setter. Allows for self.date_created = value"
raise Exception("Cannot change date_created!") raise Exception("Cannot change date_created!")
#@date_created.deleter #@date_created.deleter
def date_created_del(self): def __date_created_del(self):
"Deleter. Allows for del self.date_created" "Deleter. Allows for del self.date_created"
raise Exception("Cannot delete date_created!") raise Exception("Cannot delete date_created!")
date_created = property(date_created_get, date_created_set, date_created_del) date_created = property(__date_created_get, __date_created_set, __date_created_del)
# permissions property # permissions property
#@property #@property
def permissions_get(self): def __permissions_get(self):
"Getter. Allows for value = self.name. Returns a list of permissions." "Getter. Allows for value = self.name. Returns a list of permissions."
perms = get_cache(self, "permissions") perms = _get_cache(self, "permissions")
if perms: if perms:
return [perm.strip() for perm in perms.split(',')] return [perm.strip() for perm in perms.split(',')]
return [] return []
#@permissions.setter #@permissions.setter
def permissions_set(self, value): def __permissions_set(self, value):
"Setter. Allows for self.name = value. Stores as a comma-separated string." "Setter. Allows for self.name = value. Stores as a comma-separated string."
value = ",".join([utils.to_unicode(val).strip() for val in make_iter(value)]) value = ",".join([utils.to_unicode(val).strip() for val in make_iter(value)])
set_cache(self, "permissions", value) _set_cache(self, "permissions", value)
#@permissions.deleter #@permissions.deleter
def permissions_del(self): def __permissions_del(self):
"Deleter. Allows for del self.name" "Deleter. Allows for del self.name"
self.db_permissions = "" self.db_permissions = ""
self.save() self.save()
del_cache(self, "permissions") _del_cache(self, "permissions")
permissions = property(permissions_get, permissions_set, permissions_del) permissions = property(__permissions_get, __permissions_set, __permissions_del)
# lock_storage property (wraps db_lock_storage) # lock_storage property (wraps db_lock_storage)
#@property #@property
def lock_storage_get(self): def __lock_storage_get(self):
"Getter. Allows for value = self.lock_storage" "Getter. Allows for value = self.lock_storage"
return get_cache(self, "lock_storage") return _get_cache(self, "lock_storage")
#@lock_storage.setter #@lock_storage.setter
def lock_storage_set(self, value): def __lock_storage_set(self, value):
"""Saves the lock_storagetodate. This is usually not called directly, but through self.lock()""" """Saves the lock_storagetodate. This is usually not called directly, but through self.lock()"""
set_cache(self, "lock_storage", value) _set_cache(self, "lock_storage", value)
#@lock_storage.deleter #@lock_storage.deleter
def lock_storage_del(self): def __lock_storage_del(self):
"Deleter is disabled. Use the lockhandler.delete (self.lock.delete) instead""" "Deleter is disabled. Use the lockhandler.delete (self.lock.delete) instead"""
logger.log_errmsg("Lock_Storage (on %s) cannot be deleted. Use obj.lock.delete() instead." % self) logger.log_errmsg("Lock_Storage (on %s) cannot be deleted. Use obj.lock.delete() instead." % self)
lock_storage = property(lock_storage_get, lock_storage_set, lock_storage_del) lock_storage = property(__lock_storage_get, __lock_storage_set, __lock_storage_del)
@ -844,9 +846,9 @@ class TypedObject(SharedMemoryModel):
# #
# these are identifiers for fast Attribute access and caching # these are identifiers for fast Attribute access and caching
typeclass_paths = settings.OBJECT_TYPECLASS_PATHS _typeclass_paths = settings.OBJECT_TYPECLASS_PATHS
attribute_class = Attribute # replaced by relevant attribute class for child _attribute_class = Attribute # replaced by relevant attribute class for child
db_model_name = "typeclass" # used by attributes to safely store objects _db_model_name = "typeclass" # used by attributes to safely store objects
def __eq__(self, other): def __eq__(self, other):
return other and hasattr(other, 'id') and self.id == other.id return other and hasattr(other, 'id') and self.id == other.id
@ -866,31 +868,31 @@ class TypedObject(SharedMemoryModel):
have to be very careful to avoid loops. have to be very careful to avoid loops.
""" """
try: try:
return GA(self, propname) return _GA(self, propname)
except AttributeError: except AttributeError:
# check if the attribute exists on the typeclass instead # check if the attribute exists on the typeclass instead
# (we make sure to not incur a loop by not triggering the # (we make sure to not incur a loop by not triggering the
# typeclass' __getattribute__, since that one would # typeclass' __getattribute__, since that one would
# try to look back to this very database object.) # try to look back to this very database object.)
typeclass = GA(self, 'typeclass') typeclass = _GA(self, 'typeclass')
if typeclass: if typeclass:
return GA(typeclass, propname) return _GA(typeclass, propname)
else: else:
raise AttributeError raise AttributeError
#@property #@property
def dbref_get(self): def __dbref_get(self):
""" """
Returns the object's dbref id on the form #NN. Returns the object's dbref id on the form #NN.
Alternetively, use obj.id directly to get dbref Alternetively, use obj.id directly to get dbref
without any #. without any #.
""" """
return "#%s" % str(GA(self, "id")) return "#%s" % str(_GA(self, "id"))
dbref = property(dbref_get) dbref = property(__dbref_get)
# typeclass property # typeclass property
#@property #@property
def typeclass_get(self): def __typeclass_get(self):
""" """
Getter. Allows for value = self.typeclass. Getter. Allows for value = self.typeclass.
The typeclass is a class object found at self.typeclass_path; The typeclass is a class object found at self.typeclass_path;
@ -898,15 +900,15 @@ class TypedObject(SharedMemoryModel):
types of objects that the game needs. This property types of objects that the game needs. This property
handles loading and initialization of the typeclass on the fly. handles loading and initialization of the typeclass on the fly.
Note: The liberal use of GA and __setattr__ (instead Note: The liberal use of _GA and __setattr__ (instead
of normal dot notation) is due to optimization: it avoids calling of normal dot notation) is due to optimization: it avoids calling
the custom self.__getattribute__ more than necessary. the custom self.__getattribute__ more than necessary.
""" """
path = GA(self, "typeclass_path") path = _GA(self, "typeclass_path")
typeclass = GA(self, "_cached_typeclass") typeclass = _GA(self, "_cached_typeclass")
try: try:
if typeclass and GA(typeclass, "path") == path: if typeclass and _GA(typeclass, "path") == path:
# don't call at_init() when returning from cache # don't call at_init() when returning from cache
return typeclass return typeclass
except AttributeError: except AttributeError:
@ -915,25 +917,25 @@ class TypedObject(SharedMemoryModel):
errstring = "" errstring = ""
if not path: if not path:
# this means we should get the default obj without giving errors. # this means we should get the default obj without giving errors.
return GA(self, "get_default_typeclass")(cache=True, silent=True, save=True) return _GA(self, "_get_default_typeclass")(cache=True, silent=True, save=True)
else: else:
# handle loading/importing of typeclasses, searching all paths. # handle loading/importing of typeclasses, searching all paths.
# (self.typeclass_paths is a shortcut to settings.TYPECLASS_*_PATHS # (self._typeclass_paths is a shortcut to settings.TYPECLASS_*_PATHS
# where '*' is either OBJECT, SCRIPT or PLAYER depending on the typed # where '*' is either OBJECT, SCRIPT or PLAYER depending on the typed
# entities). # entities).
typeclass_paths = [path] + ["%s.%s" % (prefix, path) for prefix in GA(self, 'typeclass_paths')] typeclass_paths = [path] + ["%s.%s" % (prefix, path) for prefix in _GA(self, '_typeclass_paths')]
for tpath in typeclass_paths: for tpath in typeclass_paths:
# try to import and analyze the result # try to import and analyze the result
typeclass = GA(self, "_path_import")(tpath) typeclass = _GA(self, "_path_import")(tpath)
if callable(typeclass): if callable(typeclass):
# we succeeded to import. Cache and return. # we succeeded to import. Cache and return.
SA(self, 'db_typeclass_path', tpath) _SA(self, 'db_typeclass_path', tpath)
GA(self, 'save')() _GA(self, 'save')()
SA(self, "_cached_db_typeclass_path", tpath) _SA(self, "_cached_db_typeclass_path", tpath)
typeclass = typeclass(self) typeclass = typeclass(self)
SA(self, "_cached_typeclass", typeclass) _SA(self, "_cached_typeclass", typeclass)
try: try:
typeclass.at_init() typeclass.at_init()
except Exception: except Exception:
@ -946,16 +948,16 @@ class TypedObject(SharedMemoryModel):
errstring += "\n%s" % typeclass # this will hold a growing error message. errstring += "\n%s" % typeclass # this will hold a growing error message.
# If we reach this point we couldn't import any typeclasses. Return default. It's up to the calling # If we reach this point we couldn't import any typeclasses. Return default. It's up to the calling
# method to use e.g. self.is_typeclass() to detect that the result is not the one asked for. # method to use e.g. self.is_typeclass() to detect that the result is not the one asked for.
GA(self, "_display_errmsg")(errstring) _GA(self, "_display_errmsg")(errstring)
return GA(self, "get_default_typeclass")(cache=False, silent=False, save=False) return _GA(self, "_get_default_typeclass")(cache=False, silent=False, save=False)
#@typeclass.deleter #@typeclass.deleter
def typeclass_del(self): def __typeclass_del(self):
"Deleter. Disallow 'del self.typeclass'" "Deleter. Disallow 'del self.typeclass'"
raise Exception("The typeclass property should never be deleted, only changed in-place!") raise Exception("The typeclass property should never be deleted, only changed in-place!")
# typeclass property # typeclass property
typeclass = property(typeclass_get, fdel=typeclass_del) typeclass = property(__typeclass_get, fdel=__typeclass_del)
def _path_import(self, path): def _path_import(self, path):
""" """
@ -1014,7 +1016,7 @@ class TypedObject(SharedMemoryModel):
else: else:
logger.log_trace(cmessage) logger.log_trace(cmessage)
def get_default_typeclass(self, cache=False, silent=False, save=False): def _get_default_typeclass(self, cache=False, silent=False, save=False):
""" """
This is called when a typeclass fails to This is called when a typeclass fails to
load for whatever reason. load for whatever reason.
@ -1022,34 +1024,34 @@ class TypedObject(SharedMemoryModel):
Default operation is to load a default typeclass. Default operation is to load a default typeclass.
""" """
defpath = GA(self, "default_typeclass_path") defpath = _GA(self, "_default_typeclass_path")
typeclass = GA(self, "_path_import")(defpath) typeclass = _GA(self, "_path_import")(defpath)
# if not silent: # if not silent:
# #errstring = "\n\nUsing Default class '%s'." % defpath # #errstring = "\n\nUsing Default class '%s'." % defpath
# GA(self, "_display_errmsg")(errstring) # _GA(self, "_display_errmsg")(errstring)
if not callable(typeclass): if not callable(typeclass):
# if typeclass still doesn't exist at this point, we're in trouble. # if typeclass still doesn't exist at this point, we're in trouble.
# fall back to hardcoded core class which is wrong for e.g. scripts/players etc. # fall back to hardcoded core class which is wrong for e.g. scripts/players etc.
failpath = defpath failpath = defpath
defpath = "src.objects.objects.Object" defpath = "src.objects.objects.Object"
typeclass = GA(self, "_path_import")(defpath) typeclass = _GA(self, "_path_import")(defpath)
if not silent: if not silent:
#errstring = " %s\n%s" % (typeclass, errstring) #errstring = " %s\n%s" % (typeclass, errstring)
errstring = " Default class '%s' failed to load." % failpath errstring = " Default class '%s' failed to load." % failpath
errstring += "\n Using Evennia's default class '%s'." % defpath errstring += "\n Using Evennia's default class '%s'." % defpath
GA(self, "_display_errmsg")(errstring) _GA(self, "_display_errmsg")(errstring)
if not callable(typeclass): if not callable(typeclass):
# if this is still giving an error, Evennia is wrongly configured or buggy # if this is still giving an error, Evennia is wrongly configured or buggy
raise Exception("CRITICAL ERROR: The final fallback typeclass %s cannot load!!" % defpath) raise Exception("CRITICAL ERROR: The final fallback typeclass %s cannot load!!" % defpath)
typeclass = typeclass(self) typeclass = typeclass(self)
if save: if save:
SA(self, 'db_typeclass_path', defpath) _SA(self, 'db_typeclass_path', defpath)
GA(self, 'save')() _GA(self, 'save')()
if cache: if cache:
SA(self, "_cached_db_typeclass_path", defpath) _SA(self, "_cached_db_typeclass_path", defpath)
SA(self, "_cached_typeclass", typeclass) _SA(self, "_cached_typeclass", typeclass)
try: try:
typeclass.at_init() typeclass.at_init()
except Exception: except Exception:
@ -1070,17 +1072,17 @@ class TypedObject(SharedMemoryModel):
parents. parents.
""" """
try: try:
typeclass = GA(typeclass, "path") typeclass = _GA(typeclass, "path")
except AttributeError: except AttributeError:
pass pass
typeclasses = [typeclass] + ["%s.%s" % (path, typeclass) for path in GA(self, "typeclass_paths")] typeclasses = [typeclass] + ["%s.%s" % (path, typeclass) for path in _GA(self, "_typeclass_paths")]
if exact: if exact:
current_path = GA(self, "_cached_db_typeclass_path") current_path = _GA(self, "_cached_db_typeclass_path")
return typeclass and any((current_path == typec for typec in typeclasses)) return typeclass and any((current_path == typec for typec in typeclasses))
else: else:
# check parent chain # check parent chain
return any((cls for cls in self.typeclass.__class__.mro() return any((cls for cls in self.typeclass.__class__.mro()
if any(("%s.%s" % (GA(cls,"__module__"), GA(cls,"__name__")) == typec for typec in typeclasses)))) if any(("%s.%s" % (_GA(cls,"__module__"), _GA(cls,"__name__")) == typec for typec in typeclasses))))
# #
# Object manipulation methods # Object manipulation methods
@ -1135,13 +1137,13 @@ class TypedObject(SharedMemoryModel):
new_typeclass = self.typeclass new_typeclass = self.typeclass
if self.typeclass_path == new_typeclass.path: if self.typeclass_path == new_typeclass.path:
# the typeclass loading worked as expected # the typeclass loading worked as expected
DA(self, "_cached_db_typeclass_path") _DA(self, "_cached_db_typeclass_path")
SA(self, "_cached_typeclass", None) _SA(self, "_cached_typeclass", None)
elif no_default: elif no_default:
# something went wrong; the default was loaded instead, # something went wrong; the default was loaded instead,
# and we don't allow that; instead we return to previous. # and we don't allow that; instead we return to previous.
SA(self, "typeclass_path", old_typeclass_path) _SA(self, "typeclass_path", old_typeclass_path)
SA(self, "_cached_typeclass", None) _SA(self, "_cached_typeclass", None)
return False return False
if clean_attributes: if clean_attributes:
@ -1181,7 +1183,7 @@ class TypedObject(SharedMemoryModel):
attribute_name: (str) The attribute's name. attribute_name: (str) The attribute's name.
""" """
return GA(self, "attribute_class").objects.filter(db_obj=self).filter( return _GA(self, "_attribute_class").objects.filter(db_obj=self).filter(
db_key__iexact=attribute_name).count() db_key__iexact=attribute_name).count()
def set_attribute(self, attribute_name, new_value=None): def set_attribute(self, attribute_name, new_value=None):
@ -1194,7 +1196,7 @@ class TypedObject(SharedMemoryModel):
a str, the object will be stored as a pickle. a str, the object will be stored as a pickle.
""" """
attrib_obj = None attrib_obj = None
attrclass = GA(self, "attribute_class") attrclass = _GA(self, "_attribute_class")
try: try:
# use old attribute # use old attribute
attrib_obj = attrclass.objects.filter( attrib_obj = attrclass.objects.filter(
@ -1216,7 +1218,7 @@ class TypedObject(SharedMemoryModel):
""" """
attrib_obj = default attrib_obj = default
try: try:
attrib_obj = self.attribute_class.objects.filter( attrib_obj = _GA(self, "_attribute_class").objects.filter(
db_obj=self).filter(db_key__iexact=attribute_name)[0] db_obj=self).filter(db_key__iexact=attribute_name)[0]
except IndexError: except IndexError:
return default return default
@ -1230,7 +1232,7 @@ class TypedObject(SharedMemoryModel):
attribute_name: (str) The attribute's name. attribute_name: (str) The attribute's name.
""" """
try: try:
return self.attribute_class.objects.filter( return _GA(self, "_attribute_class").objects.filter(
db_obj=self).filter(db_key__iexact=attribute_name)[0].value db_obj=self).filter(db_key__iexact=attribute_name)[0].value
except IndexError: except IndexError:
raise AttributeError raise AttributeError
@ -1242,7 +1244,7 @@ class TypedObject(SharedMemoryModel):
attribute_name: (str) The attribute's name. attribute_name: (str) The attribute's name.
""" """
try: try:
self.attribute_class.objects.filter( _GA(self, "_attribute_class").objects.filter(
db_obj=self).filter(db_key__iexact=attribute_name)[0].delete() db_obj=self).filter(db_key__iexact=attribute_name)[0].delete()
except IndexError: except IndexError:
pass pass
@ -1255,7 +1257,7 @@ class TypedObject(SharedMemoryModel):
attribute_name: (str) The attribute's name. attribute_name: (str) The attribute's name.
""" """
try: try:
self.attribute_class.objects.filter( _GA(self, "_attribute_class").objects.filter(
db_obj=self).filter(db_key__iexact=attribute_name)[0].delete() db_obj=self).filter(db_key__iexact=attribute_name)[0].delete()
except IndexError: except IndexError:
raise AttributeError raise AttributeError
@ -1264,7 +1266,7 @@ class TypedObject(SharedMemoryModel):
""" """
Returns all attributes defined on the object. Returns all attributes defined on the object.
""" """
return list(self.attribute_class.objects.filter(db_obj=self)) return list(_GA(self,"_attribute_class").objects.filter(db_obj=self))
def attr(self, attribute_name=None, value=None, delete=False): def attr(self, attribute_name=None, value=None, delete=False):
""" """
@ -1291,7 +1293,7 @@ class TypedObject(SharedMemoryModel):
self.set_attribute(attribute_name, value) self.set_attribute(attribute_name, value)
#@property #@property
def db_get(self): def __db_get(self):
""" """
A second convenience wrapper for the the attribute methods. It A second convenience wrapper for the the attribute methods. It
allows for the syntax allows for the syntax
@ -1310,35 +1312,35 @@ class TypedObject(SharedMemoryModel):
class DbHolder(object): class DbHolder(object):
"Holder for allowing property access of attributes" "Holder for allowing property access of attributes"
def __init__(self, obj): def __init__(self, obj):
SA(self, 'obj', obj) _SA(self, 'obj', obj)
def __getattribute__(self, attrname): def __getattribute__(self, attrname):
if attrname == 'all': if attrname == 'all':
# we allow for overwriting the all() method # we allow for overwriting the all() method
# with an attribute named 'all'. # with an attribute named 'all'.
attr = GA(self, 'obj').get_attribute("all") attr = _GA(self, 'obj').get_attribute("all")
if attr: if attr:
return attr return attr
return GA(self, 'all') return _GA(self, 'all')
return GA(self, 'obj').get_attribute(attrname) return _GA(self, 'obj').get_attribute(attrname)
def __setattr__(self, attrname, value): def __setattr__(self, attrname, value):
GA(self, 'obj').set_attribute(attrname, value) _GA(self, 'obj').set_attribute(attrname, value)
def __delattr__(self, attrname): def __delattr__(self, attrname):
GA(self, 'obj').del_attribute(attrname) _GA(self, 'obj').del_attribute(attrname)
def all(self): def all(self):
return GA(self, 'obj').get_all_attributes() return _GA(self, 'obj').get_all_attributes()
self._db_holder = DbHolder(self) self._db_holder = DbHolder(self)
return self._db_holder return self._db_holder
#@db.setter #@db.setter
def db_set(self, value): def __db_set(self, value):
"Stop accidentally replacing the db object" "Stop accidentally replacing the db object"
string = "Cannot assign directly to db object! " string = "Cannot assign directly to db object! "
string += "Use db.attr=value instead." string += "Use db.attr=value instead."
raise Exception(string) raise Exception(string)
#@db.deleter #@db.deleter
def db_del(self): def __db_del(self):
"Stop accidental deletion." "Stop accidental deletion."
raise Exception("Cannot delete the db object!") raise Exception("Cannot delete the db object!")
db = property(db_get, db_set, db_del) db = property(__db_get, __db_set, __db_del)
# #
# NON-PERSISTENT storage methods # NON-PERSISTENT storage methods
@ -1358,19 +1360,19 @@ class TypedObject(SharedMemoryModel):
if not val.startswith['_']] if not val.startswith['_']]
elif delete == True: elif delete == True:
if hasattr(self.ndb, attribute_name): if hasattr(self.ndb, attribute_name):
DA(self.db, attribute_name) _DA(self.db, attribute_name)
elif value == None: elif value == None:
# act as a getter. # act as a getter.
if hasattr(self.ndb, attribute_name): if hasattr(self.ndb, attribute_name):
GA(self.ndb, attribute_name) _GA(self.ndb, attribute_name)
else: else:
return None return None
else: else:
# act as a setter # act as a setter
SA(self.db, attribute_name, value) _SA(self.db, attribute_name, value)
#@property #@property
def ndb_get(self): def __ndb_get(self):
""" """
A non-persistent store (ndb: NonDataBase). Everything stored A non-persistent store (ndb: NonDataBase). Everything stored
to this is guaranteed to be cleared when a server is shutdown. to this is guaranteed to be cleared when a server is shutdown.
@ -1388,22 +1390,22 @@ class TypedObject(SharedMemoryModel):
def __getattribute__(self, key): def __getattribute__(self, key):
# return None if no matching attribute was found. # return None if no matching attribute was found.
try: try:
return GA(self, key) return _GA(self, key)
except AttributeError: except AttributeError:
return None return None
self._ndb_holder = NdbHolder() self._ndb_holder = NdbHolder()
return self._ndb_holder return self._ndb_holder
#@ndb.setter #@ndb.setter
def ndb_set(self, value): def __ndb_set(self, value):
"Stop accidentally replacing the db object" "Stop accidentally replacing the db object"
string = "Cannot assign directly to ndb object! " string = "Cannot assign directly to ndb object! "
string = "Use ndb.attr=value instead." string = "Use ndb.attr=value instead."
raise Exception(string) raise Exception(string)
#@ndb.deleter #@ndb.deleter
def ndb_del(self): def __ndb_del(self):
"Stop accidental deletion." "Stop accidental deletion."
raise Exception("Cannot delete the ndb object!") raise Exception("Cannot delete the ndb object!")
ndb = property(ndb_get, ndb_set, ndb_del) ndb = property(__ndb_get, __ndb_set, __ndb_del)
# #
# Lock / permission methods # Lock / permission methods
@ -1437,9 +1439,9 @@ class TypedObject(SharedMemoryModel):
if perm in [p.lower() for p in self.permissions]: if perm in [p.lower() for p in self.permissions]:
# simplest case - we have a direct match # simplest case - we have a direct match
return True return True
if perm in PERMISSION_HIERARCHY: if perm in _PERMISSION_HIERARCHY:
# check if we have a higher hierarchy position # check if we have a higher hierarchy position
ppos = PERMISSION_HIERARCHY.index(perm) ppos = _PERMISSION_HIERARCHY.index(perm)
return any(True for hpos, hperm in enumerate(PERMISSION_HIERARCHY) return any(True for hpos, hperm in enumerate(_PERMISSION_HIERARCHY)
if hperm in [p.lower() for p in self.permissions] and hpos > ppos) if hperm in [p.lower() for p in self.permissions] and hpos > ppos)
return False return False

View file

@ -14,9 +14,9 @@ from src.utils.logger import log_trace, log_errmsg
from django.conf import settings from django.conf import settings
# these are called so many times it's worth to avoid lookup calls # these are called so many times it's worth to avoid lookup calls
GA = object.__getattribute__ _GA = object.__getattribute__
SA = object.__setattr__ _SA = object.__setattr__
DA = object.__delattr__ _DA = object.__delattr__
# To ensure the sanity of the model, there are a # To ensure the sanity of the model, there are a
# few property names we won't allow the admin to # few property names we won't allow the admin to
@ -75,13 +75,13 @@ class TypeClass(object):
""" """
# typecheck of dbobj - we can't allow it to be added here # typecheck of dbobj - we can't allow it to be added here
# unless it's really a TypedObject. # unless it's really a TypedObject.
dbobj_cls = GA(dbobj, '__class__') dbobj_cls = _GA(dbobj, '__class__')
dbobj_mro = GA(dbobj_cls, '__mro__') dbobj_mro = _GA(dbobj_cls, '__mro__')
if not any('src.typeclasses.models.TypedObject' in str(mro) for mro in dbobj_mro): if not any('src.typeclasses.models.TypedObject' in str(mro) for mro in dbobj_mro):
raise Exception("dbobj is not a TypedObject: %s: %s" % (dbobj_cls, dbobj_mro)) raise Exception("dbobj is not a TypedObject: %s: %s" % (dbobj_cls, dbobj_mro))
# store the reference to the database model instance # store the reference to the database model instance
SA(self, 'dbobj', dbobj) _SA(self, 'dbobj', dbobj)
def __getattribute__(self, propname): def __getattribute__(self, propname):
""" """
@ -93,25 +93,25 @@ class TypeClass(object):
accessible through getattr. accessible through getattr.
""" """
if propname == 'dbobj': if propname == 'dbobj':
return GA(self, 'dbobj') return _GA(self, 'dbobj')
if propname.startswith('__') and propname.endswith('__'): if propname.startswith('__') and propname.endswith('__'):
# python specials are parsed as-is (otherwise things like # python specials are parsed as-is (otherwise things like
# isinstance() fail to identify the typeclass) # isinstance() fail to identify the typeclass)
return GA(self, propname) return _GA(self, propname)
#print "get %s (dbobj:%s)" % (propname, type(dbobj)) #print "get %s (dbobj:%s)" % (propname, type(dbobj))
try: try:
return GA(self, propname) return _GA(self, propname)
except AttributeError: except AttributeError:
try: try:
dbobj = GA(self, 'dbobj') dbobj = _GA(self, 'dbobj')
except AttributeError: except AttributeError:
log_trace("Typeclass CRITICAL ERROR! dbobj not found for Typeclass %s!" % self) log_trace("Typeclass CRITICAL ERROR! dbobj not found for Typeclass %s!" % self)
raise raise
try: try:
return GA(dbobj, propname) return _GA(dbobj, propname)
except AttributeError: except AttributeError:
try: try:
return GA(dbobj,"get_attribute_raise")(propname) return _GA(dbobj,"get_attribute_raise")(propname)
except AttributeError: except AttributeError:
string = "Object: '%s' not found on %s(%s), nor on its typeclass %s." string = "Object: '%s' not found on %s(%s), nor on its typeclass %s."
raise AttributeError(string % (propname, dbobj, dbobj.dbref, dbobj.typeclass_path)) raise AttributeError(string % (propname, dbobj, dbobj.dbref, dbobj.typeclass_path))
@ -132,7 +132,7 @@ class TypeClass(object):
return return
try: try:
dbobj = GA(self, 'dbobj') dbobj = _GA(self, 'dbobj')
except AttributeError: except AttributeError:
dbobj = None dbobj = None
log_trace("This is probably due to an unsafe reload.") log_trace("This is probably due to an unsafe reload.")
@ -141,19 +141,19 @@ class TypeClass(object):
try: try:
# only set value on propname if propname already exists # only set value on propname if propname already exists
# on dbobj. __getattribute__ will raise attribute error otherwise. # on dbobj. __getattribute__ will raise attribute error otherwise.
GA(dbobj, propname) _GA(dbobj, propname)
SA(dbobj, propname, value) _SA(dbobj, propname, value)
except AttributeError: except AttributeError:
dbobj.set_attribute(propname, value) dbobj.set_attribute(propname, value)
else: else:
SA(self, propname, value) _SA(self, propname, value)
def __eq__(self, other): def __eq__(self, other):
""" """
dbobj-recognized comparison dbobj-recognized comparison
""" """
try: try:
return other == self or other == GA(self, dbobj) or other == GA(self, dbobj).user return other == self or other == _GA(self, dbobj) or other == _GA(self, dbobj).user
except AttributeError: except AttributeError:
# if self.dbobj.user fails it means the two previous comparisons failed already # if self.dbobj.user fails it means the two previous comparisons failed already
return False return False
@ -172,11 +172,11 @@ class TypeClass(object):
return return
try: try:
DA(self, propname) _DA(self, propname)
except AttributeError: except AttributeError:
# not on typeclass, try to delete on db/ndb # not on typeclass, try to delete on db/ndb
try: try:
dbobj = GA(self, 'dbobj') dbobj = _GA(self, 'dbobj')
except AttributeError: except AttributeError:
log_trace("This is probably due to an unsafe reload.") log_trace("This is probably due to an unsafe reload.")
return # ignore delete return # ignore delete