[IPython-dev] Function specific hooks into the ipython tab completion system

Aaron Meurer asmeurer at gmail.com
Thu Nov 29 14:16:24 EST 2012

On Nov 29, 2012, at 12:08 PM, Aaron Meurer <asmeurer at gmail.com> wrote:

On Nov 29, 2012, at 3:28 AM, Robert McGibbon <rmcgibbo at gmail.com> wrote:


Good spot, Matthias. I didn't see that method was already exposed -- I was
just looking at IPCompleter.matchers, which what that method inserts into.

Annotations are cool, but they're not obviously composable. I worry that if
I use them for this and then fix one syntax of how the annotation is
parsed, and somebody else
is using annotations in their lib for something else, the two schemes won't
be able to interoperate. Also they're py3k only.

Annotations syntax is python 3 only, but other than that, anyone can modify
an object's __annotations__ dict.

Also, note that annotations don't have to be strings. They can be arbitrary
objects. So what I would do is create completer template objects (e.g.,
there would be a FileCompleter for your example), and annotate with those.
To compose, just make these objects in such a way that they are easily
composable (or just annotate with a list of such objects, and append to the
list of you want to add more).

Actually, I think what we really need is a good type annotations system.
PEP 3107, which defines the python 3 annotations syntax, mentions that they
are leaving it up to the community to define such things. I think this is
the perfect community to do that, lying at the center of the scientific
python universe. It would then be just a case of making those type
annotations completeable.

This is one of the best kept secrets of python 3, and I think the special
syntax could really help drive the community to switch.

Aaron Meurer

Aaron Meurer

My preferred syntax would be

from tablib import tabcompletion, filename,

@tabcompletion(fname=filename, mode=['r', 'w'])
def load(fname, mode, other_argument):

or maybe with a parameterized filename to get specific extensions

def f(fname, other_argument):

Is this something that other people would be interested in?


On Nov 29, 2012, at 2:02 AM, Matthias BUSSONNIER wrote:


I may be wrong, but IIRC you can insert your own completer in the IPython
 completer chain and decide to filter the previous completion.

You should be able to have a custom completer that just forward the
previous completion in most cases,
And just do a dir completion if the object is np.loadtxt in your case (or
look at __annotations__ if you wish).

I've found one reference to inserting custom completer here


Le 29 nov. 2012 à 10:27, Aaron Meurer a écrit :

I've often thought this as well.  Probably a full-blown IPEP is in
order here.  Perhaps __annotations__ would be the correct way to go

Aaron Meurer

On Thu, Nov 29, 2012 at 12:58 AM, Robert McGibbon <rmcgibbo at gmail.com>


Tab completion in IPython is one of the things that makes it so useful,

especially the context specific tab completion for things like "from ..."

where only packages, or obviously the special completion for attributes when

the line contains a dot.

I use IPython for interactive data analysis a lot, and one of the most

frequent operations is loading up data with something like numpy.loadtxt()

or various related functions.

It would be really awesome if we could annotate functions to interact with

the tab completion system, perhaps for instance saying that argument 0 to

numpy.loadtxt() is supposed to be a filename, so let's give tab-complete

suggestions that try to look for directories/files. Some functions only

files with specific extensions, so you could filter based on that or


By hacking on the code for completerlib.py:cd_completer, I sketched out a

little demo of what you could do with this: https://gist.github.com/4167151.

The architecture is totally wrong, but it lets you get behavior like:


In [1]: ls

datfile.dat  dir1/        dir2/        file.gz      random_junk  test.py

In [2]: directory_as_a_variable = 'sdfsfsd'

In [3]: f = np.loadtxt(<TAB>

datfile.dat  dir1/        dir2/        file.gz

In [4]: normal_function(<TAB>

Display all 330 possibilities? (y or n)

In [5]: g = np.loadtxt(di<TAB>

dict                      dir1/                     directory_as_a_variable


dir                       dir2/                     directory_of_my_choosing


Basically hitting the tab completion, when np.loadtxt is on the input line,

only shows directories and files that end with a certain extension. If you

start to type in the name of an object in your namespace, it'll show up too,

but only once you've typed in more than 1 matching character.

The implementation in my gist is pretty lame. The way I've coded it up, the

special behavior is based on simply finding the string "np.loadtxt" on the

input line, not on the actual function. This means you can't really make the

behavior specific to your position in the argument list (i.e. I know that

the first arg is a filename, and so should be tab completed like this, but

the other ones are not). I suspect the right way to do the implementation is

via function decorators to specify the behavior and then adding to

IPCompleter instead.

I think I'm up for giving this a shot.

Thoughts? Is this a feature anyone else would find interesting?



IPython-dev mailing list

IPython-dev at scipy.org


IPython-dev mailing list
IPython-dev at scipy.org

IPython-dev mailing list
IPython-dev at scipy.org

IPython-dev mailing list
IPython-dev at scipy.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ipython-dev/attachments/20121129/f7e1e03c/attachment.html>

More information about the IPython-dev mailing list