[IPython-dev] strange namespace issue
Darren Dale
dd55 at cornell.edu
Tue Sep 11 13:56:14 EDT 2007
On Tuesday 11 September 2007 01:18:04 pm Fernando Perez wrote:
> On 9/11/07, Darren Dale <dd55 at cornell.edu> wrote:
> > Aha! The problem was introduced in svn 2754, when iplib, FakeModule and
> > Magic were modified. Try doing the following with svn 2753 and then 2754:
> >
> > $ ipython -gthread
> > In [1]: run pygtk-demo.py
> > # interact with the pygtk-demo window
> >
> > I get errors with 2754, but not with 2753.
>
> Lovely. Those are the changes I made for doctest to work correctly,
> and the more frustrating part is that the new code is in a sense much
> more correct. Instead of building a fake contraption that tries to
> look like a module, we actually put a true module object in the
> execution namespace of the called script. This could not be done back
> in the days of python 2.1, but now (post 2.2) I can do that, which
> should be a much better solution.
>
> The new code did pass all the pickle tests I had lying around as well
> as enabling doctest to work correctly. I'm totally confused as to why
> it may have broken threading support, in particular in that strange
> way you are seeing.
>
> I'm convinced that having a real module in there is the right thing to
> do. I'd be very grateful if anyone has an idea on how to address the
> GUI problems Darren is seeing without losing the doctest support.
> Very grateful.
No ideas yet, but here is the svn diff -r 2753:2754:
Index: IPython/iplib.py
===================================================================
--- IPython/iplib.py (revision 2753)
+++ IPython/iplib.py (revision 2754)
@@ -2391,8 +2391,24 @@
"""A safe version of the builtin execfile().
This version will never throw an exception, and knows how to handle
- ipython logs as well."""
+ ipython logs as well.
+ :Parameters:
+ fname : string
+ Name of the file to be executed.
+
+ where : tuple
+ One or two namespaces, passed to execfile() as (globals,locals).
+ If only one is given, it is passed as both.
+
+ :Keywords:
+ islog : boolean (False)
+
+ quiet : boolean (True)
+
+ exit_ignore : boolean (False)
+ """
+
def syspath_cleanup():
"""Internal cleanup routine for sys.path."""
if add_dname:
@@ -2424,6 +2440,7 @@
kw.setdefault('islog',0)
kw.setdefault('quiet',1)
kw.setdefault('exit_ignore',0)
+
first = xfile.readline()
loghead = str(self.loghead_tpl).split('\n',1)[0].strip()
xfile.close()
Index: IPython/FakeModule.py
===================================================================
--- IPython/FakeModule.py (revision 2753)
+++ IPython/FakeModule.py (revision 2754)
@@ -25,28 +25,19 @@
sessions.
Do NOT use this code for anything other than this IPython private
hack."""
- def __init__(self,adict):
+ def __init__(self,adict=None):
+
+ # tmp to force __dict__ instance creation, else self.__dict__ fails
+ self.__iptmp = None
+
# It seems pydoc (and perhaps others) needs any module instance to
# implement a __nonzero__ method, so we add it if missing:
- if '__nonzero__' not in adict:
- def __nonzero__():
- return 1
- adict['__nonzero__'] = __nonzero__
+ self.__dict__.setdefault('__nonzero__',lambda : True)
+ self.__dict__.setdefault('__file__',__file__)
- self._dict_ = adict
+ # cleanup our temp trick
+ del self.__iptmp
- # modules should have a __file__ attribute
- adict.setdefault('__file__',__file__)
-
- def __getattr__(self,key):
- try:
- return self._dict_[key]
- except KeyError, e:
- raise AttributeError("FakeModule object has no attribute %s" % e)
-
- def __str__(self):
- return "<IPython.FakeModule instance>"
-
- def __repr__(self):
- return str(self)
+ if adict is not None:
+ self.__dict__.update(adict)
Index: IPython/Magic.py
===================================================================
--- IPython/Magic.py (revision 2753)
+++ IPython/Magic.py (revision 2754)
@@ -1522,12 +1522,15 @@
prog_ns = self.shell.user_ns
__name__save = self.shell.user_ns['__name__']
prog_ns['__name__'] = '__main__'
+ main_mod = FakeModule(prog_ns)
else:
if opts.has_key('n'):
name = os.path.splitext(os.path.basename(filename))[0]
else:
name = '__main__'
- prog_ns = {'__name__':name}
+ main_mod = FakeModule()
+ prog_ns = main_mod.__dict__
+ prog_ns['__name__'] = name
# Since '%run foo' emulates 'python foo.py' at the cmd line, we must
# set the __file__ global in the script's namespace
@@ -1540,7 +1543,7 @@
else:
restore_main = False
- sys.modules[prog_ns['__name__']] = FakeModule(prog_ns)
+ sys.modules[prog_ns['__name__']] = main_mod
stats = None
try:
More information about the IPython-dev
mailing list