##// END OF EJS Templates
[core][tests][async_helpers] Remove nose
Samuel Gaist -
Show More
@@ -1,316 +1,315 b''
1 1 """
2 2 Test for async helpers.
3 3
4 4 Should only trigger on python 3.5+ or will have syntax errors.
5 5 """
6 6 from itertools import chain, repeat
7 import nose.tools as nt
8 7 from textwrap import dedent, indent
9 8 from unittest import TestCase
10 9 from IPython.testing.decorators import skip_without
11 10 import sys
12 11 from typing import TYPE_CHECKING
13 12
14 13 if TYPE_CHECKING:
15 14 from IPython import get_ipython
16 15
17 16 ip = get_ipython()
18 17
19 18
20 19 iprc = lambda x: ip.run_cell(dedent(x)).raise_error()
21 20 iprc_nr = lambda x: ip.run_cell(dedent(x))
22 21
23 22 from IPython.core.async_helpers import _should_be_async
24 23
25 24 class AsyncTest(TestCase):
26 25 def test_should_be_async(self):
27 nt.assert_false(_should_be_async("False"))
28 nt.assert_true(_should_be_async("await bar()"))
29 nt.assert_true(_should_be_async("x = await bar()"))
30 nt.assert_false(
26 self.assertFalse(_should_be_async("False"))
27 self.assertTrue(_should_be_async("await bar()"))
28 self.assertTrue(_should_be_async("x = await bar()"))
29 self.assertFalse(
31 30 _should_be_async(
32 31 dedent(
33 32 """
34 33 async def awaitable():
35 34 pass
36 35 """
37 36 )
38 37 )
39 38 )
40 39
41 40 def _get_top_level_cases(self):
42 41 # These are test cases that should be valid in a function
43 42 # but invalid outside of a function.
44 43 test_cases = []
45 44 test_cases.append(('basic', "{val}"))
46 45
47 46 # Note, in all conditional cases, I use True instead of
48 47 # False so that the peephole optimizer won't optimize away
49 48 # the return, so CPython will see this as a syntax error:
50 49 #
51 50 # while True:
52 51 # break
53 52 # return
54 53 #
55 54 # But not this:
56 55 #
57 56 # while False:
58 57 # return
59 58 #
60 59 # See https://bugs.python.org/issue1875
61 60
62 61 test_cases.append(('if', dedent("""
63 62 if True:
64 63 {val}
65 64 """)))
66 65
67 66 test_cases.append(('while', dedent("""
68 67 while True:
69 68 {val}
70 69 break
71 70 """)))
72 71
73 72 test_cases.append(('try', dedent("""
74 73 try:
75 74 {val}
76 75 except:
77 76 pass
78 77 """)))
79 78
80 79 test_cases.append(('except', dedent("""
81 80 try:
82 81 pass
83 82 except:
84 83 {val}
85 84 """)))
86 85
87 86 test_cases.append(('finally', dedent("""
88 87 try:
89 88 pass
90 89 except:
91 90 pass
92 91 finally:
93 92 {val}
94 93 """)))
95 94
96 95 test_cases.append(('for', dedent("""
97 96 for _ in range(4):
98 97 {val}
99 98 """)))
100 99
101 100
102 101 test_cases.append(('nested', dedent("""
103 102 if True:
104 103 while True:
105 104 {val}
106 105 break
107 106 """)))
108 107
109 108 test_cases.append(('deep-nested', dedent("""
110 109 if True:
111 110 while True:
112 111 break
113 112 for x in range(3):
114 113 if True:
115 114 while True:
116 115 for x in range(3):
117 116 {val}
118 117 """)))
119 118
120 119 return test_cases
121 120
122 121 def _get_ry_syntax_errors(self):
123 122 # This is a mix of tests that should be a syntax error if
124 123 # return or yield whether or not they are in a function
125 124
126 125 test_cases = []
127 126
128 127 test_cases.append(('class', dedent("""
129 128 class V:
130 129 {val}
131 130 """)))
132 131
133 132 test_cases.append(('nested-class', dedent("""
134 133 class V:
135 134 class C:
136 135 {val}
137 136 """)))
138 137
139 138 return test_cases
140 139
141 140
142 141 def test_top_level_return_error(self):
143 142 tl_err_test_cases = self._get_top_level_cases()
144 143 tl_err_test_cases.extend(self._get_ry_syntax_errors())
145 144
146 145 vals = ('return', 'yield', 'yield from (_ for _ in range(3))',
147 146 dedent('''
148 147 def f():
149 148 pass
150 149 return
151 150 '''),
152 151 )
153 152
154 153 for test_name, test_case in tl_err_test_cases:
155 154 # This example should work if 'pass' is used as the value
156 155 with self.subTest((test_name, 'pass')):
157 156 iprc(test_case.format(val='pass'))
158 157
159 158 # It should fail with all the values
160 159 for val in vals:
161 160 with self.subTest((test_name, val)):
162 161 msg = "Syntax error not raised for %s, %s" % (test_name, val)
163 162 with self.assertRaises(SyntaxError, msg=msg):
164 163 iprc(test_case.format(val=val))
165 164
166 165 def test_in_func_no_error(self):
167 166 # Test that the implementation of top-level return/yield
168 167 # detection isn't *too* aggressive, and works inside a function
169 168 func_contexts = []
170 169
171 170 func_contexts.append(('func', False, dedent("""
172 171 def f():""")))
173 172
174 173 func_contexts.append(('method', False, dedent("""
175 174 class MyClass:
176 175 def __init__(self):
177 176 """)))
178 177
179 178 func_contexts.append(('async-func', True, dedent("""
180 179 async def f():""")))
181 180
182 181 func_contexts.append(('async-method', True, dedent("""
183 182 class MyClass:
184 183 async def f(self):""")))
185 184
186 185 func_contexts.append(('closure', False, dedent("""
187 186 def f():
188 187 def g():
189 188 """)))
190 189
191 190 def nest_case(context, case):
192 191 # Detect indentation
193 192 lines = context.strip().splitlines()
194 193 prefix_len = 0
195 194 for c in lines[-1]:
196 195 if c != ' ':
197 196 break
198 197 prefix_len += 1
199 198
200 199 indented_case = indent(case, ' ' * (prefix_len + 4))
201 200 return context + '\n' + indented_case
202 201
203 202 # Gather and run the tests
204 203
205 204 # yield is allowed in async functions, starting in Python 3.6,
206 205 # and yield from is not allowed in any version
207 206 vals = ('return', 'yield', 'yield from (_ for _ in range(3))')
208 207
209 208 success_tests = zip(self._get_top_level_cases(), repeat(False))
210 209 failure_tests = zip(self._get_ry_syntax_errors(), repeat(True))
211 210
212 211 tests = chain(success_tests, failure_tests)
213 212
214 213 for context_name, async_func, context in func_contexts:
215 214 for (test_name, test_case), should_fail in tests:
216 215 nested_case = nest_case(context, test_case)
217 216
218 217 for val in vals:
219 218 test_id = (context_name, test_name, val)
220 219 cell = nested_case.format(val=val)
221 220
222 221 with self.subTest(test_id):
223 222 if should_fail:
224 223 msg = ("SyntaxError not raised for %s" %
225 224 str(test_id))
226 225 with self.assertRaises(SyntaxError, msg=msg):
227 226 iprc(cell)
228 227
229 228 print(cell)
230 229 else:
231 230 iprc(cell)
232 231
233 232 def test_nonlocal(self):
234 233 # fails if outer scope is not a function scope or if var not defined
235 234 with self.assertRaises(SyntaxError):
236 235 iprc("nonlocal x")
237 236 iprc("""
238 237 x = 1
239 238 def f():
240 239 nonlocal x
241 240 x = 10000
242 241 yield x
243 242 """)
244 243 iprc("""
245 244 def f():
246 245 def g():
247 246 nonlocal x
248 247 x = 10000
249 248 yield x
250 249 """)
251 250
252 251 # works if outer scope is a function scope and var exists
253 252 iprc("""
254 253 def f():
255 254 x = 20
256 255 def g():
257 256 nonlocal x
258 257 x = 10000
259 258 yield x
260 259 """)
261 260
262 261
263 262 def test_execute(self):
264 263 iprc("""
265 264 import asyncio
266 265 await asyncio.sleep(0.001)
267 266 """
268 267 )
269 268
270 269 def test_autoawait(self):
271 270 iprc("%autoawait False")
272 271 iprc("%autoawait True")
273 272 iprc("""
274 273 from asyncio import sleep
275 274 await sleep(0.1)
276 275 """
277 276 )
278 277
279 278 if sys.version_info < (3,9):
280 279 # new pgen parser in 3.9 does not raise MemoryError on too many nested
281 280 # parens anymore
282 281 def test_memory_error(self):
283 282 with self.assertRaises(MemoryError):
284 283 iprc("(" * 200 + ")" * 200)
285 284
286 285 @skip_without('curio')
287 286 def test_autoawait_curio(self):
288 287 iprc("%autoawait curio")
289 288
290 289 @skip_without('trio')
291 290 def test_autoawait_trio(self):
292 291 iprc("%autoawait trio")
293 292
294 293 @skip_without('trio')
295 294 def test_autoawait_trio_wrong_sleep(self):
296 295 iprc("%autoawait trio")
297 296 res = iprc_nr("""
298 297 import asyncio
299 298 await asyncio.sleep(0)
300 299 """)
301 with nt.assert_raises(TypeError):
300 with self.assertRaises(TypeError):
302 301 res.raise_error()
303 302
304 303 @skip_without('trio')
305 304 def test_autoawait_asyncio_wrong_sleep(self):
306 305 iprc("%autoawait asyncio")
307 306 res = iprc_nr("""
308 307 import trio
309 308 await trio.sleep(0)
310 309 """)
311 with nt.assert_raises(RuntimeError):
310 with self.assertRaises(RuntimeError):
312 311 res.raise_error()
313 312
314 313
315 314 def tearDown(self):
316 315 ip.loop_runner = "asyncio"
General Comments 0
You need to be logged in to leave comments. Login now