diff --git a/IPython/Magic.py b/IPython/Magic.py index 9b08492..e8bf6aa 100644 --- a/IPython/Magic.py +++ b/IPython/Magic.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """Magic functions for InteractiveShell. -$Id: Magic.py 988 2006-01-02 21:21:47Z fperez $""" +$Id: Magic.py 990 2006-01-04 06:59:02Z fperez $""" #***************************************************************************** # Copyright (C) 2001 Janko Hauser and @@ -424,11 +424,12 @@ Currently the magic system has the following functions:\n""" def magic_autocall(self, parameter_s = ''): """Make functions callable without having to type parentheses. - This toggles the autocall command line option on and off.""" + This cycles the autocall command line through its three valid values + (0->Off, 1->Smart, 2->Full)""" rc = self.shell.rc rc.autocall = not rc.autocall - print "Automatic calling is:",['OFF','ON'][rc.autocall] + print "Automatic calling is:",['OFF','Smart','Full'][rc.autocall] def magic_autoindent(self, parameter_s = ''): """Toggle autoindent on/off (if available).""" diff --git a/IPython/UserConfig/ipythonrc b/IPython/UserConfig/ipythonrc index 749b1aa..ed4e75a 100644 --- a/IPython/UserConfig/ipythonrc +++ b/IPython/UserConfig/ipythonrc @@ -1,5 +1,5 @@ # -*- Mode: Shell-Script -*- Not really, but shows comments correctly -# $Id: ipythonrc 963 2005-12-28 19:21:29Z fperez $ +# $Id: ipythonrc 990 2006-01-04 06:59:02Z fperez $ #*************************************************************************** # @@ -37,8 +37,9 @@ include # is encountered more than once, the last value remains, all earlier ones get # discarded. -# Automatic calling of callable objects. If set to true, callable objects are -# automatically called when invoked at the command line, even if you don't + +# Automatic calling of callable objects. If set to 1 or 2, callable objects +# are automatically called when invoked at the command line, even if you don't # type parentheses. IPython adds the parentheses for you. For example: #In [1]: str 45 @@ -48,7 +49,28 @@ include # IPython reprints your line with '---->' indicating that it added # parentheses. While this option is very convenient for interactive use, it # may occasionally cause problems with objects which have side-effects if -# called unexpectedly. Set it to 0 if you want to disable it. +# called unexpectedly. + +# The valid values for autocall are: + +# autocall 0 -> disabled (you can toggle it at runtime with the %autocall magic) + +# autocall 1 -> active, but do not apply if there are no arguments on the line. + +# In this mode, you get: + +#In [1]: callable +#Out[1]: + +#In [2]: callable 'hello' +#------> callable('hello') +#Out[2]: False + +# 2 -> Active always. Even if no arguments are present, the callable object +# is called: + +#In [4]: callable +#------> callable() # Note that even with autocall off, you can still use '/' at the start of a # line to treat the first argument on the command line as a function and add diff --git a/IPython/completer.py b/IPython/completer.py index 47987c6..f205eda 100644 --- a/IPython/completer.py +++ b/IPython/completer.py @@ -73,6 +73,13 @@ import readline import sys import types +# Python 2.4 offers sets as a builtin +try: + set([1,2]) +except NameError: + from sets import Set as set + + from IPython.genutils import shlex_split __all__ = ['Completer','IPCompleter'] @@ -192,11 +199,21 @@ class Completer: except: object = eval(expr, self.global_namespace) + # Start building the attribute list via dir(), and then complete it + # with a few extra special-purpose calls. words = dir(object) + if hasattr(object,'__class__'): words.append('__class__') words.extend(get_class_members(object.__class__)) + # this is the 'dir' function for objects with Enthought's traits + if hasattr(object, 'trait_names'): + words.extend(object.trait_names()) + # eliminate possible duplicates, as some traits may also appear as + # normal attributes in the dir() call. + words = set(words) + # 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 af88c8f..c2e5f04 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 980 2005-12-30 15:42:04Z fperez $""" +$Id: genutils.py 990 2006-01-04 06:59:02Z fperez $""" #***************************************************************************** # Copyright (C) 2001-2004 Fernando Perez. @@ -207,6 +207,18 @@ def fatal(msg,exit_val=1): warn(msg,exit_val=exit_val,level=4) + +# useful for debugging +def debugp(expr): + """Print the value of an expression from the caller's frame. + + Takes an expression, evaluates it in the caller's frame and prints both + the given expression and the resulting value. The input must be of a form + suitable for eval().""" + + cf = sys._getframe(1) + print '[DBG] %s -> %r' % (expr,eval(expr,cf.f_globals,cf.f_locals)) + #---------------------------------------------------------------------------- StringTypes = types.StringTypes diff --git a/IPython/iplib.py b/IPython/iplib.py index 3497dc4..8d05b7d 100644 --- a/IPython/iplib.py +++ b/IPython/iplib.py @@ -6,7 +6,7 @@ Requires Python 2.1 or newer. This file contains all the classes and helper functions specific to IPython. -$Id: iplib.py 988 2006-01-02 21:21:47Z fperez $ +$Id: iplib.py 990 2006-01-04 06:59:02Z fperez $ """ #***************************************************************************** @@ -472,7 +472,7 @@ class InteractiveShell(object,Magic): # RegExp to identify potential function names self.re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$') # RegExp to exclude strings with this start from autocalling - self.re_exclude_auto = re.compile('^[!=()<>,\*/\+-]|^is ') + self.re_exclude_auto = re.compile('^[!=()\[\]<>,\*/\+-]|^is ') # try to catch also methods for stuff in lists/tuples/dicts: off # (experimental). For this to work, the line_split regexp would need @@ -1836,7 +1836,8 @@ want to merge them back into the new files.""" % locals() self.re_fun_name.match(iFun) and \ callable(oinfo['obj']) : #print 'going auto' # dbg - return self.handle_auto(line,continue_prompt,pre,iFun,theRest) + return self.handle_auto(line,continue_prompt, + pre,iFun,theRest,oinfo['obj']) else: #print 'was callable?', callable(oinfo['obj']) # dbg return self.handle_normal(line,continue_prompt) @@ -1919,15 +1920,17 @@ want to merge them back into the new files.""" % locals() return cmd def handle_auto(self, line, continue_prompt=None, - pre=None,iFun=None,theRest=None): + pre=None,iFun=None,theRest=None,obj=None): """Hande lines which can be auto-executed, quoting if requested.""" #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg # This should only be active for single-line input! if continue_prompt: + self.log(line,continue_prompt) return line + auto_rewrite = True if pre == self.ESC_QUOTE: # Auto-quote splitting on whitespace newcmd = '%s("%s")' % (iFun,'", "'.join(theRest.split()) ) @@ -1935,19 +1938,31 @@ want to merge them back into the new files.""" % locals() # Auto-quote whole string newcmd = '%s("%s")' % (iFun,theRest) else: - # Auto-paren - if theRest[0:1] in ('=','['): - # Don't autocall in these cases. They can be either - # rebindings of an existing callable's name, or item access - # for an object which is BOTH callable and implements - # __getitem__. - return '%s %s' % (iFun,theRest) - if theRest.endswith(';'): - newcmd = '%s(%s);' % (iFun.rstrip(),theRest[:-1]) + # Auto-paren. + # We only apply it to argument-less calls if the autocall + # parameter is set to 2. We only need to check that autocall is < + # 2, since this function isn't called unless it's at least 1. + if not theRest and self.rc.autocall < 2: + newcmd = '%s %s' % (iFun,theRest) + auto_rewrite = False else: - newcmd = '%s(%s)' % (iFun.rstrip(),theRest) + if theRest.startswith('['): + if hasattr(obj,'__getitem__'): + # Don't autocall in this case: item access for an object + # which is BOTH callable and implements __getitem__. + newcmd = '%s %s' % (iFun,theRest) + auto_rewrite = False + else: + # if the object doesn't support [] access, go ahead and + # autocall + newcmd = '%s(%s)' % (iFun.rstrip(),theRest) + elif theRest.endswith(';'): + newcmd = '%s(%s);' % (iFun.rstrip(),theRest[:-1]) + else: + newcmd = '%s(%s)' % (iFun.rstrip(),theRest) - print >>Term.cout, self.outputcache.prompt1.auto_rewrite() + newcmd + if auto_rewrite: + print >>Term.cout, self.outputcache.prompt1.auto_rewrite() + newcmd # log what is now valid Python, not the actual user input (without the # final newline) self.log(newcmd,continue_prompt) diff --git a/IPython/ipmaker.py b/IPython/ipmaker.py index 09eb302..22454ae 100644 --- a/IPython/ipmaker.py +++ b/IPython/ipmaker.py @@ -6,7 +6,7 @@ Requires Python 2.1 or better. This file contains the main make_IPython() starter function. -$Id: ipmaker.py 967 2005-12-29 09:02:13Z fperez $""" +$Id: ipmaker.py 990 2006-01-04 06:59:02Z fperez $""" #***************************************************************************** # Copyright (C) 2001-2004 Fernando Perez. @@ -147,7 +147,7 @@ object? -> Details about 'object'. ?object also works, ?? prints more. # DPyGetOpt syntax (=s,=i,:f,etc). # Make sure there's a space before each end of line (they get auto-joined!) - cmdline_opts = ('autocall! autoindent! automagic! banner! cache_size|cs=i ' + cmdline_opts = ('autocall=i autoindent! automagic! banner! cache_size|cs=i ' 'c=s classic|cl color_info! colors=s confirm_exit! ' 'debug! deep_reload! editor=s log|l messages! nosep pdb! ' 'pprint! prompt_in1|pi1=s prompt_in2|pi2=s prompt_out|po=s ' diff --git a/IPython/usage.py b/IPython/usage.py index 268d1d9..93f30c3 100644 --- a/IPython/usage.py +++ b/IPython/usage.py @@ -6,7 +6,7 @@ # the file COPYING, distributed as part of this software. #***************************************************************************** -# $Id: usage.py 966 2005-12-29 08:34:07Z fperez $ +# $Id: usage.py 990 2006-01-04 06:59:02Z fperez $ from IPython import Release __author__ = '%s <%s>' % Release.authors['Fernando'] @@ -144,10 +144,14 @@ REGULAR OPTIONS to correctly execute (without blocking) any matplotlib-based script which calls show() at the end. - -[no]autocall - Make IPython automatically call any callable object even if you - didn’t type explicit parentheses. For example, ’str 43’ becomes - ’str(43)’ automatically. + -autocall + Make IPython automatically call any callable object even if you + didn't type explicit parentheses. For example, 'str 43' becomes + 'str(43)' automatically. The value can be '0' to disable the + feature, '1' for 'smart' autocall, where it is not applied if + there are no more arguments on the line, and '2' for 'full' + autocall, where all callable objects are automatically called + (even if no arguments are present). The default is '1'. -[no]autoindent Turn automatic indentation on/off. diff --git a/doc/ChangeLog b/doc/ChangeLog index 8f58bcd..b171f1a 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,17 @@ +2006-01-03 Fernando Perez + + * IPython/iplib.py (handle_auto): changed autocall semantics to + include 'smart' mode, where the autocall transformation is NOT + applied if there are no arguments on the line. This allows you to + just type 'foo' if foo is a callable to see its internal form, + instead of having it called with no arguments (typically a + mistake). The old 'full' autocall still exists: for that, you + need to set the 'autocall' parameter to 2 in your ipythonrc file. + + * IPython/completer.py (Completer.attr_matches): add + tab-completion support for Enthoughts' traits. After a report by + Arnd and a patch by Prabhu. + 2006-01-02 Fernando Perez * IPython/ultraTB.py (_fixed_getinnerframes): added Alex diff --git a/doc/ipython.1 b/doc/ipython.1 index b522613..b938d8a 100644 --- a/doc/ipython.1 +++ b/doc/ipython.1 @@ -115,9 +115,14 @@ All options with a [no] prepended can be specified in negated form .B \-h, \-\-help Show summary of options. .TP -.B \-[no]autocall +.B \-autocall Make IPython automatically call any callable object even if you didn't type -explicit parentheses. For example, 'str 43' becomes 'str(43)' automatically. +explicit parentheses. For example, 'str 43' becomes +'str(43)' automatically. The value can be '0' to disable the +feature, '1' for 'smart' autocall, where it is not applied if +there are no more arguments on the line, and '2' for 'full' +autocall, where all callable objects are automatically called +(even if no arguments are present). The default is '1'. .TP .B \-[no]autoindent Turn automatic indentation on/off. diff --git a/doc/manual_base.lyx b/doc/manual_base.lyx index df491d6..ed250de 100644 --- a/doc/manual_base.lyx +++ b/doc/manual_base.lyx @@ -2686,12 +2686,24 @@ show() \family typewriter \series bold --[no]autocall: +-autocall : \family default \series default Make IPython automatically call any callable object even if you didn't type explicit parentheses. For example, `str 43' becomes `str(43)' automatically. + The value can be `0' to disable the feature, `1' for +\emph on +smart +\emph default + autocall, where it is not applied if there are no more arguments on the + line, and `2' for +\emph on +full +\emph default + autocall, where all callable objects are automatically called (even if + no arguments are present). + The default is `1'. \layout List \labelwidthstring 00.00.0000