Elijah Newren wrote: > Hi, > > For some reason, Peter Otten's response is not showing up in my inbox, > but did show up in the mailing list archives > (http://mail.python.org/pipermail/python-list/2009-March/703850.html). > So I'll respond to my own email, quote him, and respond that way. > > On Sat, Mar 7, 2009 at 9:46 AM, Elijah Newren <new...@gmail.com> 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() >> --------------------------------------------- > > > > And Peter Otten wrote: >> 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. > > Ah, thanks for the explanation. The big problem here is that real > case from which I drew main.py and somelib.py is cvs2svn. I'm using a > system installed version of cvs2svn, and thus I only have control of > callee.options.
Yea, I didn't read carefully enough. > However, using your hint, I solved my problem by > changing the first line of callee.options from > > from somelib import Foo, OfficialBar > > to > > global Foo > _temp = __import__('somelib', globals(), locals(), ['Foo', 'OfficialBar']) > Foo = _temp.Foo > OfficialBar = _temp.OfficialBar > > > Yeah, I agree it's ugly, but it's a use-once program anyway. :-) > > Thanks again, > Elijah I think moving options.callee's body into a function would also work: #untested def callee(): from somelib import Foo, OfficialBar class MyBar(Foo): def __init__(self, value): Foo.__init__(self, value) def do_stuff(self): print 2 * self.value + 1 baz = MyBar(7) baz.do_stuff() callee() -- http://mail.python.org/mailman/listinfo/python-list