bettere errors in custom_import, thanks Michele

This commit is contained in:
mdipierro
2012-10-14 14:20:12 -05:00
parent 5a0ebb7d8c
commit 648cb296e6
2 changed files with 25 additions and 17 deletions
+1 -1
View File
@@ -1 +1 @@
Version 2.1.0 (2012-10-14 14:16:37) dev Version 2.1.0 (2012-10-14 14:20:09) dev
+24 -16
View File
@@ -9,11 +9,11 @@ import threading
import traceback import traceback
from gluon import current from gluon import current
NAIVE_IMPORTER = __builtin__.__import__ NATIVE_IMPORTER = __builtin__.__import__
TRACK_CHANGES = False TRACK_CHANGES = False
INVALID_MODULES = set(sys.modules.keys()).union(('','gluon','applications','custom_import')) INVALID_MODULES = set(sys.modules.keys()).union(('','gluon','applications','custom_import'))
# backward compatibility API # backward compatibility API
def custom_import_install(): def custom_import_install():
__builtin__.__import__ = custom_importer __builtin__.__import__ = custom_importer
@@ -22,14 +22,17 @@ def track_changes(track=True):
global TRACK_CHANGES global TRACK_CHANGES
TRACK_CHANGES = track TRACK_CHANGES = track
def is_tracking_changes(): def is_tracking_changes():
return TRACK_CHANGES return TRACK_CHANGES
class CustomImportException(ImportError):
pass
def custom_importer(name, globals=None, locals=None, fromlist=None, level=-1): def custom_importer(name, globals=None, locals=None, fromlist=None, level=-1):
""" """
The web2py custom importer. Like the standard Python importer but it The web2py custom importer. Like the standard Python importer but it
tries to transform import statements as something like tries to transform import statements as something like
"import applications.app_name.modules.x". "import applications.app_name.modules.x".
If the import failed, fall back on naive_importer If the import failed, fall back on naive_importer
""" """
@@ -37,13 +40,14 @@ def custom_importer(name, globals=None, locals=None, fromlist=None, level=-1):
locals = locals or {} locals = locals or {}
fromlist = fromlist or [] fromlist = fromlist or []
base_importer = TRACK_IMPORTER if TRACK_CHANGES else NAIVE_IMPORTER base_importer = TRACK_IMPORTER if TRACK_CHANGES else NATIVE_IMPORTER
# if not relative and not from applications: # if not relative and not from applications:
if hasattr(current,'request') \ if hasattr(current,'request') \
and level<=0 \ and level<=0 \
and not name.split('.')[0] in INVALID_MODULES \ and not name.split('.')[0] in INVALID_MODULES \
and isinstance(globals, dict): and isinstance(globals, dict):
import_tb = None
try: try:
items = current.request.folder.split(os.path.sep) items = current.request.folder.split(os.path.sep)
if not items[-1]: items = items[:-1] if not items[-1]: items = items[:-1]
@@ -52,23 +56,27 @@ def custom_importer(name, globals=None, locals=None, fromlist=None, level=-1):
# import like "import x" or "import x.y" # import like "import x" or "import x.y"
result = None result = None
for itemname in name.split("."): for itemname in name.split("."):
new_mod = base_importer(
modules_prefix, globals,locals, [itemname], level)
try:
result = result or new_mod.__dict__[itemname]
except KeyError, e:
raise ImportError, 'Cannot import module %s' % str(e)
modules_prefix += "." + itemname modules_prefix += "." + itemname
base_importer(
modules_prefix, globals,locals, [], level)
return result return result
else: else:
# import like "from x import a, b, ..." # import like "from x import a, b, ..."
pname = modules_prefix + "." + name pname = modules_prefix + "." + name
return base_importer(pname, globals, locals, fromlist, level) return base_importer(pname, globals, locals, fromlist, level)
except ImportError, e1: except ImportError, e1:
pass # the module does not exist import_tb = sys.exc_info()[2]
try:
return NATIVE_IMPORTER(name,globals,locals,fromlist,level)
except ImportError, e3:
raise ImportError, e1, import_tb.tb_next # there an import error in the module
except Exception, e2: except Exception, e2:
raise e2 # there is an error in the module raise e2 # there is an error in the module
return NAIVE_IMPORTER(name,globals,locals,fromlist,level) finally:
if import_tb:
import_tb = None
return NATIVE_IMPORTER(name,globals,locals,fromlist,level)
class TrackImporter(object): class TrackImporter(object):
@@ -96,7 +104,7 @@ class TrackImporter(object):
# Check the date and reload if needed: # Check the date and reload if needed:
self._update_dates(name, globals, locals, fromlist, level) self._update_dates(name, globals, locals, fromlist, level)
# Try to load the module and update the dates if it works: # Try to load the module and update the dates if it works:
result = NAIVE_IMPORTER(name, globals, locals, fromlist, level) result = NATIVE_IMPORTER(name, globals, locals, fromlist, level)
# Module maybe loaded for the 1st time so we need to set the date # Module maybe loaded for the 1st time so we need to set the date
self._update_dates(name, globals, locals, fromlist, level) self._update_dates(name, globals, locals, fromlist, level)
return result return result
@@ -152,7 +160,7 @@ class TrackImporter(object):
mod_name = module.__name__ mod_name = module.__name__
del sys.modules[mod_name] # Delete the module del sys.modules[mod_name] # Delete the module
# Reload the module: # Reload the module:
NAIVE_IMPORTER(mod_name, globals, locals, [], level) NATIVE_IMPORTER(mod_name, globals, locals, [], level)
else: else:
reload(module) reload(module)
self.THREAD_LOCAL._modules_loaded.add(module) self.THREAD_LOCAL._modules_loaded.add(module)