##// END OF EJS Templates
test for autocall regression...
Paul Ivanov -
Show More
@@ -1,139 +1,149
1 1 """Tests for input manipulation machinery."""
2 2
3 3 #-----------------------------------------------------------------------------
4 4 # Imports
5 5 #-----------------------------------------------------------------------------
6 6 import pytest
7 7
8 8 from IPython.core.prefilter import AutocallChecker
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Tests
12 12 #-----------------------------------------------------------------------------
13 13
14 14 def test_prefilter():
15 15 """Test user input conversions"""
16 16
17 17 # pairs of (raw, expected correct) input
18 18 pairs = [ ('2+2','2+2'),
19 19 ]
20 20
21 21 for raw, correct in pairs:
22 22 assert ip.prefilter(raw) == correct
23 23
24 24 def test_prefilter_shadowed():
25 25 def dummy_magic(line): pass
26 26
27 27 prev_automagic_state = ip.automagic
28 28 ip.automagic = True
29 29 ip.autocall = 0
30 30
31 31 try:
32 32 # These should not be transformed - they are shadowed by other names
33 33 for name in ['if', 'zip', 'get_ipython']: # keyword, builtin, global
34 34 ip.register_magic_function(dummy_magic, magic_name=name)
35 35 res = ip.prefilter(name + " foo")
36 36 assert res == name + " foo"
37 37 del ip.magics_manager.magics["line"][name]
38 38
39 39 # These should be transformed
40 40 for name in ['fi', 'piz', 'nohtypi_teg']:
41 41 ip.register_magic_function(dummy_magic, magic_name=name)
42 42 res = ip.prefilter(name + " foo")
43 43 assert res != name + " foo"
44 44 del ip.magics_manager.magics["line"][name]
45 45
46 46 finally:
47 47 ip.automagic = prev_automagic_state
48 48
49 49 def test_autocall_binops():
50 50 """See https://github.com/ipython/ipython/issues/81"""
51 51 ip.run_line_magic("autocall", "2")
52 52 f = lambda x: x
53 53 ip.user_ns['f'] = f
54 54 try:
55 55 assert ip.prefilter("f 1") == "f(1)"
56 56 for t in ["f +1", "f -1"]:
57 57 assert ip.prefilter(t) == t
58 58
59 59 # Run tests again with a more permissive exclude_regexp, which will
60 60 # allow transformation of binary operations ('f -1' -> 'f(-1)').
61 61 pm = ip.prefilter_manager
62 62 ac = AutocallChecker(shell=pm.shell, prefilter_manager=pm,
63 63 config=pm.config)
64 64 try:
65 65 ac.priority = 1
66 66 ac.exclude_regexp = r'^[,&^\|\*/]|^is |^not |^in |^and |^or '
67 67 pm.sort_checkers()
68 68
69 69 assert ip.prefilter("f -1") == "f(-1)"
70 70 assert ip.prefilter("f +1") == "f(+1)"
71 71 finally:
72 72 pm.unregister_checker(ac)
73 73 finally:
74 74 ip.run_line_magic("autocall", "0")
75 75 del ip.user_ns["f"]
76 76
77 77
78 78 def test_issue_114():
79 79 """Check that multiline string literals don't expand as magic
80 80 see http://github.com/ipython/ipython/issues/114"""
81 81
82 82 template = '"""\n%s\n"""'
83 83 # Store the current value of multi_line_specials and turn it off before
84 84 # running test, since it could be true (case in which the test doesn't make
85 85 # sense, as multiline string literals *will* expand as magic in that case).
86 86 msp = ip.prefilter_manager.multi_line_specials
87 87 ip.prefilter_manager.multi_line_specials = False
88 88 try:
89 89 for mgk in ip.magics_manager.lsmagic()['line']:
90 90 raw = template % mgk
91 91 assert ip.prefilter(raw) == raw
92 92 finally:
93 93 ip.prefilter_manager.multi_line_specials = msp
94 94
95 95
96 96 def test_prefilter_attribute_errors():
97 97 """Capture exceptions thrown by user objects on attribute access.
98 98
99 99 See http://github.com/ipython/ipython/issues/988."""
100 100
101 101 class X(object):
102 102 def __getattr__(self, k):
103 103 raise ValueError('broken object')
104 104 def __call__(self, x):
105 105 return x
106 106
107 107 # Create a callable broken object
108 108 ip.user_ns["x"] = X()
109 109 ip.run_line_magic("autocall", "2")
110 110 try:
111 111 # Even if x throws an attribute error when looking at its rewrite
112 112 # attribute, we should not crash. So the test here is simply making
113 113 # the prefilter call and not having an exception.
114 114 ip.prefilter('x 1')
115 115 finally:
116 116 del ip.user_ns["x"]
117 117 ip.run_line_magic("autocall", "0")
118 118
119 119
120 120 def test_autocall_type_ann():
121 121 ip.run_cell("import collections.abc")
122 122 ip.run_line_magic("autocall", "1")
123 123 try:
124 124 assert (
125 125 ip.prefilter("collections.abc.Callable[[int], None]")
126 126 == "collections.abc.Callable[[int], None]"
127 127 )
128 128 finally:
129 129 ip.run_line_magic("autocall", "0")
130 130
131 131
132 132 def test_autocall_should_support_unicode():
133 133 ip.run_line_magic("autocall", "2")
134 134 ip.user_ns["π"] = lambda x: x
135 135 try:
136 136 assert ip.prefilter("π 3") == "π(3)"
137 137 finally:
138 138 ip.run_line_magic("autocall", "0")
139 139 del ip.user_ns["π"]
140
141
142 def test_autocall_regression_gh_14513():
143 ip.run_line_magic("autocall", "2")
144 ip.user_ns["foo"] = dict()
145 try:
146 assert ip.prefilter("foo") == "foo"
147 finally:
148 ip.run_line_magic("autocall", "0")
149 del ip.user_ns["foo"]
General Comments 0
You need to be logged in to leave comments. Login now