From 3f192dc6a1873b0d2e5345fc475ffab0fa403466 2012-05-26 03:25:56 From: Fernando Perez Date: 2012-05-26 03:25:56 Subject: [PATCH] Remove next_input nonsense in magic calls (but keep functionality). --- diff --git a/IPython/core/inputsplitter.py b/IPython/core/inputsplitter.py index f2e148a..146104e 100644 --- a/IPython/core/inputsplitter.py +++ b/IPython/core/inputsplitter.py @@ -559,19 +559,23 @@ def _make_help_call(target, esc, lspace, next_input=None): else 'pinfo' arg = " ".join([method, target]) - if next_input: - tpl = '%sget_ipython().magic(%r, next_input=%r)' - return tpl % (lspace, arg, next_input) - else: + if next_input is None: return '%sget_ipython().magic(%r)' % (lspace, arg) + else: + return '%sget_ipython().set_next_input(%r);get_ipython().magic(%r)' % \ + (lspace, next_input, arg) + _initial_space_re = re.compile(r'\s*') + _help_end_re = re.compile(r"""(%? [a-zA-Z_*][\w*]* # Variable name (\.[a-zA-Z_*][\w*]*)* # .etc.etc ) (\?\??)$ # ? or ??""", re.VERBOSE) + + def transform_help_end(line): """Translate lines with ?/?? at the end""" m = _help_end_re.search(line) diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index e39e1fe..e1c5355 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -2014,7 +2014,7 @@ class InteractiveShell(SingletonConfigurable): # even need a centralize colors management object. self.magic('colors %s' % self.colors) - def line_magic(self, magic_name, line, next_input=None): + def line_magic(self, magic_name, line): """Execute the given line magic. Parameters @@ -2024,15 +2024,7 @@ class InteractiveShell(SingletonConfigurable): line : str The rest of the input line as a single string. - - next_input : str, optional - Text to pre-load into the next input line. """ - # Allow setting the next input - this is used if the user does `a=abs?`. - # We do this first so that magic functions can override it. - if next_input: - self.set_next_input(next_input) - fn = self.find_line_magic(magic_name) if fn is None: error("Magic function `%s` not found." % magic_name) @@ -2079,13 +2071,13 @@ class InteractiveShell(SingletonConfigurable): Returns None if the magic isn't found.""" return self.magics_manager.magics['cell'].get(magic_name) - def find_magic(self, magic_name, magic_type='line'): + def find_magic(self, magic_name, magic_kind='line'): """Find and return a magic of the given type by name. Returns None if the magic isn't found.""" - return self.magics_manager.magics[magic_type].get(magic_name) + return self.magics_manager.magics[magic_kind].get(magic_name) - def magic(self, arg_s, next_input=None): + def magic(self, arg_s): """DEPRECATED. Use line_magic() instead. Call a magic function by name. @@ -2107,7 +2099,7 @@ class InteractiveShell(SingletonConfigurable): # TODO: should we issue a loud deprecation warning here? magic_name, _, magic_arg_s = arg_s.partition(' ') magic_name = magic_name.lstrip(prefilter.ESC_MAGIC) - return self.line_magic(magic_name, magic_arg_s, next_input) + return self.line_magic(magic_name, magic_arg_s) #------------------------------------------------------------------------- # Things related to macros diff --git a/IPython/core/magic.py b/IPython/core/magic.py index 8173417..a87abf4 100644 --- a/IPython/core/magic.py +++ b/IPython/core/magic.py @@ -44,7 +44,7 @@ from IPython.utils.warn import error, warn magics = dict(line={}, cell={}) -magic_types = ('line', 'cell') +magic_kinds = ('line', 'cell') magic_spec = ('line', 'cell', 'line_cell') #----------------------------------------------------------------------------- @@ -98,16 +98,16 @@ def record_magic(dct, mtype, mname, func): dct[mtype][mname] = func -def validate_type(magic_type): - if magic_type not in magic_spec: - raise ValueError('magic_type must be one of %s, %s given' % - magic_types, magic_type) +def validate_type(magic_kind): + if magic_kind not in magic_spec: + raise ValueError('magic_kind must be one of %s, %s given' % + magic_kinds, magic_kind) -def _magic_marker(magic_type): - validate_type(magic_type) +def _magic_marker(magic_kind): + validate_type(magic_kind) - # This is a closure to capture the magic_type. We could also use a class, + # This is a closure to capture the magic_kind. We could also use a class, # but it's overkill for just that one bit of state. def magic_deco(arg): call = lambda f, *a, **k: f(*a, **k) @@ -118,13 +118,13 @@ def _magic_marker(magic_type): name = func.func_name func.magic_name = name retval = decorator(call, func) - record_magic(magics, magic_type, name, name) + record_magic(magics, magic_kind, name, name) elif isinstance(arg, basestring): # Decorator called with arguments (@foo('bar')) name = arg def mark(func, *a, **kw): func.magic_name = name - record_magic(magics, magic_type, name, func.func_name) + record_magic(magics, magic_kind, name, func.func_name) return decorator(call, func) retval = mark else: @@ -135,10 +135,10 @@ def _magic_marker(magic_type): return magic_deco -def _function_magic_marker(magic_type): - validate_type(magic_type) +def _function_magic_marker(magic_kind): + validate_type(magic_kind) - # This is a closure to capture the magic_type. We could also use a class, + # This is a closure to capture the magic_kind. We could also use a class, # but it's overkill for just that one bit of state. def magic_deco(arg): call = lambda f, *a, **k: f(*a, **k) @@ -157,16 +157,14 @@ def _function_magic_marker(magic_type): if callable(arg): # "Naked" decorator call (just @foo, no args) func = arg - #name = func.func_name - #func.magic_name = name - ip.register_magic_function(func) + name = func.func_name + ip.register_magic_function(func, magic_kind, name) retval = decorator(call, func) elif isinstance(arg, basestring): # Decorator called with arguments (@foo('bar')) name = arg def mark(func, *a, **kw): - #func.magic_name = name - ip.register_magic_function(func) + ip.register_magic_function(func, magic_kind, name) return decorator(call, func) retval = mark else: @@ -254,19 +252,19 @@ class MagicsManager(Configurable): # Now that we have an instance, we can register it and update the # table of callables self.registry[m.__class__.__name__] = m - for mtype in magic_types: + for mtype in magic_kinds: self.magics[mtype].update(m.magics[mtype]) - def register_function(self, func, magic_type='line', magic_name=None): + def register_function(self, func, magic_kind='line', magic_name=None): """Expose a standalone function as magic function for ipython. """ # Create the new method in the user_magics and register it in the # global table - validate_type(magic_type) + validate_type(magic_kind) magic_name = func.func_name if magic_name is None else magic_name setattr(self.user_magics, magic_name, func) - record_magic(self.magics, magic_type, magic_name, func) + record_magic(self.magics, magic_kind, magic_name, func) def define_magic(self, name, func): """Support for deprecated API. @@ -320,7 +318,7 @@ class Magics(object): # 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. - for mtype in magic_types: + for mtype in magic_kinds: tab = self.magics[mtype] # must explicitly use keys, as we're mutating this puppy for magic_name in tab.keys(): diff --git a/IPython/core/tests/test_inputsplitter.py b/IPython/core/tests/test_inputsplitter.py index 73e4dba..0d244b9 100644 --- a/IPython/core/tests/test_inputsplitter.py +++ b/IPython/core/tests/test_inputsplitter.py @@ -466,10 +466,14 @@ syntax = \ (u'%hist?', "get_ipython().magic({u}'pinfo %hist')"), (u'f*?', "get_ipython().magic({u}'psearch f*')"), (u'ax.*aspe*?', "get_ipython().magic({u}'psearch ax.*aspe*')"), - (u'a = abc?', "get_ipython().magic({u}'pinfo abc', next_input={u}'a = abc')"), - (u'a = abc.qe??', "get_ipython().magic({u}'pinfo2 abc.qe', next_input={u}'a = abc.qe')"), - (u'a = *.items?', "get_ipython().magic({u}'psearch *.items', next_input={u}'a = *.items')"), - (u'plot(a?', "get_ipython().magic({u}'pinfo a', next_input={u}'plot(a')"), + (u'a = abc?', "get_ipython().set_next_input({u}'a = abc');" + "get_ipython().magic({u}'pinfo abc')"), + (u'a = abc.qe??', "get_ipython().set_next_input({u}'a = abc.qe');" + "get_ipython().magic({u}'pinfo2 abc.qe')"), + (u'a = *.items?', "get_ipython().set_next_input({u}'a = *.items');" + "get_ipython().magic({u}'psearch *.items')"), + (u'plot(a?', "get_ipython().set_next_input({u}'plot(a');" + "get_ipython().magic({u}'pinfo a')"), (u'a*2 #comment?', 'a*2 #comment?'), ]], diff --git a/IPython/core/tests/test_magic.py b/IPython/core/tests/test_magic.py index d664931..bc17c76 100644 --- a/IPython/core/tests/test_magic.py +++ b/IPython/core/tests/test_magic.py @@ -13,10 +13,15 @@ import io import os import sys from StringIO import StringIO +from unittest import TestCase import nose.tools as nt from IPython.core import magic +from IPython.core.magic import (Magics, magics_class, line_magic, + cell_magic, line_cell_magic, + register_line_magic, register_cell_magic, + register_line_cell_magic) from IPython.core.magics import execution from IPython.nbformat.v3.tests.nbexamples import nb0 from IPython.nbformat import current