magic.py
686 lines
| 25.5 KiB
| text/x-python
|
PythonLexer
Brian Granger
|
r2498 | # encoding: utf-8 | ||
Ville M. Vainio
|
r1032 | """Magic functions for InteractiveShell. | ||
Fernando Perez
|
r1853 | """ | ||
Ville M. Vainio
|
r1032 | |||
Brian Granger
|
r2498 | #----------------------------------------------------------------------------- | ||
# Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and | ||||
Fernando Perez
|
r6917 | # Copyright (C) 2001 Fernando Perez <fperez@colorado.edu> | ||
# Copyright (C) 2008 The IPython Development Team | ||||
Brian Granger
|
r2498 | |||
Ville M. Vainio
|
r1032 | # Distributed under the terms of the BSD License. The full license is in | ||
# the file COPYING, distributed as part of this software. | ||||
Brian Granger
|
r2498 | #----------------------------------------------------------------------------- | ||
Ville M. Vainio
|
r1032 | |||
Brian Granger
|
r2498 | #----------------------------------------------------------------------------- | ||
# Imports | ||||
#----------------------------------------------------------------------------- | ||||
Fernando Perez
|
r6919 | # Stdlib | ||
Ville M. Vainio
|
r1032 | import os | ||
import re | ||||
Fernando Perez
|
r6917 | import sys | ||
Fernando Perez
|
r6923 | import types | ||
Fernando Perez
|
r6919 | from getopt import getopt, GetoptError | ||
# Our own | ||||
Fernando Perez
|
r6917 | from IPython.config.configurable import Configurable | ||
Fernando Perez
|
r6919 | from IPython.core import oinspect | ||
Fernando Perez
|
r2363 | from IPython.core.error import UsageError | ||
Bradley M. Froehle
|
r7704 | from IPython.core.inputsplitter import ESC_MAGIC, ESC_MAGIC2 | ||
Fernando Perez
|
r6919 | from IPython.external.decorator import decorator | ||
Fernando Perez
|
r6917 | from IPython.utils.ipstruct import Struct | ||
Fernando Perez
|
r6919 | from IPython.utils.process import arg_split | ||
Fernando Perez
|
r6994 | from IPython.utils.text import dedent | ||
MinRK
|
r7298 | from IPython.utils.traitlets import Bool, Dict, Instance, MetaHasTraits | ||
Thomas Kluyver
|
r9399 | from IPython.utils.warn import error | ||
Fernando Perez
|
r6919 | |||
#----------------------------------------------------------------------------- | ||||
# Globals | ||||
#----------------------------------------------------------------------------- | ||||
Fernando Perez
|
r6922 | |||
# A dict we'll use for each class that has magics, used as temporary storage to | ||||
# pass information between the @line/cell_magic method decorators and the | ||||
Fernando Perez
|
r6973 | # @magics_class class decorator, because the method decorators have no | ||
Fernando Perez
|
r6922 | # access to the class when they run. See for more details: | ||
# http://stackoverflow.com/questions/2366713/can-a-python-decorator-of-an-instance-method-access-the-class | ||||
Fernando Perez
|
r6923 | magics = dict(line={}, cell={}) | ||
Fernando Perez
|
r6974 | magic_kinds = ('line', 'cell') | ||
Fernando Perez
|
r6953 | magic_spec = ('line', 'cell', 'line_cell') | ||
Bradley M. Froehle
|
r7704 | magic_escapes = dict(line=ESC_MAGIC, cell=ESC_MAGIC2) | ||
Fernando Perez
|
r2363 | |||
Brian Granger
|
r2498 | #----------------------------------------------------------------------------- | ||
Fernando Perez
|
r6917 | # Utility classes and functions | ||
Brian Granger
|
r2498 | #----------------------------------------------------------------------------- | ||
Fernando Perez
|
r6917 | class Bunch: pass | ||
Ville M. Vainio
|
r1032 | def on_off(tag): | ||
"""Return an ON/OFF string for a 1/0 input. Simple utility function.""" | ||||
return ['OFF','ON'][tag] | ||||
def compress_dhist(dh): | ||||
Fernando Perez
|
r7001 | """Compress a directory history into a new one with at most 20 entries. | ||
Return a new list made from the first and last 10 elements of dhist after | ||||
removal of duplicates. | ||||
""" | ||||
Ville M. Vainio
|
r1032 | head, tail = dh[:-10], dh[-10:] | ||
newhead = [] | ||||
Fernando Perez
|
r1860 | done = set() | ||
Ville M. Vainio
|
r1032 | for h in head: | ||
if h in done: | ||||
continue | ||||
newhead.append(h) | ||||
done.add(h) | ||||
Bernardo B. Marques
|
r4872 | return newhead + tail | ||
Fernando Perez
|
r2358 | |||
Fernando Perez
|
r6917 | |||
Thomas Kluyver
|
r3479 | def needs_local_scope(func): | ||
"""Decorator to mark magic functions which need to local scope to run.""" | ||||
func.needs_local_scope = True | ||||
return func | ||||
Bernardo B. Marques
|
r4872 | |||
Fernando Perez
|
r6919 | #----------------------------------------------------------------------------- | ||
# Class and method decorators for registering magics | ||||
#----------------------------------------------------------------------------- | ||||
Fernando Perez
|
r6973 | def magics_class(cls): | ||
Fernando Perez
|
r7001 | """Class decorator for all subclasses of the main Magics class. | ||
Any class that subclasses Magics *must* also apply this decorator, to | ||||
ensure that all the methods that have been decorated as line/cell magics | ||||
get correctly registered in the class instance. This is necessary because | ||||
when method decorators run, the class does not exist yet, so they | ||||
temporarily store their information into a module global. Application of | ||||
this class decorator copies that global data to the class instance and | ||||
clears the global. | ||||
Obviously, this mechanism is not thread-safe, which means that the | ||||
*creation* of subclasses of Magic should only be done in a single-thread | ||||
context. Instantiation of the classes has no restrictions. Given that | ||||
these classes are typically created at IPython startup time and before user | ||||
application code becomes active, in practice this should not pose any | ||||
problems. | ||||
""" | ||||
Fernando Perez
|
r6919 | cls.registered = True | ||
Fernando Perez
|
r6923 | cls.magics = dict(line = magics['line'], | ||
cell = magics['cell']) | ||||
magics['line'] = {} | ||||
magics['cell'] = {} | ||||
Fernando Perez
|
r6919 | return cls | ||
Fernando Perez
|
r6953 | |||
Fernando Perez
|
r7001 | def record_magic(dct, magic_kind, magic_name, func): | ||
"""Utility function to store a function as a magic of a specific kind. | ||||
Parameters | ||||
---------- | ||||
dct : dict | ||||
A dictionary with 'line' and 'cell' subdicts. | ||||
magic_kind : str | ||||
Kind of magic to be stored. | ||||
magic_name : str | ||||
Key to store the magic as. | ||||
func : function | ||||
Callable object to store. | ||||
""" | ||||
if magic_kind == 'line_cell': | ||||
dct['line'][magic_name] = dct['cell'][magic_name] = func | ||||
Fernando Perez
|
r6933 | else: | ||
Fernando Perez
|
r7001 | dct[magic_kind][magic_name] = func | ||
Fernando Perez
|
r6919 | |||
Fernando Perez
|
r6953 | |||
Fernando Perez
|
r6974 | def validate_type(magic_kind): | ||
Fernando Perez
|
r7001 | """Ensure that the given magic_kind is valid. | ||
Check that the given magic_kind is one of the accepted spec types (stored | ||||
in the global `magic_spec`), raise ValueError otherwise. | ||||
""" | ||||
Fernando Perez
|
r6974 | if magic_kind not in magic_spec: | ||
raise ValueError('magic_kind must be one of %s, %s given' % | ||||
magic_kinds, magic_kind) | ||||
Fernando Perez
|
r6919 | |||
Fernando Perez
|
r6922 | |||
Fernando Perez
|
r6993 | # The docstrings for the decorator below will be fairly similar for the two | ||
# types (method and function), so we generate them here once and reuse the | ||||
# templates below. | ||||
_docstring_template = \ | ||||
"""Decorate the given {0} as {1} magic. | ||||
Fernando Perez
|
r6994 | The decorator can be used with or without arguments, as follows. | ||
Fernando Perez
|
r6993 | |||
i) without arguments: it will create a {1} magic named as the {0} being | ||||
decorated:: | ||||
@deco | ||||
def foo(...) | ||||
will create a {1} magic named `foo`. | ||||
ii) with one string argument: which will be used as the actual name of the | ||||
resulting magic:: | ||||
@deco('bar') | ||||
def foo(...) | ||||
will create a {1} magic named `bar`. | ||||
""" | ||||
# These two are decorator factories. While they are conceptually very similar, | ||||
# there are enough differences in the details that it's simpler to have them | ||||
# written as completely standalone functions rather than trying to share code | ||||
# and make a single one with convoluted logic. | ||||
def _method_magic_marker(magic_kind): | ||||
"""Decorator factory for methods in Magics subclasses. | ||||
""" | ||||
Fernando Perez
|
r6974 | validate_type(magic_kind) | ||
Fernando Perez
|
r6919 | |||
Fernando Perez
|
r6974 | # This is a closure to capture the magic_kind. We could also use a class, | ||
Fernando Perez
|
r6919 | # but it's overkill for just that one bit of state. | ||
def magic_deco(arg): | ||||
call = lambda f, *a, **k: f(*a, **k) | ||||
if callable(arg): | ||||
# "Naked" decorator call (just @foo, no args) | ||||
func = arg | ||||
name = func.func_name | ||||
retval = decorator(call, func) | ||||
Fernando Perez
|
r6974 | record_magic(magics, magic_kind, name, name) | ||
Fernando Perez
|
r6919 | elif isinstance(arg, basestring): | ||
# Decorator called with arguments (@foo('bar')) | ||||
name = arg | ||||
def mark(func, *a, **kw): | ||||
Fernando Perez
|
r6974 | record_magic(magics, magic_kind, name, func.func_name) | ||
Fernando Perez
|
r6919 | return decorator(call, func) | ||
retval = mark | ||||
else: | ||||
Thomas Kluyver
|
r7047 | raise TypeError("Decorator can only be called with " | ||
"string or function") | ||||
Fernando Perez
|
r6972 | return retval | ||
Fernando Perez
|
r6993 | # Ensure the resulting decorator has a usable docstring | ||
magic_deco.__doc__ = _docstring_template.format('method', magic_kind) | ||||
Fernando Perez
|
r6972 | return magic_deco | ||
Fernando Perez
|
r6919 | |||
Fernando Perez
|
r6974 | def _function_magic_marker(magic_kind): | ||
Fernando Perez
|
r6993 | """Decorator factory for standalone functions. | ||
""" | ||||
Fernando Perez
|
r6974 | validate_type(magic_kind) | ||
Fernando Perez
|
r6993 | |||
Fernando Perez
|
r6974 | # This is a closure to capture the magic_kind. We could also use a class, | ||
Fernando Perez
|
r6972 | # but it's overkill for just that one bit of state. | ||
def magic_deco(arg): | ||||
call = lambda f, *a, **k: f(*a, **k) | ||||
# Find get_ipython() in the caller's namespace | ||||
caller = sys._getframe(1) | ||||
for ns in ['f_locals', 'f_globals', 'f_builtins']: | ||||
get_ipython = getattr(caller, ns).get('get_ipython') | ||||
if get_ipython is not None: | ||||
break | ||||
else: | ||||
Thomas Kluyver
|
r7047 | raise NameError('Decorator can only run in context where ' | ||
'`get_ipython` exists') | ||||
Fernando Perez
|
r6972 | |||
ip = get_ipython() | ||||
if callable(arg): | ||||
# "Naked" decorator call (just @foo, no args) | ||||
func = arg | ||||
Fernando Perez
|
r6974 | name = func.func_name | ||
ip.register_magic_function(func, magic_kind, name) | ||||
Fernando Perez
|
r6972 | retval = decorator(call, func) | ||
elif isinstance(arg, basestring): | ||||
# Decorator called with arguments (@foo('bar')) | ||||
name = arg | ||||
def mark(func, *a, **kw): | ||||
Fernando Perez
|
r6974 | ip.register_magic_function(func, magic_kind, name) | ||
Fernando Perez
|
r6972 | return decorator(call, func) | ||
retval = mark | ||||
else: | ||||
Thomas Kluyver
|
r7047 | raise TypeError("Decorator can only be called with " | ||
Fernando Perez
|
r6972 | "string or function") | ||
Fernando Perez
|
r6919 | return retval | ||
Fernando Perez
|
r6993 | # Ensure the resulting decorator has a usable docstring | ||
Fernando Perez
|
r6994 | ds = _docstring_template.format('function', magic_kind) | ||
ds += dedent(""" | ||||
Note: this decorator can only be used in a context where IPython is already | ||||
active, so that the `get_ipython()` call succeeds. You can therefore use | ||||
it in your startup files loaded after IPython initializes, but *not* in the | ||||
IPython configuration file itself, which is executed before IPython is | ||||
fully up and running. Any file located in the `startup` subdirectory of | ||||
your configuration profile will be OK in this sense. | ||||
""") | ||||
magic_deco.__doc__ = ds | ||||
Fernando Perez
|
r6919 | return magic_deco | ||
Fernando Perez
|
r6972 | # Create the actual decorators for public use | ||
# These three are used to decorate methods in class definitions | ||||
Fernando Perez
|
r6993 | line_magic = _method_magic_marker('line') | ||
cell_magic = _method_magic_marker('cell') | ||||
line_cell_magic = _method_magic_marker('line_cell') | ||||
Fernando Perez
|
r6919 | |||
Fernando Perez
|
r6972 | # These three decorate standalone functions and perform the decoration | ||
# immediately. They can only run where get_ipython() works | ||||
register_line_magic = _function_magic_marker('line') | ||||
register_cell_magic = _function_magic_marker('cell') | ||||
register_line_cell_magic = _function_magic_marker('line_cell') | ||||
Fernando Perez
|
r6919 | #----------------------------------------------------------------------------- | ||
# Core Magic classes | ||||
#----------------------------------------------------------------------------- | ||||
Ville M. Vainio
|
r1032 | |||
Fernando Perez
|
r6923 | class MagicsManager(Configurable): | ||
Fernando Perez
|
r6917 | """Object that handles all magic-related functionality for IPython. | ||
""" | ||||
Fernando Perez
|
r6921 | # Non-configurable class attributes | ||
Fernando Perez
|
r6949 | |||
# A two-level dict, first keyed by magic type, then by magic function, and | ||||
# holding the actual callable object as value. This is the dict used for | ||||
# magic function dispatch | ||||
Fernando Perez
|
r6922 | magics = Dict | ||
Fernando Perez
|
r6921 | |||
Fernando Perez
|
r6949 | # A registry of the original objects that we've been given holding magics. | ||
registry = Dict | ||||
Fernando Perez
|
r6917 | shell = Instance('IPython.core.interactiveshell.InteractiveShellABC') | ||
Ville M. Vainio
|
r1032 | |||
Fernando Perez
|
r7002 | auto_magic = Bool(True, config=True, help= | ||
"Automatically call line magics without requiring explicit % prefix") | ||||
Matthias BUSSONNIER
|
r10086 | |||
def _auto_magic_changed(self, name, value): | ||||
self.shell.automagic = value | ||||
Fernando Perez
|
r7002 | |||
Fernando Perez
|
r6922 | _auto_status = [ | ||
Fernando Perez
|
r6996 | 'Automagic is OFF, % prefix IS needed for line magics.', | ||
'Automagic is ON, % prefix IS NOT needed for line magics.'] | ||||
MinRK
|
r5225 | |||
Fernando Perez
|
r6957 | user_magics = Instance('IPython.core.magics.UserMagics') | ||
Fernando Perez
|
r6910 | |||
Fernando Perez
|
r6923 | def __init__(self, shell=None, config=None, user_magics=None, **traits): | ||
super(MagicsManager, self).__init__(shell=shell, config=config, | ||||
user_magics=user_magics, **traits) | ||||
Fernando Perez
|
r6924 | self.magics = dict(line={}, cell={}) | ||
Fernando Perez
|
r6949 | # Let's add the user_magics to the registry for uniformity, so *all* | ||
# registered magic containers can be found there. | ||||
self.registry[user_magics.__class__.__name__] = user_magics | ||||
Ville M. Vainio
|
r1032 | |||
Fernando Perez
|
r6922 | def auto_status(self): | ||
"""Return descriptive string with automagic status.""" | ||||
return self._auto_status[self.auto_magic] | ||||
Matthias BUSSONNIER
|
r7270 | |||
def lsmagic_info(self): | ||||
magic_list = [] | ||||
for m_type in self.magics : | ||||
for m_name,mgc in self.magics[m_type].items(): | ||||
try : | ||||
magic_list.append({'name':m_name,'type':m_type,'class':mgc.im_class.__name__}) | ||||
except AttributeError : | ||||
magic_list.append({'name':m_name,'type':m_type,'class':'Other'}) | ||||
return magic_list | ||||
Ville M. Vainio
|
r1032 | |||
def lsmagic(self): | ||||
Fernando Perez
|
r6921 | """Return a dict of currently available magic functions. | ||
The return dict has the keys 'line' and 'cell', corresponding to the | ||||
two types of magics we support. Each value is a list of names. | ||||
""" | ||||
Fernando Perez
|
r6922 | return self.magics | ||
Fernando Perez
|
r6921 | |||
Bradley M. Froehle
|
r7652 | def lsmagic_docs(self, brief=False, missing=''): | ||
"""Return dict of documentation of magic functions. | ||||
The return dict has the keys 'line' and 'cell', corresponding to the | ||||
two types of magics we support. Each value is a dict keyed by magic | ||||
name whose value is the function docstring. If a docstring is | ||||
unavailable, the value of `missing` is used instead. | ||||
If brief is True, only the first line of each docstring will be returned. | ||||
""" | ||||
docs = {} | ||||
for m_type in self.magics: | ||||
m_docs = {} | ||||
for m_name, m_func in self.magics[m_type].iteritems(): | ||||
if m_func.__doc__: | ||||
if brief: | ||||
m_docs[m_name] = m_func.__doc__.split('\n', 1)[0] | ||||
else: | ||||
m_docs[m_name] = m_func.__doc__.rstrip() | ||||
else: | ||||
m_docs[m_name] = missing | ||||
docs[m_type] = m_docs | ||||
return docs | ||||
Fernando Perez
|
r6924 | def register(self, *magic_objects): | ||
Fernando Perez
|
r6921 | """Register one or more instances of Magics. | ||
Fernando Perez
|
r7002 | |||
Take one or more classes or instances of classes that subclass the main | ||||
`core.Magic` class, and register them with IPython to use the magic | ||||
functions they provide. The registration process will then ensure that | ||||
any methods that have decorated to provide line and/or cell magics will | ||||
be recognized with the `%x`/`%%x` syntax as a line/cell magic | ||||
respectively. | ||||
If classes are given, they will be instantiated with the default | ||||
constructor. If your classes need a custom constructor, you should | ||||
instanitate them first and pass the instance. | ||||
The provided arguments can be an arbitrary mix of classes and instances. | ||||
Parameters | ||||
---------- | ||||
magic_objects : one or more classes or instances | ||||
Fernando Perez
|
r6921 | """ | ||
# Start by validating them to ensure they have all had their magic | ||||
# methods registered at the instance level | ||||
Fernando Perez
|
r6924 | for m in magic_objects: | ||
Fernando Perez
|
r6921 | if not m.registered: | ||
raise ValueError("Class of magics %r was constructed without " | ||||
MinRK
|
r7298 | "the @register_magics class decorator") | ||
if type(m) in (type, MetaHasTraits): | ||||
Fernando Perez
|
r6927 | # If we're given an uninstantiated class | ||
MinRK
|
r7298 | m = m(shell=self.shell) | ||
Fernando Perez
|
r6927 | |||
Fernando Perez
|
r6949 | # Now that we have an instance, we can register it and update the | ||
# table of callables | ||||
self.registry[m.__class__.__name__] = m | ||||
Fernando Perez
|
r6974 | for mtype in magic_kinds: | ||
Fernando Perez
|
r6924 | self.magics[mtype].update(m.magics[mtype]) | ||
Fernando Perez
|
r6921 | |||
Fernando Perez
|
r6974 | def register_function(self, func, magic_kind='line', magic_name=None): | ||
Fernando Perez
|
r7002 | """Expose a standalone function as magic function for IPython. | ||
This will create an IPython magic (line, cell or both) from a | ||||
standalone function. The functions should have the following | ||||
signatures: | ||||
* For line magics: `def f(line)` | ||||
* For cell magics: `def f(line, cell)` | ||||
* For a function that does both: `def f(line, cell=None)` | ||||
In the latter case, the function will be called with `cell==None` when | ||||
invoked as `%f`, and with cell as a string when invoked as `%%f`. | ||||
Parameters | ||||
---------- | ||||
func : callable | ||||
Function to be registered as a magic. | ||||
magic_kind : str | ||||
Kind of magic, one of 'line', 'cell' or 'line_cell' | ||||
magic_name : optional str | ||||
If given, the name the magic will have in the IPython namespace. By | ||||
default, the name of the function itself is used. | ||||
Fernando Perez
|
r6923 | """ | ||
Fernando Perez
|
r6933 | |||
Fernando Perez
|
r6923 | # Create the new method in the user_magics and register it in the | ||
# global table | ||||
Fernando Perez
|
r6974 | validate_type(magic_kind) | ||
Fernando Perez
|
r6936 | magic_name = func.func_name if magic_name is None else magic_name | ||
setattr(self.user_magics, magic_name, func) | ||||
Fernando Perez
|
r6974 | record_magic(self.magics, magic_kind, magic_name, func) | ||
Fernando Perez
|
r6936 | |||
Fernando Perez
|
r6954 | def define_magic(self, name, func): | ||
Fernando Perez
|
r7002 | """[Deprecated] Expose own function as magic function for IPython. | ||
Example:: | ||||
def foo_impl(self, parameter_s=''): | ||||
'My very own magic!. (Use docstrings, IPython reads them).' | ||||
print 'Magic function. Passed parameter is between < >:' | ||||
print '<%s>' % parameter_s | ||||
print 'The self object is:', self | ||||
Fernando Perez
|
r6936 | |||
Fernando Perez
|
r7002 | ip.define_magic('foo',foo_impl) | ||
Fernando Perez
|
r6936 | """ | ||
meth = types.MethodType(func, self.user_magics) | ||||
setattr(self.user_magics, name, meth) | ||||
Fernando Perez
|
r6953 | record_magic(self.magics, 'line', name, meth) | ||
Fernando Perez
|
r6936 | |||
Bradley M. Froehle
|
r7931 | def register_alias(self, alias_name, magic_name, magic_kind='line'): | ||
"""Register an alias to a magic function. | ||||
The alias is an instance of :class:`MagicAlias`, which holds the | ||||
name and kind of the magic it should call. Binding is done at | ||||
call time, so if the underlying magic function is changed the alias | ||||
will call the new function. | ||||
Parameters | ||||
---------- | ||||
alias_name : str | ||||
The name of the magic to be registered. | ||||
magic_name : str | ||||
The name of an existing magic. | ||||
magic_kind : str | ||||
Kind of magic, one of 'line' or 'cell' | ||||
""" | ||||
# `validate_type` is too permissive, as it allows 'line_cell' | ||||
# which we do not handle. | ||||
if magic_kind not in magic_kinds: | ||||
raise ValueError('magic_kind must be one of %s, %s given' % | ||||
magic_kinds, magic_kind) | ||||
alias = MagicAlias(self.shell, magic_name, magic_kind) | ||||
setattr(self.user_magics, alias_name, alias) | ||||
record_magic(self.magics, magic_kind, alias_name, alias) | ||||
Fernando Perez
|
r6919 | # Key base class that provides the central functionality for magics. | ||
Fernando Perez
|
r6917 | |||
Fernando Perez
|
r6919 | class Magics(object): | ||
Fernando Perez
|
r6917 | """Base class for implementing magic functions. | ||
Shell functions which can be reached as %function_name. All magic | ||||
functions should accept a string, which they can parse for their own | ||||
needs. This can make some functions easier to type, eg `%cd ../` | ||||
vs. `%cd("../")` | ||||
Fernando Perez
|
r6919 | |||
Classes providing magic functions need to subclass this class, and they | ||||
MUST: | ||||
- Use the method decorators `@line_magic` and `@cell_magic` to decorate | ||||
individual methods as magic functions, AND | ||||
Fernando Perez
|
r6973 | - Use the class decorator `@magics_class` to ensure that the magic | ||
Fernando Perez
|
r6919 | methods are properly registered at the instance level upon instance | ||
initialization. | ||||
See :mod:`magic_functions` for examples of actual implementation classes. | ||||
Fernando Perez
|
r6917 | """ | ||
Fernando Perez
|
r6923 | # Dict holding all command-line options for each magic. | ||
options_table = None | ||||
Fernando Perez
|
r6929 | # Dict for the mapping of magic names to methods, set by class decorator | ||
magics = None | ||||
# Flag to check that the class decorator was properly applied | ||||
Fernando Perez
|
r6927 | registered = False | ||
Fernando Perez
|
r6930 | # Instance of IPython shell | ||
shell = None | ||||
Fernando Perez
|
r6917 | |||
def __init__(self, shell): | ||||
if not(self.__class__.registered): | ||||
Fernando Perez
|
r6930 | raise ValueError('Magics subclass without registration - ' | ||
Fernando Perez
|
r6973 | 'did you forget to apply @magics_class?') | ||
Fernando Perez
|
r6917 | self.shell = shell | ||
Fernando Perez
|
r6929 | self.options_table = {} | ||
Fernando Perez
|
r6930 | # The method decorators are run when the instance doesn't exist yet, so | ||
# they can only record the names of the methods they are supposed to | ||||
# grab. Only now, that the instance exists, can we create the proper | ||||
# mapping to bound methods. So we read the info off the original names | ||||
# table and replace each method name by the actual bound method. | ||||
MinRK
|
r7584 | # But we mustn't clobber the *class* mapping, in case of multiple instances. | ||
class_magics = self.magics | ||||
self.magics = {} | ||||
Fernando Perez
|
r6974 | for mtype in magic_kinds: | ||
MinRK
|
r7584 | tab = self.magics[mtype] = {} | ||
cls_tab = class_magics[mtype] | ||||
for magic_name, meth_name in cls_tab.iteritems(): | ||||
Fernando Perez
|
r6927 | if isinstance(meth_name, basestring): | ||
MinRK
|
r7584 | # it's a method name, grab it | ||
Fernando Perez
|
r6927 | tab[magic_name] = getattr(self, meth_name) | ||
MinRK
|
r7584 | else: | ||
# it's the real thing | ||||
tab[magic_name] = meth_name | ||||
Fernando Perez
|
r6917 | |||
Ville M. Vainio
|
r1032 | def arg_err(self,func): | ||
"""Print docstring if incorrect arguments were passed""" | ||||
print 'Error in arguments:' | ||||
Brian Granger
|
r2498 | print oinspect.getdoc(func) | ||
Ville M. Vainio
|
r1032 | |||
Fernando Perez
|
r6929 | def format_latex(self, strng): | ||
Ville M. Vainio
|
r1032 | """Format a string for latex inclusion.""" | ||
# Characters that need to be escaped for latex: | ||||
escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE) | ||||
# Magic command names as headers: | ||||
Brian Granger
|
r2245 | cmd_name_re = re.compile(r'^(%s.*?):' % ESC_MAGIC, | ||
Ville M. Vainio
|
r1032 | re.MULTILINE) | ||
Bernardo B. Marques
|
r4872 | # Magic commands | ||
Brian Granger
|
r2245 | cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % ESC_MAGIC, | ||
Ville M. Vainio
|
r1032 | re.MULTILINE) | ||
# Paragraph continue | ||||
par_re = re.compile(r'\\$',re.MULTILINE) | ||||
# The "\n" symbol | ||||
newline_re = re.compile(r'\\n') | ||||
# Now build the string for output: | ||||
#strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng) | ||||
strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:', | ||||
strng) | ||||
strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng) | ||||
strng = par_re.sub(r'\\\\',strng) | ||||
strng = escape_re.sub(r'\\\1',strng) | ||||
strng = newline_re.sub(r'\\textbackslash{}n',strng) | ||||
return strng | ||||
Fernando Perez
|
r6917 | def parse_options(self, arg_str, opt_str, *long_opts, **kw): | ||
Ville M. Vainio
|
r1032 | """Parse options passed to an argument string. | ||
The interface is similar to that of getopt(), but it returns back a | ||||
Struct with the options as keys and the stripped argument string still | ||||
as a string. | ||||
arg_str is quoted as a true sys.argv vector by using shlex.split. | ||||
This allows us to easily expand variables, glob files, quote | ||||
arguments, etc. | ||||
Options: | ||||
-mode: default 'string'. If given as 'list', the argument string is | ||||
returned as a list (split on whitespace) instead of a string. | ||||
-list_all: put all option values in lists. Normally only options | ||||
appearing more than once are put in a list. | ||||
-posix (True): whether to split the input line in POSIX mode or not, | ||||
as per the conventions outlined in the shlex module from the | ||||
standard library.""" | ||||
Bernardo B. Marques
|
r4872 | |||
Ville M. Vainio
|
r1032 | # inject default options at the beginning of the input line | ||
Fernando Perez
|
r6929 | caller = sys._getframe(1).f_code.co_name | ||
Ville M. Vainio
|
r1032 | arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str) | ||
Bernardo B. Marques
|
r4872 | |||
Ville M. Vainio
|
r1032 | mode = kw.get('mode','string') | ||
if mode not in ['string','list']: | ||||
Bradley M. Froehle
|
r7843 | raise ValueError('incorrect mode given: %s' % mode) | ||
Ville M. Vainio
|
r1032 | # Get options | ||
list_all = kw.get('list_all',0) | ||||
Fernando Perez
|
r2450 | posix = kw.get('posix', os.name == 'posix') | ||
MinRK
|
r5672 | strict = kw.get('strict', True) | ||
Ville M. Vainio
|
r1032 | |||
# Check if we have more than one argument to warrant extra processing: | ||||
odict = {} # Dictionary with options | ||||
args = arg_str.split() | ||||
if len(args) >= 1: | ||||
# If the list of inputs only has 0 or 1 thing in it, there's no | ||||
# need to look for options | ||||
MinRK
|
r5672 | argv = arg_split(arg_str, posix, strict) | ||
Ville M. Vainio
|
r1032 | # Do regular option processing | ||
try: | ||||
MinRK
|
r7041 | opts,args = getopt(argv, opt_str, long_opts) | ||
Matthias BUSSONNIER
|
r7787 | except GetoptError as e: | ||
Bernardo B. Marques
|
r4872 | raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str, | ||
Ville M. Vainio
|
r1032 | " ".join(long_opts))) | ||
for o,a in opts: | ||||
if o.startswith('--'): | ||||
o = o[2:] | ||||
else: | ||||
o = o[1:] | ||||
try: | ||||
odict[o].append(a) | ||||
except AttributeError: | ||||
odict[o] = [odict[o],a] | ||||
except KeyError: | ||||
if list_all: | ||||
odict[o] = [a] | ||||
else: | ||||
odict[o] = a | ||||
# Prepare opts,args for return | ||||
opts = Struct(odict) | ||||
if mode == 'string': | ||||
args = ' '.join(args) | ||||
return opts,args | ||||
Bernardo B. Marques
|
r4872 | |||
Fernando Perez
|
r6923 | def default_option(self, fn, optstr): | ||
Fernando Perez
|
r6917 | """Make an entry in the options_table for fn, with value optstr""" | ||
if fn not in self.lsmagic(): | ||||
error("%s is not a magic function" % fn) | ||||
self.options_table[fn] = optstr | ||||
Bradley M. Froehle
|
r7931 | |||
class MagicAlias(object): | ||||
Bradley M. Froehle
|
r8032 | """An alias to another magic function. | ||
Bradley M. Froehle
|
r7931 | |||
An alias is determined by its magic name and magic kind. Lookup | ||||
is done at call time, so if the underlying magic changes the alias | ||||
will call the new function. | ||||
Use the :meth:`MagicsManager.register_alias` method or the | ||||
`%alias_magic` magic function to create and register a new alias. | ||||
""" | ||||
def __init__(self, shell, magic_name, magic_kind): | ||||
self.shell = shell | ||||
self.magic_name = magic_name | ||||
self.magic_kind = magic_kind | ||||
Bradley M. Froehle
|
r8032 | self.pretty_target = '%s%s' % (magic_escapes[self.magic_kind], self.magic_name) | ||
self.__doc__ = "Alias for `%s`." % self.pretty_target | ||||
Bradley M. Froehle
|
r7931 | |||
Bradley M. Froehle
|
r8032 | self._in_call = False | ||
Bradley M. Froehle
|
r7931 | |||
def __call__(self, *args, **kwargs): | ||||
"""Call the magic alias.""" | ||||
fn = self.shell.find_magic(self.magic_name, self.magic_kind) | ||||
if fn is None: | ||||
raise UsageError("Magic `%s` not found." % self.pretty_target) | ||||
# Protect against infinite recursion. | ||||
if self._in_call: | ||||
raise UsageError("Infinite recursion detected; " | ||||
"magic aliases cannot call themselves.") | ||||
self._in_call = True | ||||
try: | ||||
return fn(*args, **kwargs) | ||||
finally: | ||||
self._in_call = False | ||||