> We were discussing something along these lines a while ago, and I
> never saw anything truly satisfactory - there's no easy way to handle
> a missing name by returning a value (comparably to __getattr__), you
> have to catch it and then try to re-execute the failing code, which
> isn't perfect. How does yours work? Or was it one of the ones that was
> mentioned last time?
Just like that. I've attached a copy. As you said, I'm sure it's not
perfect, but it's handy in precisely those interactive interpreter
cases when *dope slap* you forgot to import a standard module before
launching into a block of code.
Skip
"""
autoload - load common symbols automatically on demand
When a NameError is raised attempt to find the name in a couple places.
Check to see if it's a name in a list of commonly used modules. If it's
found, import the name. If it's not in the common names try importing it.
In either case (assuming the imports succeed), reexecute the code in the
original context.
"""
import sys, traceback, re
_common = {}
# order important - most important needs to be last - os.path is chosen over
# sys.path for example
for mod in "sys os math xmlrpclib".split():
m = __import__(mod)
try:
names = m.__all__
except AttributeError:
names = dir(m)
names = [n for n in names if not n.startswith("_") and n.upper() != n]
for n in names:
_common[n] = mod
def _exec(import_stmt, tb):
f_locals = tb.tb_frame.f_locals
f_globals = tb.tb_frame.f_globals
sys.excepthook = _eh
try:
exec import_stmt in f_locals, f_globals
exec tb.tb_frame.f_code in f_locals, f_globals
finally:
sys.excepthook = _autoload_exc
def _autoload_exc(ty, va, tb):
## if ty != ImportError:
## traceback.print_exception(ty, va, tb)
## return
mat = re.search("name '([^']*)' is not defined", va.args[0])
if mat is not None:
name = mat.group(1)
if name in _common:
mod = _common[name]
print >> sys.stderr, "found", name, "in", mod, "module"
_exec("from %s import %s" % (mod, name), tb)
else:
print >> sys.stderr, "autoloading", name
_exec("import %s" % name, tb)
else:
traceback.print_exception(ty, va, tb)
_eh = sys.excepthook
sys.excepthook = _autoload_exc
--
https://mail.python.org/mailman/listinfo/python-list