test_prefilter.py
119 lines
| 4.0 KiB
| text/x-python
|
PythonLexer
Fernando Perez
|
r2426 | """Tests for input manipulation machinery.""" | ||
#----------------------------------------------------------------------------- | ||||
# Imports | ||||
#----------------------------------------------------------------------------- | ||||
import nose.tools as nt | ||||
Bradley M. Froehle
|
r6737 | from IPython.core.prefilter import AutocallChecker | ||
Paul Ivanov
|
r2618 | from IPython.testing.globalipapp import get_ipython | ||
Fernando Perez
|
r2426 | |||
#----------------------------------------------------------------------------- | ||||
# Tests | ||||
#----------------------------------------------------------------------------- | ||||
Fernando Perez
|
r2551 | ip = get_ipython() | ||
Fernando Perez
|
r2426 | def test_prefilter(): | ||
"""Test user input conversions""" | ||||
# pairs of (raw, expected correct) input | ||||
pairs = [ ('2+2','2+2'), | ||||
] | ||||
for raw, correct in pairs: | ||||
Thomas Kluyver
|
r12374 | nt.assert_equal(ip.prefilter(raw), correct) | ||
Fernando Perez
|
r2551 | |||
Thomas Kluyver
|
r12760 | def test_prefilter_shadowed(): | ||
def dummy_magic(line): pass | ||||
prev_automagic_state = ip.automagic | ||||
ip.automagic = True | ||||
Thomas Kluyver
|
r12761 | ip.autocall = 0 | ||
Thomas Kluyver
|
r12760 | |||
try: | ||||
# These should not be transformed - they are shadowed by other names | ||||
for name in ['if', 'zip', 'get_ipython']: # keyword, builtin, global | ||||
ip.register_magic_function(dummy_magic, magic_name=name) | ||||
res = ip.prefilter(name+' foo') | ||||
nt.assert_equal(res, name+' foo') | ||||
del ip.magics_manager.magics['line'][name] | ||||
# These should be transformed | ||||
for name in ['fi', 'piz', 'nohtypi_teg']: | ||||
ip.register_magic_function(dummy_magic, magic_name=name) | ||||
res = ip.prefilter(name+' foo') | ||||
nt.assert_not_equal(res, name+' foo') | ||||
del ip.magics_manager.magics['line'][name] | ||||
finally: | ||||
ip.automagic = prev_automagic_state | ||||
Fernando Perez
|
r5298 | |||
Fernando Perez
|
r2551 | def test_autocall_binops(): | ||
Thomas Kluyver
|
r3917 | """See https://github.com/ipython/ipython/issues/81""" | ||
Fernando Perez
|
r2551 | ip.magic('autocall 2') | ||
f = lambda x: x | ||||
ip.user_ns['f'] = f | ||||
try: | ||||
Thomas Kluyver
|
r12374 | nt.assert_equal(ip.prefilter('f 1'),'f(1)') | ||
Fernando Perez
|
r2551 | for t in ['f +1', 'f -1']: | ||
Thomas Kluyver
|
r12374 | nt.assert_equal(ip.prefilter(t), t) | ||
Bradley M. Froehle
|
r6737 | |||
# 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() | ||||
Thomas Kluyver
|
r12374 | nt.assert_equal(ip.prefilter('f -1'), 'f(-1)') | ||
nt.assert_equal(ip.prefilter('f +1'), 'f(+1)') | ||||
Bradley M. Froehle
|
r6737 | finally: | ||
pm.unregister_checker(ac) | ||||
Fernando Perez
|
r2551 | finally: | ||
ip.magic('autocall 0') | ||||
del ip.user_ns['f'] | ||||
Paul Ivanov
|
r2618 | |||
Fernando Perez
|
r5298 | |||
def test_issue_114(): | ||||
Paul Ivanov
|
r2618 | """Check that multiline string literals don't expand as magic | ||
Fernando Perez
|
r5298 | see http://github.com/ipython/ipython/issues/114""" | ||
Fernando Perez
|
r2648 | |||
Paul Ivanov
|
r2618 | template = '"""\n%s\n"""' | ||
Fernando Perez
|
r2648 | # 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: | ||||
Fernando Perez
|
r6942 | for mgk in ip.magics_manager.lsmagic()['line']: | ||
Fernando Perez
|
r2648 | raw = template % mgk | ||
Thomas Kluyver
|
r12374 | nt.assert_equal(ip.prefilter(raw), raw) | ||
Fernando Perez
|
r2648 | finally: | ||
ip.prefilter_manager.multi_line_specials = msp | ||||
Fernando Perez
|
r5298 | |||
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') | ||||