[pypy-dev] bug with vars() in a nested function

Laura Creighton lac at strakt.com
Mon Dec 22 23:16:58 CET 2003

In a message of Mon, 22 Dec 2003 22:23:24 +0100, Alex Martelli writes:
>The implementation of vars() in builtin.py relies on a call to getdictsco
>to return the caller's locals as a dir, but unfortunately that doesn't wo
>when the caller of built-in vars() is a nested function -- nestedscope.py
>overrides fast2locals to ensure setting in self.w_locals the free variabl
>in addition to the locals, and that w_locals is what getdictscope returns
>Apparently this kind of bug must have bitten CPython at some point (or
>at least be suspected!) since the unit-test for vars() looks for it prett
>exactly (that's how I found it, too -- still striving to run as much of t
>CPython unit-test as feasible!) -- basically, it has something like:
>        def test_vars(self):
>            def get_vars_f0():
>                return vars()
>            def get_vars_f2():
>                get_vars_f0()
>                a = 1
>                b = 2
>                return vars()
>            ...
>            self.assertEqual(get_vars_f2(), {'a': 1, 'b': 2})
>where that 'useless' call to get_vars_f0 inside get_vars_f2 serves just
>the purpose of "infecting" the latter with the former name -- and sure
>enough the assertEqual fails because 'get_vars_f0' is reported as being
>a key in the dict returned by get_vars_f2().
>My instinct is to patch this with an optional switch to getdictscope to
>ask for "return the TRUE locals only please" -- but since a vaguely
>analogous patch I had tried to remedy the issue with generators raising
>StopIteration (i.e. "directly attacking the symptom rather than going for
>a more general solution") was criticized, I thought I'd better ask first 
>rather than committing anything yet -- this one IS a rather marginal and
>obscure side issue after all, so for now I'll just mark it as 'XXX TODO'
>and comment it away in the builtin_functions_test.py file (what's one
>Which reminds me: do we have a "known bugs" file/summary, or are
>the infos about known bugs, limitations &c spread around in comments
>and docstrings?  'cause the XXX TODO in the builtin_*_test.py files
>are quite a nifty list of known current bugs and limitations for built-in
>so I wondered if I should collect them in some documentation file...

Please put them someplace and have goals refer to them.

I wonder if this is what we should be using the issue tracker for....

As per your real question -- fast2locals strikes me as a hack,
that needs to be more general, and our understanding of what a
scope would be has been significantly mangled since getdictscope
was written.  Something in me says that we want to do scoping
in some more cleaner way, but I cannot quite envision what it will
be after builtins changes _again_ to be more like a regular module.

I am now looking at our current crop of builtins, and thinking ...
'the only reason you lot are there is because CPython had you there'.
Now that we have hacked the architecture one more time again, grin,
we have something a lot cleaner (for now at any rate) ... I am
pushing for a more elegant definition of builtin, based on a 
pragmatic idea of 'you have to be built in becauswe we cannot make
you any other way'

What of ours make it?  Which cannot be made in app space and why,
given that interp space is dead?  I think that we have gloriously
moved to a place where most of our builtins really do not have to be.
Some sort of execfile sort of thing is all we need.

This is probably wrong, and indicates that my vision is too idealised,
and I miss very real practical problems.  I await more enlightenment.
But I still think that most of our 'builtins' are more 'reimplentations
of CPython builtins, done because CPython doesn't have them so we
couldn't have a working Python without them'.   And we could
implement them as a module.  When we have leftovers, real
problems in converting one object space to another, then things
like getdictscope -- or a more general thing that does this and more
actually -- strikes me as  a thing that belongs __there__.  Scoping
rules strike me as object space 'required things to leave a hook
out for'.

But perhaps I am just confused again, and oversimplifying in my mind.

I await enlightenment.


>pypy-dev at codespeak.net

More information about the Pypy-dev mailing list