Hooking exceptions outside of call stack
Warren Stringer
warren at muse.com
Sun Jun 10 17:40:08 EDT 2007
Hey Josiah,
I just spent a couple hours with your example, and it explains a lot. Some
of your interactive session got garbled, so am reposting your
merged_namespace example, with tweaks:
#---------------------------------------------------------
def merged_namespace(*ns):
try:
__builtins__
namespaces = ns + (globals(),__builtins__.__dict__)
except NameError:
namespaces = ns + (globals(),__builtin__)
ns = {}
for i in reversed(namespaces):
ns.update(i)
return ns
def foo():
print type(globals())
print a.b[c] #works!
return
#------------------------------------------
# was having trouble with embedded classes
# so, I tried this to track down the problem
class a(object):
def __init__(self): print 'init a'
class b(object):
def __init__(self): print 'init b'
class c(object):
def __init__(self): print 'init c'
pass
aa = a() # only prints 'init a', oops
# so, starting with this:
class A(dict):
def __getattr__(self, name):
# here's where a namespace resolver might go
return self[name]
def __getitem__(self,key):
return key # useless, but simple
a = A() # build from scratch
a.__dict__['b'] = A()
a.b.__dict__['c'] = A()
print a.b[a.b.c] # works as expected
#print a.b[c] # NameError: name 'c' is not defined
#-------------------------
# back to Josiah's example
ns = merged_namespace(a.b.__dict__)
foo2 = type(foo)(foo.func_code, ns, foo.func_name, foo.func_defaults,
foo.func_closure)
foo2()
#---------------------------------------------------------
As I was tracing through merged_namespace, I noticed how large resulting
dict is. Too, bad there isn't an equivalent namespace resolution order, as
the there is for methods (or, is there? Am not sure where/how locals are
managed). Then a tupple could be passed to `foo2 = type(foo)(foo.func_code,
namespace, ...)`
With a mro-style namespace, __getattr__ might be able to change namespaces,
on the fly. Too much of a performance hit? Could be. Fortunately, your
example precludes the performance question. Thanks
"Restartable exceptions", as Jean-Paul Calderone called it, might have
yielded results. But searching on his specific phrase yielded a long
discussion (http://www.python.org/search/hypermail/python-1994q2/0425.html)
that illuminates the implausibility of this approach in Python.
So, am replacing `a.b[c]` with `f(a.b,'c')`. The user still can type
"a.b[c]" but, no longer at the python prompt. Oh well.
Thanks again,
\~/
More information about the Python-list
mailing list