467,135 Members | 1,181 Online
Bytes | Developer Community
Ask Question

Home New Posts Topics Members FAQ

Post your question to a community of 467,135 developers. It's quick & easy.

UnboundLocalError on shadowed import

I was going to file this as a bug in the tracker, but maybe it's not really
a bug. Poor Python code does what I consider to be unexpected. What's your
opinion?

With Python 2.3.2 (but also happens with 2.2)

An import within a function that shadows a global import can raise
UnboundLocalError. I think the real problem is that the the local 'import
sys' is seen as occuring after the use of sys within this function, even
though sys is imported in global scope.

import sys

def t():
sys.exit(0)
import sys
sys.exit(1)

if __name__ == "__main__":
t()

I noticed this when editing an existing module. After adding 'import sys' at
the global level and then using sys in the function (and not noticing that
this function imported sys locally below), I got the UnboundLocalError

python2.3 ~/temp/test.py
Traceback (most recent call last):
File "/home/bkc/temp/test.py", line 10, in ?
t()
File "/home/bkc/temp/test.py", line 4, in t
sys.exit(0)
UnboundLocalError: local variable 'sys' referenced before assignment

This is not much of an error. The local import is superfluous, and no one
would really write code this way. But should it raise an exception?

--
Novell DeveloperNet Sysop #5

_


Jul 18 '05 #1
  • viewed: 2348
Share:
3 Replies
Brad Clements wrote:
python2.3 ~/temp/test.py
Traceback (most recent call last):
File "/home/bkc/temp/test.py", line 10, in ?
t()
File "/home/bkc/temp/test.py", line 4, in t
sys.exit(0)
UnboundLocalError: local variable 'sys' referenced before assignment

This is not much of an error. The local import is superfluous, and no one
would really write code this way. But should it raise an exception?


It "has to" raise an exception. The use of "sys" inside the function
is local (because you assign to it, because "import sys" is effectively
an assignment). Locals are not handled quite the same as other names,
as you know -- they are turned into index lookups in a list instead of
hash lookups in a dictionary. The interpreter can't know that your use
of sys.exit(0) is supposed to refer to the global sys, because all uses
of "sys" are really just "local variable number 3" or something like
that inside the function.

Basically, "don't do that" is about the best you'll get, I think.

-Peter
Jul 18 '05 #2
Peter Hansen wrote:
It "has to" raise an exception. The use of "sys" inside the function
is local (because you assign to it, because "import sys" is effectively
an assignment). Locals are not handled quite the same as other names,
as you know -- they are turned into index lookups in a list instead of
hash lookups in a dictionary. The interpreter can't know that your use
of sys.exit(0) is supposed to refer to the global sys, because all uses
of "sys" are really just "local variable number 3" or something like
that inside the function.

Basically, "don't do that" is about the best you'll get, I think.


Well, just for the sake of it, there still is the obvious option of
adding the line "global sys" before sys.exit(0) to tell the interpreter
to use the "globally imported sys".

--
Vincent Wehren
Jul 18 '05 #3
vincent wehren wrote:
Peter Hansen wrote:
It "has to" raise an exception. The use of "sys" inside the function
is local (because you assign to it, because "import sys" is effectively
an assignment). Locals are not handled quite the same as other names,
as you know -- they are turned into index lookups in a list instead of
hash lookups in a dictionary. The interpreter can't know that your use
of sys.exit(0) is supposed to refer to the global sys, because all uses
of "sys" are really just "local variable number 3" or something like
that inside the function.

Basically, "don't do that" is about the best you'll get, I think.


Well, just for the sake of it, there still is the obvious option of
adding the line "global sys" before sys.exit(0) to tell the interpreter
to use the "globally imported sys".


Which basically amounts to "not doing that". ;-) You're right...
Jul 18 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

6 posts views Thread by Alex Gittens | last post: by
8 posts views Thread by David Bear | last post: by
15 posts views Thread by Paddy | last post: by
2 posts views Thread by Matthew Franz | last post: by
2 posts views Thread by Konstantinos Pachopoulos | last post: by
reply views Thread by Terry Reedy | last post: by
1 post views Thread by AmeL | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.