diff --git a/IPython/core/inputtransformer.py b/IPython/core/inputtransformer.py index b157453..b70c011 100644 --- a/IPython/core/inputtransformer.py +++ b/IPython/core/inputtransformer.py @@ -173,3 +173,39 @@ def leading_indent(): line = (yield line) leading_indent.look_in_string = True + +def _special_assignment(assignment_re, template): + line = '' + while True: + line = (yield line) + if not line or line.isspace(): + continue + + m = assignment_re.match(line) + if not m: + continue + + parts = [] + while line is not None: + parts.append(line.rstrip('\\')) + if not line.endswith('\\'): + break + line = (yield None) + + # Output + whole = assignment_re.match(' '.join(parts)) + line = template % (whole.group('lhs'), whole.group('cmd')) + +@CoroutineInputTransformer +def assign_from_system(): + assignment_re = re.compile(r'(?P(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))' + r'\s*=\s*!\s*(?P.*)') + template = '%s = get_ipython().getoutput(%r)' + return _special_assignment(assignment_re, template) + +@CoroutineInputTransformer +def assign_from_magic(): + assignment_re = re.compile(r'(?P(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))' + r'\s*=\s*%\s*(?P.*)') + template = '%s = get_ipython().magic(%r)' + return _special_assignment(assignment_re, template) diff --git a/IPython/core/tests/test_inputtransformer.py b/IPython/core/tests/test_inputtransformer.py index d7c5719..39ff777 100644 --- a/IPython/core/tests/test_inputtransformer.py +++ b/IPython/core/tests/test_inputtransformer.py @@ -66,3 +66,19 @@ leading_indent_tests = [ def test_leading_indent(): tt.check_pairs(wrap_transform(inputtransformer.leading_indent), leading_indent_tests) + +assign_magic_tests = [(i, [py3compat.u_format(ol) for ol in o]) for i,o in [ +(['a = %bc de \\', 'fg'], ["a = get_ipython().magic('bc de fg')"]), +(['a = %bc de \\', 'fg\\', None], ["a = get_ipython().magic('bc de fg')"]), +]] + +def test_assign_magic(): + tt.check_pairs(wrap_transform(inputtransformer.assign_from_magic), assign_magic_tests) + +assign_system_tests = [(i, [py3compat.u_format(ol) for ol in o]) for i,o in [ +(['a = !bc de \\', 'fg'], ["a = get_ipython().getoutput('bc de fg')"]), +(['a = !bc de \\', 'fg\\', None], ["a = get_ipython().getoutput('bc de fg')"]), +]] + +def test_assign_system(): + tt.check_pairs(wrap_transform(inputtransformer.assign_from_system), assign_system_tests)