##// END OF EJS Templates
Merge pull request #13628 from Carreau/auto-backport-of-pr-13600-on-7.x...
Merge pull request #13628 from Carreau/auto-backport-of-pr-13600-on-7.x Backport PR #13600: Allow to get cellid from ipykernel

File last commit:

r27026:03e31878
r27631:c3f199f9 merge
Show More
test_inputtransformer2.py
358 lines | 9.8 KiB | text/x-python | PythonLexer
/ IPython / core / tests / test_inputtransformer2.py
Matthias Bussonnier
add docstring, and emit deprecation warnings
r24406 """Tests for the token-based transformers in IPython.core.inputtransformer2
Line-based transformers are the simpler ones; token-based transformers are
Thomas Kluyver
Add & improve docstrings following @willingc's review
r24407 more complex. See test_inputtransformer2_line for tests for line-based
transformations.
Matthias Bussonnier
add docstring, and emit deprecation warnings
r24406 """
Thomas Kluyver
Start adding tests for inputtransformer2
r24155 import nose.tools as nt
Matthias Bussonnier
Add some inputtransformer test cases
r24566 import string
Matthias Bussonnier
Backport PR #13270: Add Xfail test on 3.9.8
r27026 import sys
from textwrap import dedent
Thomas Kluyver
Start adding tests for inputtransformer2
r24155
Matthias Bussonnier
Backport PR #13270: Add Xfail test on 3.9.8
r27026 import pytest
Thomas Kluyver
Start adding tests for inputtransformer2
r24155
Matthias Bussonnier
Backport PR #13270: Add Xfail test on 3.9.8
r27026 from IPython.core import inputtransformer2 as ipt2
from IPython.core.inputtransformer2 import _find_assign_op, make_tokens_by_line
from IPython.testing.decorators import skip
Matthias Bussonnier
add tests
r24637
Thomas Kluyver
Escaped commands
r24159 MULTILINE_MAGIC = ("""\
a = f()
%foo \\
bar
g()
Thomas Kluyver
Transformations for 'help?' syntax
r24161 """.splitlines(keepends=True), (2, 0), """\
Thomas Kluyver
Escaped commands
r24159 a = f()
get_ipython().run_line_magic('foo', ' bar')
g()
""".splitlines(keepends=True))
Thomas Kluyver
Some more tests for escaped commands
r24160 INDENTED_MAGIC = ("""\
for a in range(5):
%ls
Thomas Kluyver
Transformations for 'help?' syntax
r24161 """.splitlines(keepends=True), (2, 4), """\
Thomas Kluyver
Some more tests for escaped commands
r24160 for a in range(5):
get_ipython().run_line_magic('ls', '')
""".splitlines(keepends=True))
Matthias Bussonnier
Backport PR #12475: Support CRLF line endings in magic transforms
r25949 CRLF_MAGIC = ([
"a = f()\n",
"%ls\r\n",
"g()\n"
], (2, 0), [
"a = f()\n",
"get_ipython().run_line_magic('ls', '')\n",
"g()\n"
])
Thomas Kluyver
Start adding tests for inputtransformer2
r24155 MULTILINE_MAGIC_ASSIGN = ("""\
a = f()
b = %foo \\
bar
g()
Thomas Kluyver
Transformations for 'help?' syntax
r24161 """.splitlines(keepends=True), (2, 4), """\
Thomas Kluyver
Start adding tests for inputtransformer2
r24155 a = f()
b = get_ipython().run_line_magic('foo', ' bar')
g()
""".splitlines(keepends=True))
MULTILINE_SYSTEM_ASSIGN = ("""\
a = f()
b = !foo \\
bar
g()
Thomas Kluyver
Transformations for 'help?' syntax
r24161 """.splitlines(keepends=True), (2, 4), """\
Thomas Kluyver
Start adding tests for inputtransformer2
r24155 a = f()
Thomas Kluyver
Add transformation for system assignments
r24156 b = get_ipython().getoutput('foo bar')
Thomas Kluyver
Start adding tests for inputtransformer2
r24155 g()
""".splitlines(keepends=True))
Matthias Bussonnier
Fix miss-capturing of assign statement after a dedent....
r24728 #####
MULTILINE_SYSTEM_ASSIGN_AFTER_DEDENT = ("""\
def test():
for i in range(1):
print(i)
res =! ls
""".splitlines(keepends=True), (4, 7), '''\
def test():
for i in range(1):
print(i)
res =get_ipython().getoutput(\' ls\')
'''.splitlines(keepends=True))
######
Thomas Kluyver
Some more tests for escaped commands
r24160 AUTOCALL_QUOTE = (
Thomas Kluyver
Transformations for 'help?' syntax
r24161 [",f 1 2 3\n"], (1, 0),
Thomas Kluyver
Some more tests for escaped commands
r24160 ['f("1", "2", "3")\n']
)
AUTOCALL_QUOTE2 = (
Thomas Kluyver
Transformations for 'help?' syntax
r24161 [";f 1 2 3\n"], (1, 0),
Thomas Kluyver
Some more tests for escaped commands
r24160 ['f("1 2 3")\n']
)
AUTOCALL_PAREN = (
Thomas Kluyver
Transformations for 'help?' syntax
r24161 ["/f 1 2 3\n"], (1, 0),
Thomas Kluyver
Some more tests for escaped commands
r24160 ['f(1, 2, 3)\n']
)
Thomas Kluyver
Transformations for 'help?' syntax
r24161 SIMPLE_HELP = (
["foo?\n"], (1, 0),
["get_ipython().run_line_magic('pinfo', 'foo')\n"]
)
DETAILED_HELP = (
["foo??\n"], (1, 0),
["get_ipython().run_line_magic('pinfo2', 'foo')\n"]
)
MAGIC_HELP = (
["%foo?\n"], (1, 0),
["get_ipython().run_line_magic('pinfo', '%foo')\n"]
)
HELP_IN_EXPR = (
["a = b + c?\n"], (1, 0),
["get_ipython().set_next_input('a = b + c');"
"get_ipython().run_line_magic('pinfo', 'c')\n"]
)
HELP_CONTINUED_LINE = ("""\
a = \\
zip?
""".splitlines(keepends=True), (1, 0),
[r"get_ipython().set_next_input('a = \\\nzip');get_ipython().run_line_magic('pinfo', 'zip')" + "\n"]
)
HELP_MULTILINE = ("""\
(a,
b) = zip?
""".splitlines(keepends=True), (1, 0),
[r"get_ipython().set_next_input('(a,\nb) = zip');get_ipython().run_line_magic('pinfo', 'zip')" + "\n"]
)
Matthias Bussonnier
Backport PR #12208: support for unicode identifiers
r25597 HELP_UNICODE = (
["Ï€.foo?\n"], (1, 0),
["get_ipython().run_line_magic('pinfo', 'Ï€.foo')\n"]
)
Matthias Bussonnier
Fix miss-capturing of assign statement after a dedent....
r24728
Tony Fast
Add tests for null cleanup test.
r24630 def null_cleanup_transformer(lines):
"""
A cleanup transform that returns an empty list.
"""
return []
Matthias Bussonnier
Add some inputtransformer test cases
r24566 def check_make_token_by_line_never_ends_empty():
"""
Check that not sequence of single or double characters ends up leading to en empty list of tokens
"""
from string import printable
for c in printable:
nt.assert_not_equal(make_tokens_by_line(c)[-1], [])
for k in printable:
nt.assert_not_equal(make_tokens_by_line(c+k)[-1], [])
Thomas Kluyver
Transformations for 'help?' syntax
r24161 def check_find(transformer, case, match=True):
sample, expected_start, _ = case
tbl = make_tokens_by_line(sample)
res = transformer.find(tbl)
if match:
# start_line is stored 0-indexed, expected values are 1-indexed
nt.assert_equal((res.start_line+1, res.start_col), expected_start)
return res
else:
nt.assert_is(res, None)
def check_transform(transformer_cls, case):
lines, start, expected = case
transformer = transformer_cls(start)
nt.assert_equal(transformer.transform(lines), expected)
Thomas Kluyver
Factor out handling of line continuations
r24157 def test_continued_line():
lines = MULTILINE_MAGIC_ASSIGN[0]
nt.assert_equal(ipt2.find_end_of_continued_line(lines, 1), 2)
nt.assert_equal(ipt2.assemble_continued_line(lines, (1, 5), 2), "foo bar")
Thomas Kluyver
Start adding tests for inputtransformer2
r24155 def test_find_assign_magic():
Thomas Kluyver
Transformations for 'help?' syntax
r24161 check_find(ipt2.MagicAssign, MULTILINE_MAGIC_ASSIGN)
check_find(ipt2.MagicAssign, MULTILINE_SYSTEM_ASSIGN, match=False)
Matthias Bussonnier
Fix miss-capturing of assign statement after a dedent....
r24728 check_find(ipt2.MagicAssign, MULTILINE_SYSTEM_ASSIGN_AFTER_DEDENT, match=False)
Thomas Kluyver
Start adding tests for inputtransformer2
r24155
def test_transform_assign_magic():
Thomas Kluyver
Transformations for 'help?' syntax
r24161 check_transform(ipt2.MagicAssign, MULTILINE_MAGIC_ASSIGN)
Thomas Kluyver
Add transformation for system assignments
r24156
def test_find_assign_system():
Thomas Kluyver
Transformations for 'help?' syntax
r24161 check_find(ipt2.SystemAssign, MULTILINE_SYSTEM_ASSIGN)
Matthias Bussonnier
Fix miss-capturing of assign statement after a dedent....
r24728 check_find(ipt2.SystemAssign, MULTILINE_SYSTEM_ASSIGN_AFTER_DEDENT)
Thomas Kluyver
Transformations for 'help?' syntax
r24161 check_find(ipt2.SystemAssign, (["a = !ls\n"], (1, 5), None))
check_find(ipt2.SystemAssign, (["a=!ls\n"], (1, 2), None))
check_find(ipt2.SystemAssign, MULTILINE_MAGIC_ASSIGN, match=False)
Thomas Kluyver
Add transformation for system assignments
r24156
Thomas Kluyver
Transformations for 'help?' syntax
r24161 def test_transform_assign_system():
check_transform(ipt2.SystemAssign, MULTILINE_SYSTEM_ASSIGN)
Matthias Bussonnier
Fix miss-capturing of assign statement after a dedent....
r24728 check_transform(ipt2.SystemAssign, MULTILINE_SYSTEM_ASSIGN_AFTER_DEDENT)
Thomas Kluyver
Add transformation for system assignments
r24156
Thomas Kluyver
Transformations for 'help?' syntax
r24161 def test_find_magic_escape():
check_find(ipt2.EscapedCommand, MULTILINE_MAGIC)
check_find(ipt2.EscapedCommand, INDENTED_MAGIC)
check_find(ipt2.EscapedCommand, MULTILINE_MAGIC_ASSIGN, match=False)
Thomas Kluyver
Add transformation for system assignments
r24156
Thomas Kluyver
Transformations for 'help?' syntax
r24161 def test_transform_magic_escape():
check_transform(ipt2.EscapedCommand, MULTILINE_MAGIC)
check_transform(ipt2.EscapedCommand, INDENTED_MAGIC)
Matthias Bussonnier
Backport PR #12475: Support CRLF line endings in magic transforms
r25949 check_transform(ipt2.EscapedCommand, CRLF_MAGIC)
Thomas Kluyver
Add transformation for system assignments
r24156
Thomas Kluyver
Transformations for 'help?' syntax
r24161 def test_find_autocalls():
for case in [AUTOCALL_QUOTE, AUTOCALL_QUOTE2, AUTOCALL_PAREN]:
print("Testing %r" % case[0])
check_find(ipt2.EscapedCommand, case)
Thomas Kluyver
Escaped commands
r24159
Thomas Kluyver
Transformations for 'help?' syntax
r24161 def test_transform_autocall():
for case in [AUTOCALL_QUOTE, AUTOCALL_QUOTE2, AUTOCALL_PAREN]:
print("Testing %r" % case[0])
check_transform(ipt2.EscapedCommand, case)
Thomas Kluyver
Escaped commands
r24159
Thomas Kluyver
Transformations for 'help?' syntax
r24161 def test_find_help():
for case in [SIMPLE_HELP, DETAILED_HELP, MAGIC_HELP, HELP_IN_EXPR]:
check_find(ipt2.HelpEnd, case)
Thomas Kluyver
Some more tests for escaped commands
r24160
Thomas Kluyver
Transformations for 'help?' syntax
r24161 tf = check_find(ipt2.HelpEnd, HELP_CONTINUED_LINE)
nt.assert_equal(tf.q_line, 1)
nt.assert_equal(tf.q_col, 3)
Thomas Kluyver
Escaped commands
r24159
Thomas Kluyver
Transformations for 'help?' syntax
r24161 tf = check_find(ipt2.HelpEnd, HELP_MULTILINE)
nt.assert_equal(tf.q_line, 1)
nt.assert_equal(tf.q_col, 8)
Thomas Kluyver
Some more tests for escaped commands
r24160
Thomas Kluyver
Transformations for 'help?' syntax
r24161 # ? in a comment does not trigger help
check_find(ipt2.HelpEnd, (["foo # bar?\n"], None, None), match=False)
# Nor in a string
check_find(ipt2.HelpEnd, (["foo = '''bar?\n"], None, None), match=False)
Thomas Kluyver
Some more tests for escaped commands
r24160
Thomas Kluyver
Transformations for 'help?' syntax
r24161 def test_transform_help():
tf = ipt2.HelpEnd((1, 0), (1, 9))
nt.assert_equal(tf.transform(HELP_IN_EXPR[0]), HELP_IN_EXPR[2])
Thomas Kluyver
Some more tests for escaped commands
r24160
Thomas Kluyver
Transformations for 'help?' syntax
r24161 tf = ipt2.HelpEnd((1, 0), (2, 3))
nt.assert_equal(tf.transform(HELP_CONTINUED_LINE[0]), HELP_CONTINUED_LINE[2])
tf = ipt2.HelpEnd((1, 0), (2, 8))
nt.assert_equal(tf.transform(HELP_MULTILINE[0]), HELP_MULTILINE[2])
Thomas Kluyver
Start adding code for checking when input is complete
r24165
Matthias Bussonnier
Backport PR #12208: support for unicode identifiers
r25597 tf = ipt2.HelpEnd((1, 0), (1, 0))
nt.assert_equal(tf.transform(HELP_UNICODE[0]), HELP_UNICODE[2])
Matthias Bussonnier
Fix miss-capturing of assign statement after a dedent....
r24728 def test_find_assign_op_dedent():
"""
luz.paz
Fix misc. comment typos...
r24756 be careful that empty token like dedent are not counted as parens
Matthias Bussonnier
Fix miss-capturing of assign statement after a dedent....
r24728 """
class Tk:
def __init__(self, s):
self.string = s
nt.assert_equal(_find_assign_op([Tk(s) for s in ('','a','=','b')]), 2)
nt.assert_equal(_find_assign_op([Tk(s) for s in ('','(', 'a','=','b', ')', '=' ,'5')]), 6)
Matthias Bussonnier
Backport PR #13270: Add Xfail test on 3.9.8
r27026 examples = [
pytest.param("a = 1", "complete", None),
pytest.param("for a in range(5):", "incomplete", 4),
pytest.param("for a in range(5):\n if a > 0:", "incomplete", 8),
pytest.param("raise = 2", "invalid", None),
pytest.param("a = [1,\n2,", "incomplete", 0),
pytest.param("(\n))", "incomplete", 0),
pytest.param("\\\r\n", "incomplete", 0),
pytest.param("a = '''\n hi", "incomplete", 3),
pytest.param("def a():\n x=1\n global x", "invalid", None),
pytest.param(
"a \\ ",
"invalid",
None,
marks=pytest.mark.xfail(
reason="Bug in python 3.9.8 – bpo 45738",
condition=sys.version_info[:3] == (3, 9, 8),
raises=SystemError,
strict=True,
),
), # Nothing allowed after backslash,
pytest.param("1\\\n+2", "complete", None),
]
@skip('Tested on master, skip only on iptest not available on 7.x')
@pytest.mark.xfail(
reason="Bug in python 3.9.8 – bpo 45738",
condition=sys.version_info[:3] == (3, 9, 8),
)
Thomas Kluyver
Start adding code for checking when input is complete
r24165 def test_check_complete():
Thomas Kluyver
Start integrating new machinery for checking code completeness
r24166 cc = ipt2.TransformerManager().check_complete
Matthias Bussonnier
Add some inputtransformer test cases
r24566
Matthias Bussonnier
add tests
r24637 example = dedent("""
if True:
a=1""" )
nt.assert_equal(cc(example), ('incomplete', 4))
nt.assert_equal(cc(example+'\n'), ('complete', None))
nt.assert_equal(cc(example+'\n '), ('complete', None))
Matthias Bussonnier
Add some inputtransformer test cases
r24566 # no need to loop on all the letters/numbers.
short = '12abAB'+string.printable[62:]
for c in short:
# test does not raise:
cc(c)
for k in short:
cc(c+k)
Dominik Miedziński
Fix handling of repeated NEWLINE tokens
r25393 nt.assert_equal(cc("def f():\n x=0\n \\\n "), ('incomplete', 2))
Matthias Bussonnier
Fix to allow entering docstring into IPython....
r24701 def test_check_complete_II():
"""
Test that multiple line strings are properly handled.
Separate test function for convenience
"""
cc = ipt2.TransformerManager().check_complete
nt.assert_equal(cc('''def foo():\n """'''), ('incomplete', 4))
Tony Fast
Add tests for null cleanup test.
r24630 def test_null_cleanup_transformer():
manager = ipt2.TransformerManager()
manager.cleanup_transforms.insert(0, null_cleanup_transformer)
Matthias Bussonnier
Backport PR #12456: Allow to mark transformers as having side effects
r25930 assert manager.transform_cell("") == ""
def test_side_effects_I():
count = 0
def counter(lines):
nonlocal count
count += 1
return lines
counter.has_side_effects = True
manager = ipt2.TransformerManager()
manager.cleanup_transforms.insert(0, counter)
assert manager.check_complete("a=1\n") == ('complete', None)
assert count == 0
def test_side_effects_II():
count = 0
def counter(lines):
nonlocal count
count += 1
return lines
counter.has_side_effects = True
manager = ipt2.TransformerManager()
manager.line_transforms.insert(0, counter)
assert manager.check_complete("b=1\n") == ('complete', None)
assert count == 0