|
|
"""Tests for input manipulation machinery."""
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
# Imports
|
|
|
#-----------------------------------------------------------------------------
|
|
|
import nose.tools as nt
|
|
|
|
|
|
from IPython.core.prefilter import AutocallChecker
|
|
|
from IPython.testing import decorators as dec
|
|
|
from IPython.testing.globalipapp import get_ipython
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
# Tests
|
|
|
#-----------------------------------------------------------------------------
|
|
|
ip = get_ipython()
|
|
|
|
|
|
@dec.parametric
|
|
|
def test_prefilter():
|
|
|
"""Test user input conversions"""
|
|
|
|
|
|
# pairs of (raw, expected correct) input
|
|
|
pairs = [ ('2+2','2+2'),
|
|
|
]
|
|
|
|
|
|
for raw, correct in pairs:
|
|
|
yield nt.assert_equal(ip.prefilter(raw), correct)
|
|
|
|
|
|
|
|
|
@dec.parametric
|
|
|
def test_autocall_binops():
|
|
|
"""See https://github.com/ipython/ipython/issues/81"""
|
|
|
ip.magic('autocall 2')
|
|
|
f = lambda x: x
|
|
|
ip.user_ns['f'] = f
|
|
|
try:
|
|
|
yield nt.assert_equal(ip.prefilter('f 1'),'f(1)')
|
|
|
for t in ['f +1', 'f -1']:
|
|
|
yield nt.assert_equal(ip.prefilter(t), t)
|
|
|
|
|
|
# Run tests again with a more permissive exclude_regexp, which will
|
|
|
# allow transformation of binary operations ('f -1' -> 'f(-1)').
|
|
|
pm = ip.prefilter_manager
|
|
|
ac = AutocallChecker(shell=pm.shell, prefilter_manager=pm,
|
|
|
config=pm.config)
|
|
|
try:
|
|
|
ac.priority = 1
|
|
|
ac.exclude_regexp = r'^[,&^\|\*/]|^is |^not |^in |^and |^or '
|
|
|
pm.sort_checkers()
|
|
|
|
|
|
yield nt.assert_equal(ip.prefilter('f -1'), 'f(-1)')
|
|
|
yield nt.assert_equal(ip.prefilter('f +1'), 'f(+1)')
|
|
|
finally:
|
|
|
pm.unregister_checker(ac)
|
|
|
finally:
|
|
|
ip.magic('autocall 0')
|
|
|
del ip.user_ns['f']
|
|
|
|
|
|
|
|
|
@dec.parametric
|
|
|
def test_issue_114():
|
|
|
"""Check that multiline string literals don't expand as magic
|
|
|
see http://github.com/ipython/ipython/issues/114"""
|
|
|
|
|
|
template = '"""\n%s\n"""'
|
|
|
# Store the current value of multi_line_specials and turn it off before
|
|
|
# running test, since it could be true (case in which the test doesn't make
|
|
|
# sense, as multiline string literals *will* expand as magic in that case).
|
|
|
msp = ip.prefilter_manager.multi_line_specials
|
|
|
ip.prefilter_manager.multi_line_specials = False
|
|
|
try:
|
|
|
for mgk in ip.magics_manager.lsmagic()['line']:
|
|
|
raw = template % mgk
|
|
|
yield nt.assert_equal(ip.prefilter(raw), raw)
|
|
|
finally:
|
|
|
ip.prefilter_manager.multi_line_specials = msp
|
|
|
|
|
|
|
|
|
def test_prefilter_attribute_errors():
|
|
|
"""Capture exceptions thrown by user objects on attribute access.
|
|
|
|
|
|
See http://github.com/ipython/ipython/issues/988."""
|
|
|
|
|
|
class X(object):
|
|
|
def __getattr__(self, k):
|
|
|
raise ValueError('broken object')
|
|
|
def __call__(self, x):
|
|
|
return x
|
|
|
|
|
|
# Create a callable broken object
|
|
|
ip.user_ns['x'] = X()
|
|
|
ip.magic('autocall 2')
|
|
|
try:
|
|
|
# Even if x throws an attribute error when looking at its rewrite
|
|
|
# attribute, we should not crash. So the test here is simply making
|
|
|
# the prefilter call and not having an exception.
|
|
|
ip.prefilter('x 1')
|
|
|
finally:
|
|
|
del ip.user_ns['x']
|
|
|
ip.magic('autocall 0')
|
|
|
|