original) (raw)
(On Mon, 9 May 2011, Eli Bendersky wrote:
Extrapolating from your suggestion, you're saying before a \*possible\* assignment it will be treated as global, and after a \*possible\* assignment it will be treated as local?x = 5
def foo ():
� � � print (x)
� � � if bar ():
� � � � � � � x = 1
� � � print (x)
I wish you'd annotate this code sample, what do you intend it to
demonstrate?
It probably shows the original complaint even more strongly. As for being a
problem with the suggested solution, I suppose you're right, although it
doesn't make it much different. Still, before a \*possible\* assignment to
'x', it should be loaded as LOAD\_NAME since it was surely not bound as
local, yet.
But surely:
print (x)
if False:
� � � �x = 1
print (x)
Alright, I now understand the problems with the suggestion. Indeed, conditional assignments that are only really resolved at runtime are the big stumbling block here.
However, maybe the error message/reporting can still be improved?
ISTM the UnboundLocalError exception gets raised only in those weird and confusing cases. After all, why would Python decide an access to some name is to a local? Only if it found an assignment to that local in the scope. But that assignment clearly didn't happen yet, so the error is thrown. So cases like these:
x = 2
def foo1():
� x += 1
def foo2():
� print(x)
� x = 10
def foo3():
� if something_that_didnot_happen:
��� x = 10
� print(x)
All belong to the category.
With an unlimited error message length it could make sense to say "Hey, I see 'x' may be assigned in this scope, so I mark it local. But this access to 'x' happens before assignment - so ERROR". This isn't realistic, of course, so I'm wondering:
1. Does this error message (although unrealistic) capture all possible appearances of UnboundLocalError?
2. If the answer to (1) is yes - could it be usefully shortened to be clearer than the current "local variable referenced before assignment"?
This may not be possible, of course, but it doesn't harm trying :-)
Eli
�