Re: Multi-line string extension ( upglobals, uplocals )

Tim Peters (
Tue, 19 Apr 94 23:42:35 -0400

> > [tim, suggesting uplocals/upglobals functions]

> [steve, explains how to force an exception and suck up the caller's
> namespaces via the tb_frame component of a traceback object]

Alas, that doesn't work for locals; the reason was hinted at in:

> > Insisting on returning the _actual_ namespaces would probably be an
> > implementation nightmare (for locals, since they're not ordinarily
> > maintained in genuine dicts anymore, & that's a feature).

If you run this chunk of code:

def uplevels1():
global testlocals
import sys
1 + '' # make an error happen
except: # get caller's frame
frame = sys.exc_traceback.tb_frame.f_back
testlocals = frame.f_locals # caller's locals

def test():
i, j, k = 1, 2, 3
print 'in test'
print 'locals =', testlocals

print 'back from test'
print 'locals =', testlocals

You get this output:

in test
locals = {}
back from test
locals = {'j': 2, 'i': 1, 'k': 3}

I.e., you _can_ capture locals via this trick -- but only _after_ the
function to which they're local is no longer active!

I generally view frame & traceback objects as "off limits", because they
reach deep into the accidents of the current implementation. The "real
reason" f_locals doesn't work the way we might expect in the above is
because Guido improved the implementation of locals in a way that
_happened_ to render the f_locals component of a frame object
meangingless most of the times I might peek at it.

And I'm not willing to call that "a bug", especially since Guido has said
that the _intent_ of giving access to the accidents of implementation was
to enable writing debuggers & other such implementation-dependent tools.

So if there's a good case to be made for providing general-purpose access
to some key abstractions (like local and global namespaces) _underlying_
the implementation, I think it should be done via documented functions
that can reasonably promise to keep the abstract _view_ consistent across
implementations. Accessing data components of low-level runtime-system
objects directly can be powerful, but the few times I do that I never
expect it to work in the next release.

In this specific case, the code to materialize the current implementation
of local namespaces into their older implementation as dicts already
exists, and the suggestion to add an "uplocals" builtin is really (a)
suggesting that a way to get at that code from Python be provided, and
(b) requesting that no matter how much the implementation may change in
the future, Python always provide a way to grant (at least read-only)
access to local namespaces "as if" they were dicts.

Ditto for global namespaces too, if their implementation is in danger of
being sped up <wink>.

trying-to-make-it-respectable-for-us-to-sin-in-public-ly y'rs - tim

Tim Peters
not speaking for Kendall Square Research Corp