Added more logics for pre-lookups of cmdset paths at any nested package depth. Resolves #769.

This commit is contained in:
Griatch 2015-07-07 13:31:17 +02:00
parent 45e0785c8e
commit 0003868533

View file

@ -64,7 +64,7 @@ example, you can have a 'On a boat' set, onto which you then tack on
the 'Fishing' set. Fishing from a boat? No problem! the 'Fishing' set. Fishing from a boat? No problem!
""" """
import traceback import traceback
from imp import find_module from imp import find_module, load_module
from django.conf import settings from django.conf import settings
from evennia.utils import logger, utils from evennia.utils import logger, utils
from evennia.commands.cmdset import CmdSet from evennia.commands.cmdset import CmdSet
@ -99,6 +99,7 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False):
path - This is the full path to the cmdset object on python dot-form path - This is the full path to the cmdset object on python dot-form
Args: Args:
path (str): The path to the command set to load.
cmdsetobj (CmdSet): The database object/typeclass on which this cmdset is to be cmdsetobj (CmdSet): The database object/typeclass on which this cmdset is to be
assigned (this can be also channels and exits, as well as players assigned (this can be also channels and exits, as well as players
but there will always be such an object) but there will always be such an object)
@ -108,8 +109,9 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False):
This can be useful if import_cmdset is just used to check if This can be useful if import_cmdset is just used to check if
this is a valid python path or not. this is a valid python path or not.
Returns: Returns:
cmdset (CmdSet): If an error was encountered, `commands.cmdsethandler._ErrorCmdSet` cmdset (CmdSet): The imported command set. If an error was
is returned for the benefit of the handler. encountered, `commands.cmdsethandler._ErrorCmdSet` is returned
for the benefit of the handler.
""" """
python_paths = [path] + ["%s.%s" % (prefix, path) python_paths = [path] + ["%s.%s" % (prefix, path)
@ -117,30 +119,39 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False):
errstring = "" errstring = ""
for python_path in python_paths: for python_path in python_paths:
# check if module exists at all
modulepath, classname = python_path.rsplit('.', 1)
if python_path.count('.') < 2:
extrapath, modulename = "", modulepath
else:
extrapath, modulename = modulepath.rsplit('.', 1)
try:
find_module(modulename, [extrapath])
except ImportError:
# module not found, try next
errstring += _("\n(Unsuccessfully tried '%s.' + '%s.%s')." % (extrapath, modulename, classname))
continue
try: try:
# first try to get from cache
#print "importing %s: _CACHED_CMDSETS=%s" % (python_path, _CACHED_CMDSETS) #print "importing %s: _CACHED_CMDSETS=%s" % (python_path, _CACHED_CMDSETS)
wanted_cache_key = python_path wanted_cache_key = python_path
cmdsetclass = _CACHED_CMDSETS.get(wanted_cache_key, None) cmdsetclass = _CACHED_CMDSETS.get(wanted_cache_key, None)
if not cmdsetclass: if not cmdsetclass:
#print "cmdset '%s' not in cache. Reloading %s on %s." % (wanted_cache_key, python_path, cmdsetobj)
# Not in cache. Reload from disk. # check if module exists at all
#modulepath, classname = python_path.rsplit('.', 1) try:
module = __import__(modulepath, fromlist=[True]) mod_path, classname = python_path.rsplit(".", 1)
except ValueError:
# malformed input.
errstring += _("\n(Malformed path '%s' (requires at least modulename.Classname).)" % python_path)
continue
path_tree = mod_path.split(".")
mod_path = None
module = None
while path_tree:
# traverse the tree
modname = path_tree.pop(0)
try:
info = find_module(modname, mod_path)
except ImportError:
errstring += _("\n(Unsuccessfully tried '%s')." % (python_path))
break
module = load_module(modname, *info)
mod_path = module.__path__ if hasattr(module, "__path__") else None
if not module:
continue
cmdsetclass = module.__dict__[classname] cmdsetclass = module.__dict__[classname]
_CACHED_CMDSETS[wanted_cache_key] = cmdsetclass _CACHED_CMDSETS[wanted_cache_key] = cmdsetclass
#instantiate the cmdset (and catch its errors) #instantiate the cmdset (and catch its errors)
if callable(cmdsetclass): if callable(cmdsetclass):
cmdsetclass = cmdsetclass(cmdsetobj) cmdsetclass = cmdsetclass(cmdsetobj)