From 8dcaaddbf841d760229fb343f771935c03f82f17 2006-05-24 07:51:39 From: fperez Date: 2006-05-24 07:51:39 Subject: [PATCH] - add support for PyCrust-style _getAttributeNames magic method. Closes #50. - don't delete exit/quit. Closes #55. - rename 'with' to 'with_obj' to avoid problems in python 2.5. Closes #53. - fix FakeModule, which also closes #59. - add -n option to %edit. - fix various other crashes reported by the automatic crash handler. --- diff --git a/IPython/FakeModule.py b/IPython/FakeModule.py index c3cac63..39253eb 100644 --- a/IPython/FakeModule.py +++ b/IPython/FakeModule.py @@ -5,7 +5,7 @@ Class which mimics a module. Needed to allow pickle to correctly resolve namespaces during IPython sessions. -$Id: FakeModule.py 410 2004-11-04 07:58:17Z fperez $""" +$Id: FakeModule.py 1322 2006-05-24 07:51:39Z fperez $""" #***************************************************************************** # Copyright (C) 2002-2004 Fernando Perez. @@ -35,6 +35,9 @@ class FakeModule: self.__dict__ = adict + # modules should have a __file__ attribute + adict['__file__'] = __file__ + def __getattr__(self,key): try: return self.__dict__[key] diff --git a/IPython/Magic.py b/IPython/Magic.py index dfe271d..9727ebe 100644 --- a/IPython/Magic.py +++ b/IPython/Magic.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """Magic functions for InteractiveShell. -$Id: Magic.py 1314 2006-05-19 18:24:14Z fperez $""" +$Id: Magic.py 1322 2006-05-24 07:51:39Z fperez $""" #***************************************************************************** # Copyright (C) 2001 Janko Hauser and @@ -1874,6 +1874,12 @@ Currently the magic system has the following functions:\n""" Options: + -n : open the editor at a specified line number. By default, + the IPython editor hook uses the unix syntax 'editor +N filename', but + you can configure this by providing your own modified hook if your + favorite editor supports line-number specifications with a different + syntax. + -p: this will call the editor with the same data as the previous time it was used, regardless of how long ago (in your current session) it was. @@ -2003,16 +2009,14 @@ Currently the magic system has the following functions:\n""" # custom exceptions class DataIsObject(Exception): pass - opts,args = self.parse_options(parameter_s,'prxn=i') - - print 'opt.n: <%r>' % opts.n # dbg - + opts,args = self.parse_options(parameter_s,'prxn:') # Set a few locals from the options for convenience: opts_p = opts.has_key('p') opts_r = opts.has_key('r') - + # Default line number value - lineno = None + lineno = opts.get('n',None) + if opts_p: args = '_%s' % last_call[0] if not self.shell.user_ns.has_key(args): @@ -2081,7 +2085,8 @@ Currently the magic system has the following functions:\n""" # a temp file it's gone by now). if datafile: try: - lineno = inspect.getsourcelines(data)[1] + if lineno is None: + lineno = inspect.getsourcelines(data)[1] except IOError: filename = make_filename(args) if filename is None: diff --git a/IPython/completer.py b/IPython/completer.py index 211b42d..0f89170 100644 --- a/IPython/completer.py +++ b/IPython/completer.py @@ -219,6 +219,17 @@ class Completer: # This will happen if `object` is a class and not an instance. pass + # Support for PyCrust-style _getAttributeNames magic method. + if hasattr(object, '_getAttributeNames'): + try: + words.extend(object._getAttributeNames()) + # Eliminate duplicates. + words = set(words) + except TypeError: + # `object` is a class and not an instance. Ignore + # this error. + pass + # filter out non-string attributes which may be stuffed by dir() calls # and poor coding in third-party modules words = [w for w in words diff --git a/IPython/genutils.py b/IPython/genutils.py index 2aaaec2..01a908a 100644 --- a/IPython/genutils.py +++ b/IPython/genutils.py @@ -5,7 +5,7 @@ General purpose utilities. This is a grab-bag of stuff I find useful in most programs I write. Some of these things are also convenient when working at the command line. -$Id: genutils.py 1314 2006-05-19 18:24:14Z fperez $""" +$Id: genutils.py 1322 2006-05-24 07:51:39Z fperez $""" #***************************************************************************** # Copyright (C) 2001-2006 Fernando Perez. @@ -1576,17 +1576,22 @@ def chop(seq,size): return map(chunk,xrange(0,len(seq),size)) #---------------------------------------------------------------------------- -def with(object, **args): +# with is a keyword as of python 2.5, so this function is renamed to withobj +# from its old 'with' name. +def with_obj(object, **args): """Set multiple attributes for an object, similar to Pascal's with. Example: - with(jim, - born = 1960, - haircolour = 'Brown', - eyecolour = 'Green') + with_obj(jim, + born = 1960, + haircolour = 'Brown', + eyecolour = 'Green') Credit: Greg Ewing, in - http://mail.python.org/pipermail/python-list/2001-May/040703.html""" + http://mail.python.org/pipermail/python-list/2001-May/040703.html. + + NOTE: up until IPython 0.7.2, this was called simply 'with', but 'with' + has become a keyword for Python 2.5, so we had to rename it.""" object.__dict__.update(args) diff --git a/IPython/hooks.py b/IPython/hooks.py index 184b75d..c85d3d5 100644 --- a/IPython/hooks.py +++ b/IPython/hooks.py @@ -32,7 +32,7 @@ ip.set_hook('editor', calljed) You can then enable the functionality by doing 'import myiphooks' somewhere in your configuration files or ipython command line. -$Id: hooks.py 1303 2006-05-17 03:39:29Z fperez $""" +$Id: hooks.py 1322 2006-05-24 07:51:39Z fperez $""" #***************************************************************************** # Copyright (C) 2005 Fernando Perez. @@ -73,7 +73,7 @@ def editor(self,filename, linenum=None): if linenum is None or editor=='notepad': linemark = '' else: - linemark = '+%d' % linenum + linemark = '+%d' % int(linenum) # Enclose in quotes if necessary and legal if ' ' in editor and os.path.isfile(editor) and editor[0] != '"': diff --git a/IPython/ipapi.py b/IPython/ipapi.py index 2f1ffcc..563ad83 100644 --- a/IPython/ipapi.py +++ b/IPython/ipapi.py @@ -251,7 +251,6 @@ class IPApi: # exposes variables 'foo' as 'x' and 'bar' as 'y' in IPython # user namespace ip.user_ns.update(dict(x=foo,y=bar)) - """ # print 'vars given:',vars # dbg diff --git a/IPython/iplib.py b/IPython/iplib.py index bfc1893..d90a642 100644 --- a/IPython/iplib.py +++ b/IPython/iplib.py @@ -6,7 +6,7 @@ Requires Python 2.3 or newer. This file contains all the classes and helper functions specific to IPython. -$Id: iplib.py 1314 2006-05-19 18:24:14Z fperez $ +$Id: iplib.py 1322 2006-05-24 07:51:39Z fperez $ """ #***************************************************************************** @@ -204,13 +204,6 @@ class InteractiveShell(object,Magic): # Job manager (for jobs run as background threads) self.jobs = BackgroundJobManager() - # Do the intuitively correct thing for quit/exit: we remove the - # builtins if they exist, and our own magics will deal with this - try: - del __builtin__.exit, __builtin__.quit - except AttributeError: - pass - # Store the actual shell's name self.name = name @@ -1231,7 +1224,8 @@ want to merge them back into the new files.""" % locals() """Utility routine for edit_syntax_error""" if e.filename in ('','','', - '',None): + '','', + None): return False try: @@ -1269,11 +1263,14 @@ want to merge them back into the new files.""" % locals() except: self.showtraceback() else: - f = file(err.filename) try: - sys.displayhook(f.read()) - finally: - f.close() + f = file(err.filename) + try: + sys.displayhook(f.read()) + finally: + f.close() + except: + self.showtraceback() def showsyntaxerror(self, filename=None): """Display the syntax error that just occurred. @@ -1316,7 +1313,16 @@ want to merge them back into the new files.""" % locals() pdb.pm() def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None): - """Display the exception that just occurred.""" + """Display the exception that just occurred. + + If nothing is known about the exception, this is the method which + should be used throughout the code for presenting user tracebacks, + rather htan directly invoking the InteractiveTB object. + + A specific showsyntaxerror() also exists, but this method can take + care of calling it if needed, so unless you are explicitly catching a + SyntaxError exception, don't try to analyze the stack manually and + simply call this method.""" # Though this won't be called by syntax errors in the input line, # there may be SyntaxError cases whith imported code. @@ -1793,7 +1799,12 @@ want to merge them back into the new files.""" % locals() else: self.input_hist_raw.append('%s\n' % line) - lineout = self.prefilter(line,continue_prompt) + try: + lineout = self.prefilter(line,continue_prompt) + except: + # blanket except, in case a user-defined prefilter crashes, so it + # can't take all of ipython with it. + self.showtraceback() return lineout def split_user_input(self,line): diff --git a/doc/ChangeLog b/doc/ChangeLog index 91fffbd..7842b56 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,40 @@ +2006-05-24 Fernando Perez + + * IPython/completer.py (Completer.attr_matches): add support for + PyCrust-style _getAttributeNames magic method. Patch contributed + by . Closes #50. + + * IPython/iplib.py (InteractiveShell.__init__): remove the + deletion of exit/quit from __builtin__, which can break + third-party tools like the Zope debugging console. The + %exit/%quit magics remain. In general, it's probably a good idea + not to delete anything from __builtin__, since we never know what + that will break. In any case, python now (for 2.5) will support + 'real' exit/quit, so this issue is moot. Closes #55. + + * IPython/genutils.py (with_obj): rename the 'with' function to + 'withobj' to avoid incompatibilities with Python 2.5, where 'with' + becomes a language keyword. Closes #53. + + * IPython/FakeModule.py (FakeModule.__init__): add a proper + __file__ attribute to this so it fools more things into thinking + it is a real module. Closes #59. + + * IPython/Magic.py (magic_edit): add -n option to open the editor + at a specific line number. After a patch by Stefan van der Walt. + +2006-05-23 Fernando Perez + + * IPython/iplib.py (edit_syntax_error): fix crash when for some + reason the file could not be opened. After automatic crash + reports sent by James Graham and + Charles Dolan . + (_should_recompile): Don't fire editor if using %bg, since there + is no file in the first place. From the same report as above. + (raw_input): protect against faulty third-party prefilters. After + an automatic crash report sent by Dirk Laurie + while running under SAGE. + 2006-05-23 Ville Vainio * ipapi.py: Stripped down ip.to_user_ns() to work only as