Changed how lazy-loading of handlers work, using a werkzeug recipe. Much more efficient now.
This commit is contained in:
parent
680e603c4d
commit
e6950aadf2
10 changed files with 125 additions and 144 deletions
|
|
@ -141,7 +141,6 @@ class CmdClimb(Command):
|
||||||
obj = self.caller.search(self.args.strip())
|
obj = self.caller.search(self.args.strip())
|
||||||
if not obj:
|
if not obj:
|
||||||
return
|
return
|
||||||
print "obj", "self.obj", obj, self
|
|
||||||
if obj != self.obj:
|
if obj != self.obj:
|
||||||
self.caller.msg("Try as you might, you cannot climb that.")
|
self.caller.msg("Try as you might, you cannot climb that.")
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ All commands in Evennia inherit from the 'Command' class in this module.
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from src.locks.lockhandler import LockHandler
|
from src.locks.lockhandler import LockHandler
|
||||||
from src.utils.utils import is_iter, fill, LazyLoadHandler
|
from src.utils.utils import is_iter, fill, lazy_property
|
||||||
|
|
||||||
|
|
||||||
def _init_command(mcs, **kwargs):
|
def _init_command(mcs, **kwargs):
|
||||||
|
|
@ -155,7 +155,10 @@ class Command(object):
|
||||||
overloading evential same-named class properties."""
|
overloading evential same-named class properties."""
|
||||||
if kwargs:
|
if kwargs:
|
||||||
_init_command(self, **kwargs)
|
_init_command(self, **kwargs)
|
||||||
self.lockhandler = LazyLoadHandler(self, "lockhandler", LockHandler)
|
|
||||||
|
@lazy_property
|
||||||
|
def lockhandler(self):
|
||||||
|
return LockHandler(self)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"Print the command"
|
"Print the command"
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ from src.utils.idmapper.models import SharedMemoryModel
|
||||||
from src.comms import managers
|
from src.comms import managers
|
||||||
from src.comms.managers import identify_object
|
from src.comms.managers import identify_object
|
||||||
from src.locks.lockhandler import LockHandler
|
from src.locks.lockhandler import LockHandler
|
||||||
from src.utils.utils import crop, make_iter, LazyLoadHandler
|
from src.utils.utils import crop, make_iter, lazy_property
|
||||||
|
|
||||||
__all__ = ("Msg", "TempMsg", "ChannelDB")
|
__all__ = ("Msg", "TempMsg", "ChannelDB")
|
||||||
|
|
||||||
|
|
@ -103,7 +103,6 @@ class Msg(SharedMemoryModel):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
SharedMemoryModel.__init__(self, *args, **kwargs)
|
SharedMemoryModel.__init__(self, *args, **kwargs)
|
||||||
#_SA(self, "locks", LazyLoadHandler(self, "locks", LockHandler))
|
|
||||||
self.extra_senders = []
|
self.extra_senders = []
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
@ -299,10 +298,13 @@ class TempMsg(object):
|
||||||
self.header = header
|
self.header = header
|
||||||
self.message = message
|
self.message = message
|
||||||
self.lock_storage = lockstring
|
self.lock_storage = lockstring
|
||||||
self.locks = LazyLoadHandler(self, "locks", LockHandler)
|
|
||||||
self.hide_from = hide_from and make_iter(hide_from) or []
|
self.hide_from = hide_from and make_iter(hide_from) or []
|
||||||
self.date_sent = datetime.now()
|
self.date_sent = datetime.now()
|
||||||
|
|
||||||
|
@lazy_property
|
||||||
|
def locks(self):
|
||||||
|
return LockHandler(self)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"This handles what is shown when e.g. printing the message"
|
"This handles what is shown when e.g. printing the message"
|
||||||
senders = ",".join(obj.key for obj in self.senders)
|
senders = ",".join(obj.key for obj in self.senders)
|
||||||
|
|
@ -359,12 +361,6 @@ class ChannelDB(TypedObject):
|
||||||
_typeclass_paths = settings.CHANNEL_TYPECLASS_PATHS
|
_typeclass_paths = settings.CHANNEL_TYPECLASS_PATHS
|
||||||
_default_typeclass_path = settings.BASE_CHANNEL_TYPECLASS or "src.comms.comms.Channel"
|
_default_typeclass_path = settings.BASE_CHANNEL_TYPECLASS or "src.comms.comms.Channel"
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
TypedObject.__init__(self, *args, **kwargs)
|
|
||||||
_SA(self, "tags", LazyLoadHandler(self, "tags", TagHandler))
|
|
||||||
_SA(self, "attributes", LazyLoadHandler(self, "attributes", AttributeHandler))
|
|
||||||
_SA(self, "aliases", LazyLoadHandler(self, "aliases", AliasHandler))
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"Define Django meta options"
|
"Define Django meta options"
|
||||||
verbose_name = "Channel"
|
verbose_name = "Channel"
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ from src.utils.idmapper.models import SharedMemoryModel
|
||||||
from src.help.manager import HelpEntryManager
|
from src.help.manager import HelpEntryManager
|
||||||
from src.typeclasses.models import Tag, TagHandler
|
from src.typeclasses.models import Tag, TagHandler
|
||||||
from src.locks.lockhandler import LockHandler
|
from src.locks.lockhandler import LockHandler
|
||||||
from src.utils.utils import LazyLoadHandler
|
from src.utils.utils import lazy_property
|
||||||
__all__ = ("HelpEntry",)
|
__all__ = ("HelpEntry",)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -66,10 +66,16 @@ class HelpEntry(SharedMemoryModel):
|
||||||
objects = HelpEntryManager()
|
objects = HelpEntryManager()
|
||||||
_is_deleted = False
|
_is_deleted = False
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
# lazy-loaded handlers
|
||||||
SharedMemoryModel.__init__(self, *args, **kwargs)
|
|
||||||
self.locks = LazyLoadHandler(self, "locks", LockHandler)
|
@lazy_property
|
||||||
self.tags = LazyLoadHandler(self, "tags", TagHandler)
|
def locks(self):
|
||||||
|
return LockHandler(self)
|
||||||
|
|
||||||
|
@lazy_property
|
||||||
|
def tags(self):
|
||||||
|
return TagHandler(self)
|
||||||
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"Define Django meta options"
|
"Define Django meta options"
|
||||||
|
|
|
||||||
|
|
@ -19,16 +19,15 @@ from django.db import models
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
|
|
||||||
from src.typeclasses.models import (TypedObject, TagHandler, NickHandler,
|
from src.typeclasses.models import TypedObject, NickHandler
|
||||||
AliasHandler, AttributeHandler)
|
|
||||||
from src.objects.manager import ObjectManager
|
from src.objects.manager import ObjectManager
|
||||||
from src.players.models import PlayerDB
|
from src.players.models import PlayerDB
|
||||||
from src.commands.cmdsethandler import CmdSetHandler
|
from src.commands.cmdsethandler import CmdSetHandler
|
||||||
from src.commands import cmdhandler
|
from src.commands import cmdhandler
|
||||||
from src.scripts.scripthandler import ScriptHandler
|
from src.scripts.scripthandler import ScriptHandler
|
||||||
from src.utils import logger
|
from src.utils import logger
|
||||||
from src.utils.utils import (make_iter, to_str, to_unicode,
|
from src.utils.utils import (make_iter, to_str, to_unicode, lazy_property,
|
||||||
variable_from_module, dbref, LazyLoadHandler)
|
variable_from_module, dbref)
|
||||||
|
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
|
|
@ -130,19 +129,18 @@ class ObjectDB(TypedObject):
|
||||||
_typeclass_paths = settings.OBJECT_TYPECLASS_PATHS
|
_typeclass_paths = settings.OBJECT_TYPECLASS_PATHS
|
||||||
_default_typeclass_path = settings.BASE_OBJECT_TYPECLASS or "src.objects.objects.Object"
|
_default_typeclass_path = settings.BASE_OBJECT_TYPECLASS or "src.objects.objects.Object"
|
||||||
|
|
||||||
# Add the object-specific handlers
|
# lazy-load handlers
|
||||||
def __init__(self, *args, **kwargs):
|
@lazy_property
|
||||||
"Parent must be initialized first."
|
def cmdset(self):
|
||||||
TypedObject.__init__(self, *args, **kwargs)
|
return CmdSetHandler(self, True)
|
||||||
# handlers
|
|
||||||
_SA(self, "cmdset", LazyLoadHandler(self, "cmdset", CmdSetHandler, True))
|
@lazy_property
|
||||||
_SA(self, "scripts", LazyLoadHandler(self, "scripts", ScriptHandler))
|
def scripts(self):
|
||||||
_SA(self, "nicks", LazyLoadHandler(self, "nicks", NickHandler))
|
return ScriptHandler(self)
|
||||||
#_SA(self, "attributes", LazyLoadHandler(self, "attributes", AttributeHandler))
|
|
||||||
#_SA(self, "tags", LazyLoadHandler(self, "tags", TagHandler))
|
@lazy_property
|
||||||
#_SA(self, "aliases", LazyLoadHandler(self, "aliases", AliasHandler))
|
def nicks(self):
|
||||||
# make sure to sync the contents cache when initializing
|
return NickHandler(self)
|
||||||
#_GA(self, "contents_update")()
|
|
||||||
|
|
||||||
def _at_db_player_postsave(self):
|
def _at_db_player_postsave(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,12 @@ from django.utils.encoding import smart_str
|
||||||
|
|
||||||
from src.players import manager
|
from src.players import manager
|
||||||
from src.scripts.models import ScriptDB
|
from src.scripts.models import ScriptDB
|
||||||
from src.typeclasses.models import (TypedObject, TagHandler, NickHandler,
|
from src.typeclasses.models import (TypedObject, NickHandler)
|
||||||
AliasHandler, AttributeHandler)
|
|
||||||
from src.scripts.scripthandler import ScriptHandler
|
from src.scripts.scripthandler import ScriptHandler
|
||||||
from src.commands.cmdsethandler import CmdSetHandler
|
from src.commands.cmdsethandler import CmdSetHandler
|
||||||
from src.commands import cmdhandler
|
from src.commands import cmdhandler
|
||||||
from src.utils import utils, logger
|
from src.utils import utils, logger
|
||||||
from src.utils.utils import to_str, make_iter, LazyLoadHandler
|
from src.utils.utils import to_str, make_iter, lazy_property
|
||||||
|
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
|
|
@ -111,15 +110,19 @@ class PlayerDB(TypedObject, AbstractUser):
|
||||||
app_label = 'players'
|
app_label = 'players'
|
||||||
verbose_name = 'Player'
|
verbose_name = 'Player'
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
# lazy-loading of handlers
|
||||||
"Parent must be initiated first"
|
@lazy_property
|
||||||
TypedObject.__init__(self, *args, **kwargs)
|
def cmdset(self):
|
||||||
# handlers
|
return CmdSetHandler(self, True)
|
||||||
_SA(self, "cmdset", LazyLoadHandler(self, "cmdset", CmdSetHandler, True))
|
|
||||||
_SA(self, "scripts", LazyLoadHandler(self, "scripts", ScriptHandler))
|
@lazy_property
|
||||||
_SA(self, "nicks", LazyLoadHandler(self, "nicks", NickHandler))
|
def scripts(self):
|
||||||
#_SA(self, "tags", LazyLoadHandler(self, "tags", TagHandler))
|
return ScriptHandler(self)
|
||||||
#_SA(self, "aliases", LazyLoadHandler(self, "aliases", AliasHandler))
|
|
||||||
|
@lazy_property
|
||||||
|
def nicks(self):
|
||||||
|
return NickHandler(self)
|
||||||
|
|
||||||
|
|
||||||
# alias to the objs property
|
# alias to the objs property
|
||||||
def __characters_get(self):
|
def __characters_get(self):
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,9 @@ Common examples of uses of Scripts:
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
from src.typeclasses.models import TypedObject, TagHandler, AttributeHandler
|
from src.typeclasses.models import TypedObject
|
||||||
from src.scripts.manager import ScriptManager
|
from src.scripts.manager import ScriptManager
|
||||||
from src.utils.utils import dbref, to_str, LazyLoadHandler
|
from src.utils.utils import dbref, to_str
|
||||||
|
|
||||||
__all__ = ("ScriptDB",)
|
__all__ = ("ScriptDB",)
|
||||||
_GA = object.__getattribute__
|
_GA = object.__getattribute__
|
||||||
|
|
@ -108,13 +108,6 @@ class ScriptDB(TypedObject):
|
||||||
"Define Django meta options"
|
"Define Django meta options"
|
||||||
verbose_name = "Script"
|
verbose_name = "Script"
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super(ScriptDB, self).__init__(*args, **kwargs)
|
|
||||||
_SA(self, "attributes", LazyLoadHandler(self, "attributes", AttributeHandler))
|
|
||||||
_SA(self, "tags", LazyLoadHandler(self, "tags", TagHandler))
|
|
||||||
#_SA(self, "aliases", AliasHandler(self))
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# ScriptDB class properties
|
# ScriptDB class properties
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,9 @@ from django.conf import settings
|
||||||
#from src.scripts.models import ScriptDB
|
#from src.scripts.models import ScriptDB
|
||||||
from src.comms.models import ChannelDB
|
from src.comms.models import ChannelDB
|
||||||
from src.utils import logger, utils
|
from src.utils import logger, utils
|
||||||
from src.utils.utils import make_iter, to_unicode, LazyLoadHandler
|
from src.utils.utils import make_iter, to_unicode
|
||||||
from src.commands import cmdhandler, cmdsethandler
|
from src.commands.cmdhandler import cmdhandler
|
||||||
|
from src.commands.cmdsethandler import CmdSetHandler
|
||||||
from src.server.session import Session
|
from src.server.session import Session
|
||||||
|
|
||||||
IDLE_COMMAND = settings.IDLE_COMMAND
|
IDLE_COMMAND = settings.IDLE_COMMAND
|
||||||
|
|
@ -49,7 +50,7 @@ class ServerSession(Session):
|
||||||
self.puppet = None
|
self.puppet = None
|
||||||
self.player = None
|
self.player = None
|
||||||
self.cmdset_storage_string = ""
|
self.cmdset_storage_string = ""
|
||||||
self.cmdset = LazyLoadHandler(self, "cmdset", cmdsethandler.CmdSetHandler, True)
|
self.cmdset = CmdSetHandler(self, True)
|
||||||
|
|
||||||
def __cmdset_storage_get(self):
|
def __cmdset_storage_get(self):
|
||||||
return [path.strip() for path in self.cmdset_storage_string.split(',')]
|
return [path.strip() for path in self.cmdset_storage_string.split(',')]
|
||||||
|
|
@ -103,7 +104,7 @@ class ServerSession(Session):
|
||||||
self.player.save()
|
self.player.save()
|
||||||
|
|
||||||
# add the session-level cmdset
|
# add the session-level cmdset
|
||||||
self.cmdset = LazyLoadHandler(self, "cmdset", cmdsethandler.CmdSetHandler, True)
|
self.cmdset = CmdSetHandler(self, True)
|
||||||
|
|
||||||
def at_disconnect(self):
|
def at_disconnect(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -198,7 +199,7 @@ class ServerSession(Session):
|
||||||
else:
|
else:
|
||||||
text = self.player.nicks.nickreplace(text,
|
text = self.player.nicks.nickreplace(text,
|
||||||
categories=("inputline", "channels"), include_player=False)
|
categories=("inputline", "channels"), include_player=False)
|
||||||
cmdhandler.cmdhandler(self, text, callertype="session", sessid=self.sessid)
|
cmdhandler(self, text, callertype="session", sessid=self.sessid)
|
||||||
self.update_session_counters()
|
self.update_session_counters()
|
||||||
if "oob" in kwargs:
|
if "oob" in kwargs:
|
||||||
# handle oob instructions
|
# handle oob instructions
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ import weakref
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db.models import Q
|
|
||||||
from django.utils.encoding import smart_str
|
from django.utils.encoding import smart_str
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
|
||||||
|
|
@ -48,7 +47,7 @@ from src.typeclasses import managers
|
||||||
from src.locks.lockhandler import LockHandler
|
from src.locks.lockhandler import LockHandler
|
||||||
from src.utils import logger
|
from src.utils import logger
|
||||||
from src.utils.utils import (
|
from src.utils.utils import (
|
||||||
make_iter, is_iter, to_str, inherits_from, LazyLoadHandler)
|
make_iter, is_iter, to_str, inherits_from, lazy_property)
|
||||||
from src.utils.dbserialize import to_pickle, from_pickle
|
from src.utils.dbserialize import to_pickle, from_pickle
|
||||||
from src.utils.picklefield import PickledObjectField
|
from src.utils.picklefield import PickledObjectField
|
||||||
|
|
||||||
|
|
@ -132,12 +131,9 @@ class Attribute(SharedMemoryModel):
|
||||||
# Database manager
|
# Database manager
|
||||||
objects = managers.AttributeManager()
|
objects = managers.AttributeManager()
|
||||||
|
|
||||||
# Lock handler self.locks
|
@lazy_property
|
||||||
def __init__(self, *args, **kwargs):
|
def locks(self):
|
||||||
"Initializes the parent first -important!"
|
return LockHandler(self)
|
||||||
#SharedMemoryModel.__init__(self, *args, **kwargs)
|
|
||||||
super(Attribute, self).__init__(*args, **kwargs)
|
|
||||||
self.locks = LazyLoadHandler(self, "locks", LockHandler)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"Define Django meta options"
|
"Define Django meta options"
|
||||||
|
|
@ -801,15 +797,33 @@ class TypedObject(SharedMemoryModel):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
"We must initialize the parent first - important!"
|
"We must initialize the parent first - important!"
|
||||||
super(TypedObject, self).__init__(*args, **kwargs)
|
super(TypedObject, self).__init__(*args, **kwargs)
|
||||||
#SharedMemoryModel.__init__(self, *args, **kwargs)
|
|
||||||
_SA(self, "dbobj", self) # this allows for self-reference
|
_SA(self, "dbobj", self) # this allows for self-reference
|
||||||
_SA(self, "locks", LazyLoadHandler(self, "locks", LockHandler))
|
|
||||||
_SA(self, "tags", LazyLoadHandler(self, "tags", TagHandler))
|
# initialize all handlers in a lazy fashion
|
||||||
_SA(self, "aliases", LazyLoadHandler(self, "aliases", AliasHandler))
|
@lazy_property
|
||||||
_SA(self, "permissions", LazyLoadHandler(self, "permissions", PermissionHandler))
|
def attributes(self):
|
||||||
_SA(self, "attributes", LazyLoadHandler(self, "attributes", AttributeHandler))
|
return AttributeHandler(self)
|
||||||
_SA(self, "nattributes", NAttributeHandler(self))
|
|
||||||
#_SA(self, "nattributes", LazyLoadHandler(self, "nattributes", NAttributeHandler))
|
@lazy_property
|
||||||
|
def locks(self):
|
||||||
|
return LockHandler(self)
|
||||||
|
|
||||||
|
@lazy_property
|
||||||
|
def tags(self):
|
||||||
|
return TagHandler(self)
|
||||||
|
|
||||||
|
@lazy_property
|
||||||
|
def aliases(self):
|
||||||
|
return AliasHandler(self)
|
||||||
|
|
||||||
|
@lazy_property
|
||||||
|
def permissions(self):
|
||||||
|
return PermissionHandler(self)
|
||||||
|
|
||||||
|
@lazy_property
|
||||||
|
def nattributes(self):
|
||||||
|
return NAttributeHandler(self)
|
||||||
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
|
|
@ -1276,13 +1290,10 @@ class TypedObject(SharedMemoryModel):
|
||||||
if not TICKER_HANDLER:
|
if not TICKER_HANDLER:
|
||||||
from src.scripts.tickerhandler import TICKER_HANDLER
|
from src.scripts.tickerhandler import TICKER_HANDLER
|
||||||
TICKER_HANDLER.remove(self) # removes objects' all ticker subscriptions
|
TICKER_HANDLER.remove(self) # removes objects' all ticker subscriptions
|
||||||
if not isinstance(_GA(self, "permissions"), LazyLoadHandler):
|
_GA(self, "permissions").clear()
|
||||||
_GA(self, "permissions").clear()
|
_GA(self, "attributes").clear()
|
||||||
if not isinstance(_GA(self, "attributes"), LazyLoadHandler):
|
_GA(self, "aliases").clear()
|
||||||
_GA(self, "attributes").clear()
|
if hasattr(self, "nicks"):
|
||||||
if not isinstance(_GA(self, "aliases"), LazyLoadHandler):
|
|
||||||
_GA(self, "aliases").clear()
|
|
||||||
if hasattr(self, "nicks") and not isinstance(_GA(self, "nicks"), LazyLoadHandler):
|
|
||||||
_GA(self, "nicks").clear()
|
_GA(self, "nicks").clear()
|
||||||
_SA(self, "_cached_typeclass", None)
|
_SA(self, "_cached_typeclass", None)
|
||||||
_GA(self, "flush_from_cache")()
|
_GA(self, "flush_from_cache")()
|
||||||
|
|
|
||||||
|
|
@ -1060,67 +1060,38 @@ def deepsize(obj, max_depth=4):
|
||||||
size = getsizeof(obj) + sum([p[1] for p in sizedict.values()])
|
size = getsizeof(obj) + sum([p[1] for p in sizedict.values()])
|
||||||
return size
|
return size
|
||||||
|
|
||||||
# lazy load handlers
|
# lazy load handler
|
||||||
|
_missing = object()
|
||||||
import weakref
|
class lazy_property(object):
|
||||||
class LazyLoadHandler(object):
|
|
||||||
"""
|
"""
|
||||||
Load handlers only when they are actually accessed
|
Delays loading of property until first access. Credit goes to
|
||||||
|
the Implementation in the werkzeug suite:
|
||||||
|
http://werkzeug.pocoo.org/docs/utils/#werkzeug.utils.cached_property
|
||||||
|
|
||||||
|
This should be used as a decorator in a class and is in Evennia
|
||||||
|
mainly used to lazy-load handlers:
|
||||||
|
|
||||||
|
@lazy_property
|
||||||
|
def attributes(self):
|
||||||
|
return AttributeHandler(self)
|
||||||
|
|
||||||
|
Once initialized, the AttributeHandler will be available
|
||||||
|
as a property "attributes" on the object.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, obj, name, cls, *args):
|
def __init__(self, func, name=None, doc=None):
|
||||||
"""
|
"Store all properties for now"
|
||||||
Set up a delayed load of a class. The 'name' must be named the
|
self.__name__ = name or func.__name__
|
||||||
same as the variable to which the LazyLoadHandler is assigned.
|
self.__module__ = func.__module__
|
||||||
"""
|
self.__doc__ = doc or func.__doc__
|
||||||
_SA(self, "obj", weakref.ref(obj))
|
self.func = func
|
||||||
_SA(self, "name", name)
|
|
||||||
_SA(self, "cls", cls)
|
|
||||||
_SA(self, "args", args)
|
|
||||||
|
|
||||||
def _instantiate(self):
|
def __get__(self, obj, type=None):
|
||||||
"""
|
"Triggers initialization"
|
||||||
Initialize handler as cls(obj, *args)
|
if obj is None:
|
||||||
"""
|
return self
|
||||||
obj = _GA(self, "obj")()
|
value = obj.__dict__.get(self.__name__, _missing)
|
||||||
instance = _GA(self, "cls")(weakref.proxy(obj), *_GA(self, "args"))
|
if value is _missing:
|
||||||
_SA(obj, _GA(self, "name"), instance)
|
value = self.func(obj)
|
||||||
return instance
|
obj.__dict__[self.__name__] = value
|
||||||
|
return value
|
||||||
def __getattribute__(self, name):
|
|
||||||
"""
|
|
||||||
Access means loading the handler
|
|
||||||
"""
|
|
||||||
return getattr(_GA(self, "_instantiate")(), name)
|
|
||||||
|
|
||||||
def __setattr__(self, name, value):
|
|
||||||
"""
|
|
||||||
Setting means loading the handler
|
|
||||||
"""
|
|
||||||
setattr(_GA(self, "_instantiate")(), name, value)
|
|
||||||
|
|
||||||
def __delattr__(self, name):
|
|
||||||
"""
|
|
||||||
Deleting also triggers loading of handler
|
|
||||||
"""
|
|
||||||
delattr(_GA(self, "_instantiate")(), name)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return repr(_GA(self, "_instantiate")())
|
|
||||||
def __str__(self):
|
|
||||||
return str(_GA(self, "_instantiate")())
|
|
||||||
def __unicode__(self):
|
|
||||||
return str(_GA(self, "_instantiate")())
|
|
||||||
|
|
||||||
class NonWeakLazyLoadHandler(LazyLoadHandler):
|
|
||||||
"""
|
|
||||||
Variation of LazyLoadHandler that does not
|
|
||||||
create a weak reference when initiating.
|
|
||||||
"""
|
|
||||||
def _instantiate(self):
|
|
||||||
"""
|
|
||||||
Initialize handler as cls(obj, *args)
|
|
||||||
"""
|
|
||||||
obj = _GA(self, "obj")()
|
|
||||||
instance = _GA(self, "cls")(obj, *_GA(self, "args"))
|
|
||||||
_SA(obj, _GA(self, "name"), instance)
|
|
||||||
return instance
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue