Why I need to declare import as global in function

D

didier.doussaud

I have a stange side effect in my project :

in my project I need to write "gobal" to use global symbol :

....
import math
....
def f() :
global math # necessary ?????? else next line generate an error
message ?????
print math.pi

(the problem is for all global module symbol)

I have certainly change somthing in my project, but I can't find what ?

(just a small program wort fine without this global of course)

Can anybody help me : where can I search the mistake in my project ?
 
F

Fredrik Lundh

I have a stange side effect in my project :

in my project I need to write "gobal" to use global symbol :

...
import math
...
def f() :
global math # necessary ?????? else next line generate an error
message ?????

what error message?
print math.pi

you only need global in this case if you assign to the name somewhere
later in the function (e.g. "math = ..." or "import math" or some other
assignment)

please post the error message (the entire traceback).

</F>
 
T

Tim N. van der Leeuw

Sounds like something, either in your program, in another lib you
imported, or perhaps some extension you recently installed (and which
automatically starts), overrides 'import' (replaces it with it's own
version) -- and forgets to add the imported modules properly to the
globlals?
Or something, some option, that perhaps changes the way that Python
recognizes globals?

If you declare another global variable, then try to use it in your
function, then what's the result?

What Python version do you use?

cheers,

--Tim
 
D

didier.doussaud

the error message :

EXCEPTION RAISED::

Traceback (most recent call last):
File "../tu.py", line 21, in run_tu
execfile( filename )
File "TU_05_010.py", line 8, in ?
import TU_05_tools
File "./TU_05_tools.py", line 4, in ?
f()
File "./TU_05_tools.py", line 2, in f
print math.pi
NameError: global name 'math' is not defined

I have remarq that this problem is raised when I execute code in an
imported module (during importation)

I think I will be able to isolate it and have a simple sample soon ....
 
D

Duncan Booth

wrote:
I have remarq that this problem is raised when I execute code in an
imported module (during importation)

I think I will be able to isolate it and have a simple sample soon ....
Meanwhile, try adding:

import math

to the top of TU_05_tools.py.
 
P

Peter Otten

the error message :

EXCEPTION RAISED::

Traceback (most recent call last):
File "../tu.py", line 21, in run_tu
execfile( filename )
File "TU_05_010.py", line 8, in ?
import TU_05_tools
File "./TU_05_tools.py", line 4, in ?
f()
File "./TU_05_tools.py", line 2, in f
print math.pi
NameError: global name 'math' is not defined

I have remarq that this problem is raised when I execute code in an
imported module (during importation)

I think I will be able to isolate it and have a simple sample soon ....

Random guess: change the execfile() call to

execfile(filename, globals())

or

exec file(filename).read()

If one of the above works, a minimal example of what happens could be

file("tmp.py", "w").write("""
import math
""")

def f():
execfile("tmp.py")
print locals()["math"].pi # 3.14159265359
print math.pi # Error, math looked up in the global
namespace

f()

execfile() puts symbols into the local namespace but keeps the compiler
clueless because it's just an ordinary function, whereas exec triggers the
generation of slightly different bytecode for the enclosing function.

Peter
 
D

Duncan Booth

Peter said:
Random guess: change the execfile() call to

execfile(filename, globals())

or

exec file(filename).read()

That is unlikely to help. The execfile target seems to have been
TU_05_010.py, but the file which cannot access math is TU_05_tools.py
accessed by a normal import, so adding some globals to the execfile call
won't really do anything useful.

Isn't it fun trying to guess the problem in the absence of the code?
 
F

Fredrik Lundh

Duncan said:
That is unlikely to help. The execfile target seems to have been
TU_05_010.py, but the file which cannot access math is TU_05_tools.py
accessed by a normal import, so adding some globals to the execfile call
won't really do anything useful.

Isn't it fun trying to guess the problem in the absence of the code?

given that the NameError occurs on line 2 of the file, inside a function, this
is probably just a misunderstanding of how namespaces work in Python...

</F>
 
P

Peter Otten

Duncan said:
Isn't it fun trying to guess the problem in the absence of the code?

What other reason could there be to forego the sane approach -- stick
'import math' everywhere it might belong?
Those exec/execfile() peculiarities are so much more interesting ;-)

Peter
 
D

didier.doussaud

You're right, the problem is around the usage of "execfile".

But I have still difficulties to get a simple sample.... and have no
enough time to work on it until end of week.

I will post if I resolve my problem or if I can get a simple sample.
 
D

didier.doussaud

I think I understand my problem, but first the sample code extracted to
my project.

Rq : it's an automatic run of unitary test, the names of unitary test
are parameter of main program "imported" file via the "execfile"
function (an usage of "import" instead may be a solution....) :

file run.py :
----------------

def run_ut( test ) :
# to have the problem the execfile MUST be in a function
execfile( test )
run_ut( "ut_00.py" )


file ut_00.py :
--------------------
import math

def f() :
## global math # <-- just decomment this line to avoid error
print "Second access :"
print "\t",math.pi # ERROR

print "First access :"
print "\t",math.pi # OK
f()
 
D

Dennis Lee Bieber

I have remarq that this problem is raised when I execute code in an
imported module (during importation)

I think I will be able to isolate it and have a simple sample soon ....

And does that IMPORTED module start with "import math"?
--
 
D

didier.doussaud

lot's of solutions proposed in the discussion works fine :

file run.py :
----------------
def run_ut( test ) :
# to have the problem the execfile MUST be in a function
# execfile( test ) # ERROR
execfile( test, globals() ) # OK
exec "import ut_00" # OK
exec file(test).read() # OK
run_ut( "ut_00.py" )

Thanks a lor
 
D

didier.doussaud

yes I have imported math in the file I want to use it. But the imported
module "math" is not visible in function without a global instruction.

But the solutions already proposed seems to work file for my sample
program. I will try on my project soon :)
 
D

Duncan Booth

I think I understand my problem, but first the sample code extracted to
my project.

Rq : it's an automatic run of unitary test, the names of unitary test
are parameter of main program "imported" file via the "execfile"
function (an usage of "import" instead may be a solution....) :

file run.py :
----------------

def run_ut( test ) :
# to have the problem the execfile MUST be in a function
execfile( test )
run_ut( "ut_00.py" )


file ut_00.py :
--------------------
import math

def f() :
## global math # <-- just decomment this line to avoid error
print "Second access :"
print "\t",math.pi # ERROR

print "First access :"
print "\t",math.pi # OK
f()

How interesting. Can anyone actually explain the behaviour here?

Without the global statement everything works as I expect: the 'import
math' is executed in the local scope of run_ut, so the function f() doesn't
find it either in its local scope nor in global scope.

Inserting 'global math' at the outer level in ut_00.py (e.g. before the
'import math') also works as I expect: math now becomes a global variable
and is visible to f().

What I really don't understand is why the global statement *inside* f
affects the scope of math outside f. If we had nested functions then a
global variable in an inner function doesn't affect scope in outer
functions. I realise that f() here isn't a nested function, but even so it
looks to me like a bug unless I'm missing something.

(Technically the program is invoking undefined behaviour as the language
reference says that names listed in a global statement must not be defined
in an import statement, but that isn't really relevant since you can
replace the import with an assignment statement and get the same weird
behaviour.)
 
D

Dennis Lee Bieber

yes I have imported math in the file I want to use it. But the imported
module "math" is not visible in function without a global instruction.
The code you just posted shows it, yes... My reading of an earlier
message seemed to imply you had a nested import chain with the "import
math" at the wrong level... Something like:

#file 1
execfile("file 2")

#file 2
import math
import file_3

#file_3
print math.pi
But the solutions already proposed seems to work file for my sample
program. I will try on my project soon :)

Looking at the documentation for "execfile", I can see /how/ the
problem occurs -- but can't determine if this can be considered
"expected".

-=-=-=-=-=-=-
execfile( filename[, globals[, locals]])

This function is similar to the exec statement, but parses a file
instead of a string. It is different from the import statement in that
it does not use the module administration -- it reads the file
unconditionally and does not create a new module.2.2
-=-=-=-=-=-=-

I'm guessing that the intent was only that "file 1" not become an
entry on the module list, but it seems to be applying "...not create a
new module" recursively to the imported "math"... Maybe an expert with
the Python byte-code can verify. My hypothesis is something on the order
of:
Outer (file level) references to math (math.pi) are being handled
during the byte-code compilation phase of execfile, so even if "math"
isn't in the module list, it is still in local scope for the outer
math.pi...

Inner (function) references to math become dynamic look-ups
evaluated at function execution; at that point math is not in scope and
is not in the module list.

Interestingly, I note that is the file calling execfile has imported
math (so math is in the module list), the called file works...

#no import in run
E:\UserData\Dennis Lee Bieber\My Documents\Python Progs>python run.py
in module: <module 'math' (built-in)>
Traceback (most recent call last):
File "run.py", line 5, in ?
run_ut("ut_00.py")
File "run.py", line 3, in run_ut
execfile(test)
File "ut_00.py", line 8, in ?
f()
File "ut_00.py", line 5, in f
print "in function: \t %s" % math
NameError: global name 'math' is not defined

#import is in run
E:\UserData\Dennis Lee Bieber\My Documents\Python Progs>python run.py
<module 'math' (built-in)>
<module 'math' (built-in)>
in module: <module 'math' (built-in)>
in function: <module 'math' (built-in)>

E:\UserData\Dennis Lee Bieber\My Documents\Python Progs>

--
 
R

Rick Wotnaz

yes I have imported math in the file I want to use it. But the
imported module "math" is not visible in function without a
global instruction.
The code you just posted shows it, yes... My reading of an
earlier
message seemed to imply you had a nested import chain with the
"import math" at the wrong level... Something like:

#file 1
execfile("file 2")

#file 2
import math
import file_3

#file_3
print math.pi
But the solutions already proposed seems to work file for my
sample program. I will try on my project soon :)

Looking at the documentation for "execfile", I can see
/how/ the
problem occurs -- but can't determine if this can be considered
"expected".

-=-=-=-=-=-=-
execfile( filename[, globals[, locals]])

This function is similar to the exec statement, but parses a
file instead of a string. It is different from the import
statement in that it does not use the module administration --
it reads the file unconditionally and does not create a new
module.2.2 -=-=-=-=-=-=-

I'm guessing that the intent was only that "file 1" not
become an
entry on the module list, but it seems to be applying "...not
create a new module" recursively to the imported "math"... Maybe
an expert with the Python byte-code can verify. My hypothesis is
something on the order of:
Outer (file level) references to math (math.pi) are being
handled
during the byte-code compilation phase of execfile, so even if
"math" isn't in the module list, it is still in local scope for
the outer math.pi...

Inner (function) references to math become dynamic look-ups
evaluated at function execution; at that point math is not in
scope and is not in the module list.

Interestingly, I note that is the file calling execfile has
imported
math (so math is in the module list), the called file works...

#no import in run
E:\UserData\Dennis Lee Bieber\My Documents\Python Progs>python
run.py in module: <module 'math' (built-in)>
Traceback (most recent call last):
File "run.py", line 5, in ?
run_ut("ut_00.py")
File "run.py", line 3, in run_ut
execfile(test)
File "ut_00.py", line 8, in ?
f()
File "ut_00.py", line 5, in f
print "in function: \t %s" % math
NameError: global name 'math' is not defined

#import is in run
E:\UserData\Dennis Lee Bieber\My Documents\Python Progs>python
run.py <module 'math' (built-in)>
<module 'math' (built-in)>
in module: <module 'math' (built-in)>
in function: <module 'math' (built-in)>

This may be saying what you said, but it seems to depend on where
the import occurs:
# File: runt2.py
def Bobo():
import math
execfile( "ut_00.py" )
b = Bobo()
First access :
3.14159265359
Second access :
Traceback (most recent call last):
File "D:\pyWork\test\runt2.py", line 5, in ?
b = Bobo()
File "D:\pyWork\test\runt2.py", line 3, in Bobo
execfile( "ut_00.py" )
File "ut_00.py", line 10, in ?
f()
File "ut_00.py", line 6, in f
print "\t",math.pi # ERROR
NameError: global name 'math' is not defined

# File: runt.py
import math
def Bobo():
execfile( "ut_00.py" )
b = Bobo()
First access :
3.14159265359
Second access :
3.14159265359

So the import at the module level of the caller works, but an
import at the function level of the caller doesn't. I don't see why
the namespace would be significantly different by the time execfile
is executed, though it apparently is.
 
F

Fredrik Lundh

Dennis said:
But the solutions already proposed seems to work file for my sample
program. I will try on my project soon :)

Looking at the documentation for "execfile", I can see /how/ the
problem occurs -- but can't determine if this can be considered
"expected".

-=-=-=-=-=-=-
execfile( filename[, globals[, locals]])

This function is similar to the exec statement, but parses a file
instead of a string. It is different from the import statement in that
it does not use the module administration -- it reads the file
unconditionally and does not create a new module.2.2
-=-=-=-=-=-=-

I'm guessing that the intent was only that "file 1" not become an
entry on the module list, but it seems to be applying "...not create a
new module" recursively to the imported "math"... Maybe an expert with
the Python byte-code can verify. My hypothesis is something on the order
of:
Outer (file level) references to math (math.pi) are being handled
during the byte-code compilation phase of execfile, so even if "math"
isn't in the module list, it is still in local scope for the outer
math.pi...

the byte code is identical for both cases; the only difference I can see is
that when when you compile a function that contains a global statement,
the corresponding name is added to the globals for the function that does
the compilation (run_ut in this case).

if you don't use globals, or if the "global" name doesn't exist in the module
namespace, this doesn't happen.

hmm. puzzling.

</F>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top