Elijah Newren wrote:

> Hi,
> 
> I have three files in a simple testcase, and when I run
>   $ main.py callee.options
> This comes back with a Traceback pointing out the following error:
>   File "callee.options", line 5, in __init__
>     Foo.__init__(self, value)
> NameError: global name 'Foo' is not defined
> 
> 
> The three files are:
> 
> ---------------  main.py  ---------------
> #!/usr/bin/env python
> 
> import sys
> 
> class Stuff:
>   def __init__(self, filename):
>     self.greeting = 'Hi world'
>     self.filename = filename
> 
>   def run(self):
>     print self.greeting
>     execfile(self.filename)
> 
> work = Stuff(sys.argv[1])
> work.run()
> ---------------  somelib.py  ---------------
> class Foo:
>   def __init__(self, value):
>     self.value = value
> 
>   def do_stuff(self):
>     raise NotImplementedError()
> 
> class OfficialBar(Foo):
>   def __init__(self, value):
>     Foo.__init__(self, value)
> 
>   def do_stuff(self):
>     print self.value
> ---------------  callee.options  ---------------
> from somelib import Foo, OfficialBar
> 
> class MyBar(Foo):
>   def __init__(self, value):
>     Foo.__init__(self, value)
>     #super(MyBar, self).__init__(value)
> 
>   def do_stuff(self):
>     print 2 * self.value + 1
> 
> 
> baz = MyBar(7)
> #baz = OfficialBar(7)
> baz.do_stuff()
> ---------------------------------------------
> 
> If I comment out the baz = MyBar(7) line, and uncomment the baz =
> OfficialBar(7) line, then there's no error.
> 
> I'm sure this is somehow related to the fact that the execfile is
> within the Stuff class scope, and thus my import statements are
> working under some nested scope, but I don't know how to fix it (other
> modifying main.py to remove the Stuff class entirely, but in my real
> testcase I only have access to the callee.options file).  I'm sure
> this is covered in some FAQ or post somewhere, but I seem to be coming
> up short in my search.  If someone could someone point me to the
> relevant FAQ or post, I'd be more than happy to go read it.

execfile puts Foo in the local namespace of the Stuff.run() method, then
MyBar.__init__() looks it up in the global namespace and fails.

A quick and dirty fix may be to modify execefile to

    execfile(self.filename, globals())

but you should seriously consider renaming callee.options and importing it
the normal way.

Peter
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to