[ python-Bugs-1387650 ] weird behavior when assigning locals() to a variable

SourceForge.net noreply at sourceforge.net
Thu Dec 22 14:24:57 CET 2005


Bugs item #1387650, was opened at 2005-12-22 00:04
Message generated for change (Comment added) made by sambayer
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1387650&group_id=5470

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: Python Interpreter Core
Group: Python 2.3
Status: Closed
Resolution: Invalid
Priority: 5
Submitted By: Samuel Bayer (sambayer)
Assigned to: Nobody/Anonymous (nobody)
Summary: weird behavior when assigning locals() to a variable

Initial Comment:
Tried this on Python 2.3.3, under Redhat Linux
Enterprise 3, and on Python 2.3.5, under MacOS X
10.4.3. Don't have access to 2.4 anywhere, so I can't
test it, but I took a look at the bug queue and can't
find any reference to this problem.

The following function yields a KeyError when run:

def foo():
    b = locals()
    c = 5
    print b["c"]

The following function does not:

def foo():
    b = locals()
    c = 5
    locals()
    print b["c"]

There's no typo there. After referencing locals()
again, without updating the value of b, the printout works.

Note that b and locals(), as I believe is intended, are
identical:

def foo():
    b = locals()
    c = 5
    print id(b)
    print b.has_key()
    print id(locals())
    print b.has_key()

yields, when run:

>>> foo()
285984
False
285984
True

This has GOT to be a bug. 

----------------------------------------------------------------------

>Comment By: Samuel Bayer (sambayer)
Date: 2005-12-22 13:24

Message:
Logged In: YES 
user_id=40146

This morning, as I thought about it some more, I had some vain hope that the 
__getitem__ method of that particular dictionary could be updated to refresh 
the dictionary, but after trolling through the source a little, I see that it's 
really just a regular dictionary, and it doesn't know anything about where it 
came from. Would it be dangerous to add the current stack frame to the 
locals() dictionary as a value like __frame___? Perhaps that would screw up the 
garbage collection by adding a circular reference.

In any case, the current documentation for locals() reads:

"Update and return a dictionary representing the current local symbol table. 
Warning: The contents of this dictionary should not be modified; changes 
may not affect the values of local variables used by the interpreter."

I'd say something like

"Update and return a dictionary representing the current local symbol table. 
Warnings: The contents of this dictionary should not be modified; changes 
may not affect the values of local variables used by the interpreter. Also, this 
dictionary is not guaranteed to be synchronized with the actual local 
environment; if the local symbol table changes between the time you retrieve 
the value of locals() and the time you use it, you won't see the changes."

----------------------------------------------------------------------

Comment By: Neal Norwitz (nnorwitz)
Date: 2005-12-22 05:48

Message:
Logged In: YES 
user_id=33168

If you have suggestions for how we can improve the doc, let
us know.  I'll close this bug report since you seem to agree
it's not a bug.

----------------------------------------------------------------------

Comment By: Samuel Bayer (sambayer)
Date: 2005-12-22 00:25

Message:
Logged In: YES 
user_id=40146

OK, it doesn't got to be a bug. After staring at the
documentation for locals(), I realize that locals() is only
updated when it's called again. 

So it's not a bug, but it is a little odd. It's the only
namespace-like object you can't reliably use as a format
string argument. Consider the following:

>>> b = globals()
>>> c = 5
>>> print "%(c)d" % b

This prints the expected value. Ditto this:

>>> Class Foo: pass
>>> a = Foo(); b = a.__dict__
>>> a.c = 5
>>> print "%(c)d" % b

Only with locals(), inside a function, does this pattern
fail. I imagine it would be expensive to make work, though.

Never mind...

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1387650&group_id=5470


More information about the Python-bugs-list mailing list