IPython Documentation

Table Of Contents

Previous topic

Connection Diagrams of The IPython ZMQ Cluster

Next topic

Notes on code execution in InteractiveShell

This Page

The magic commands subsystem

Warning

These are preliminary notes and thoughts on the magic system, kept here for reference so we can come up with a good design now that the major core refactoring has made so much progress. Do not consider yet any part of this document final.

Two entry points:

  • m.line_eval(self,parameter_s): like today
  • m.block_eval(self,code_block): for whole-block evaluation.

This would allow us to have magics that take input, and whose single line form can even take input and call block_eval later (like %cpaste does, but with a generalized interface).

Constructor

Suggested syntax:

class MyMagic(BaseMagic):
    requires_shell = True/False
    def __init__(self,shell=None):

Registering magics

Today, ipapi provides an expose_magic() function for making simple magics. We will probably extend this (in a backwards-compatible manner if possible) to allow the simplest cases to work as today, while letting users register more complex ones.

Use cases:

def func(arg): pass  # note signature, no 'self'
ip.expose_magic('name',func)

def func_line(arg): pass
def func_block(arg):pass
ip.expose_magic('name',func_line,func_block)

class mymagic(BaseMagic):
    """Magic docstring, used in help messages.
    """
    def line_eval(self,arg): pass
    def block_eval(self,arg): pass

ip.register_magic(mymagic)

The BaseMagic class will offer common functionality to all, including things like options handling (via argparse).

Call forms: line and block

Block-oriented environments will call line_eval() for the first line of input (the call line starting with ‘%’) and will then feed the rest of the block to block_eval() if the magic in question has a block mode.

In line environments, by default %foo -> foo.line_eval(), but no block call is made. Specific implementations of line_eval can decide to then call block_eval if they want to provide for whole-block input in line-oriented environments.

The api might be adapted for this decision to be made automatically by the frontend...

Precompiled magics for rapid loading

For IPython itself, we’ll have a module of ‘core’ magic functions that do not require run-time registration. These will be the ones contained today in Magic.py, plus any others we deem worthy of being available by default. This is a trick to enable faster startup, since once we move to a model where each magic can in principle be registered at runtime, creating a lot of them can easily swamp startup time.

The trick is to make a module with a top-level class object that contains explicit references to all the ‘core’ magics in its dict. This way, the magic table can be quickly updated at interpreter startup with a single call, by doing something along the lines of:

self.magic_table.update(static_magics.__dict__)

The point will be to be able to bypass the explicit calling of whatever register_magic() API we end up making for users to declare their own magics. So ultimately one should be able to do either:

ip.register_magic(mymagic) # for one function

or:

ip.load_magics(static_magics)  # for a bunch of them

I still need to clarify exactly how this should work though.