Reworked the fix of #769 to be cleaner and using a full import mechanism rather than the pre-module lookup that messed up the unittests.

This commit is contained in:
Griatch 2015-07-07 15:29:28 +02:00
parent 0003868533
commit a8332fe431

View file

@ -63,8 +63,9 @@ can then implement separate sets for different situations. For
example, you can have a 'On a boat' set, onto which you then tack on 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 sys
from imp import find_module, load_module from importlib import import_module
from inspect import trace
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
@ -119,38 +120,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:
if "." in path:
modpath, classname = python_path.rsplit(".", 1)
else:
raise ImportError("The path '%s' is not on the form modulepath.ClassName" % path)
try: try:
# first try to get from cache # 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 cmdsetclass = _CACHED_CMDSETS.get(python_path, None)
cmdsetclass = _CACHED_CMDSETS.get(wanted_cache_key, None)
if not cmdsetclass: if not cmdsetclass:
# check if module exists at all
try: try:
mod_path, classname = python_path.rsplit(".", 1) module = import_module(modpath, package="evennia")
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: except ImportError:
errstring += _("\n(Unsuccessfully tried '%s')." % (python_path)) if len(trace()) > 2:
break # error in module, make sure to not hide it.
module = load_module(modname, *info) exc = sys.exc_info()
mod_path = module.__path__ if hasattr(module, "__path__") else None raise exc[1], None, exc[2]
if not module: else:
# try next suggested path
errstring += _("\n(Unsuccessfully tried '%s')." % python_path)
continue continue
cmdsetclass = module.__dict__[classname] try:
_CACHED_CMDSETS[wanted_cache_key] = cmdsetclass cmdsetclass = getattr(module, classname)
except AttributeError:
if len(trace()) > 2:
# Attribute error within module, don't hide it
exc = sys.exc_info()
raise exc[1], None, exc[2]
else:
errstring += _("\n(Unsuccessfully tried '%s')." % python_path)
continue
_CACHED_CMDSETS[python_path] = cmdsetclass
#instantiate the cmdset (and catch its errors) #instantiate the cmdset (and catch its errors)
if callable(cmdsetclass): if callable(cmdsetclass):
@ -161,18 +163,22 @@ def import_cmdset(path, cmdsetobj, emit_to_obj=None, no_logging=False):
logger.log_trace() logger.log_trace()
errstring += _("\nError loading cmdset {path}: \"{error}\"") errstring += _("\nError loading cmdset {path}: \"{error}\"")
errstring = errstring.format(path=python_path, error=e) errstring = errstring.format(path=python_path, error=e)
break
except KeyError: except KeyError:
logger.log_trace() logger.log_trace()
errstring += _("\nError in loading cmdset: No cmdset class '{classname}' in {path}.") errstring += _("\nError in loading cmdset: No cmdset class '{classname}' in {path}.")
errstring = errstring.format(classname=classname, path=python_path) errstring = errstring.format(classname=classname, path=python_path)
break
except SyntaxError, e: except SyntaxError, e:
logger.log_trace() logger.log_trace()
errstring += _("\nSyntaxError encountered when loading cmdset '{path}': \"{error}\".") errstring += _("\nSyntaxError encountered when loading cmdset '{path}': \"{error}\".")
errstring = errstring.format(path=python_path, error=e) errstring = errstring.format(path=python_path, error=e)
break
except Exception, e: except Exception, e:
logger.log_trace() logger.log_trace()
errstring += _("\nCompile/Run error when loading cmdset '{path}': \"{error}\".") errstring += _("\nCompile/Run error when loading cmdset '{path}': \"{error}\".")
errstring = errstring.format(path=python_path, error=e) errstring = errstring.format(path=python_path, error=e)
break
if errstring: if errstring:
# returning an empty error cmdset # returning an empty error cmdset