Issue 1387650: weird behavior when assigning locals() to a variable (original) (raw)

Issue1387650

Created on 2005-12-22 00:04 by sambayer, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (4)
msg27123 - (view) Author: Samuel Bayer (sambayer) Date: 2005-12-22 00:04
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.
msg27124 - (view) Author: Samuel Bayer (sambayer) Date: 2005-12-22 00:25
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...
msg27125 - (view) Author: Neal Norwitz (nnorwitz) * (Python committer) Date: 2005-12-22 05:48
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.
msg27126 - (view) Author: Samuel Bayer (sambayer) Date: 2005-12-22 13:24
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."
History
Date User Action Args
2022-04-11 14:56:14 admin set github: 42714
2005-12-22 00:04:14 sambayer create