]> crepu.dev Git - config.git/blob - djavu-asus/elpy/rpc-venv/lib/python3.11/site-packages/pyflakes/test/test_doctests.py
Actualizado el Readme
[config.git] / djavu-asus / elpy / rpc-venv / lib / python3.11 / site-packages / pyflakes / test / test_doctests.py
1 import textwrap
2
3 from pyflakes import messages as m
4 from pyflakes.checker import (
5 PYPY,
6 DoctestScope,
7 FunctionScope,
8 ModuleScope,
9 )
10 from pyflakes.test.test_other import Test as TestOther
11 from pyflakes.test.test_imports import Test as TestImports
12 from pyflakes.test.test_undefined_names import Test as TestUndefinedNames
13 from pyflakes.test.harness import TestCase, skip
14
15
16 class _DoctestMixin:
17
18 withDoctest = True
19
20 def doctestify(self, input):
21 lines = []
22 for line in textwrap.dedent(input).splitlines():
23 if line.strip() == '':
24 pass
25 elif (line.startswith(' ') or
26 line.startswith('except:') or
27 line.startswith('except ') or
28 line.startswith('finally:') or
29 line.startswith('else:') or
30 line.startswith('elif ') or
31 (lines and lines[-1].startswith(('>>> @', '... @')))):
32 line = "... %s" % line
33 else:
34 line = ">>> %s" % line
35 lines.append(line)
36 doctestificator = textwrap.dedent('''\
37 def doctest_something():
38 """
39 %s
40 """
41 ''')
42 return doctestificator % "\n ".join(lines)
43
44 def flakes(self, input, *args, **kw):
45 return super().flakes(self.doctestify(input), *args, **kw)
46
47
48 class Test(TestCase):
49
50 withDoctest = True
51
52 def test_scope_class(self):
53 """Check that a doctest is given a DoctestScope."""
54 checker = self.flakes("""
55 m = None
56
57 def doctest_stuff():
58 '''
59 >>> d = doctest_stuff()
60 '''
61 f = m
62 return f
63 """)
64
65 scopes = checker.deadScopes
66 module_scopes = [
67 scope for scope in scopes if scope.__class__ is ModuleScope]
68 doctest_scopes = [
69 scope for scope in scopes if scope.__class__ is DoctestScope]
70 function_scopes = [
71 scope for scope in scopes if scope.__class__ is FunctionScope]
72
73 self.assertEqual(len(module_scopes), 1)
74 self.assertEqual(len(doctest_scopes), 1)
75
76 module_scope = module_scopes[0]
77 doctest_scope = doctest_scopes[0]
78
79 self.assertIsInstance(doctest_scope, DoctestScope)
80 self.assertIsInstance(doctest_scope, ModuleScope)
81 self.assertNotIsInstance(doctest_scope, FunctionScope)
82 self.assertNotIsInstance(module_scope, DoctestScope)
83
84 self.assertIn('m', module_scope)
85 self.assertIn('doctest_stuff', module_scope)
86
87 self.assertIn('d', doctest_scope)
88
89 self.assertEqual(len(function_scopes), 1)
90 self.assertIn('f', function_scopes[0])
91
92 def test_nested_doctest_ignored(self):
93 """Check that nested doctests are ignored."""
94 checker = self.flakes("""
95 m = None
96
97 def doctest_stuff():
98 '''
99 >>> def function_in_doctest():
100 ... \"\"\"
101 ... >>> ignored_undefined_name
102 ... \"\"\"
103 ... df = m
104 ... return df
105 ...
106 >>> function_in_doctest()
107 '''
108 f = m
109 return f
110 """)
111
112 scopes = checker.deadScopes
113 module_scopes = [
114 scope for scope in scopes if scope.__class__ is ModuleScope]
115 doctest_scopes = [
116 scope for scope in scopes if scope.__class__ is DoctestScope]
117 function_scopes = [
118 scope for scope in scopes if scope.__class__ is FunctionScope]
119
120 self.assertEqual(len(module_scopes), 1)
121 self.assertEqual(len(doctest_scopes), 1)
122
123 module_scope = module_scopes[0]
124 doctest_scope = doctest_scopes[0]
125
126 self.assertIn('m', module_scope)
127 self.assertIn('doctest_stuff', module_scope)
128 self.assertIn('function_in_doctest', doctest_scope)
129
130 self.assertEqual(len(function_scopes), 2)
131
132 self.assertIn('f', function_scopes[0])
133 self.assertIn('df', function_scopes[1])
134
135 def test_global_module_scope_pollution(self):
136 """Check that global in doctest does not pollute module scope."""
137 checker = self.flakes("""
138 def doctest_stuff():
139 '''
140 >>> def function_in_doctest():
141 ... global m
142 ... m = 50
143 ... df = 10
144 ... m = df
145 ...
146 >>> function_in_doctest()
147 '''
148 f = 10
149 return f
150
151 """)
152
153 scopes = checker.deadScopes
154 module_scopes = [
155 scope for scope in scopes if scope.__class__ is ModuleScope]
156 doctest_scopes = [
157 scope for scope in scopes if scope.__class__ is DoctestScope]
158 function_scopes = [
159 scope for scope in scopes if scope.__class__ is FunctionScope]
160
161 self.assertEqual(len(module_scopes), 1)
162 self.assertEqual(len(doctest_scopes), 1)
163
164 module_scope = module_scopes[0]
165 doctest_scope = doctest_scopes[0]
166
167 self.assertIn('doctest_stuff', module_scope)
168 self.assertIn('function_in_doctest', doctest_scope)
169
170 self.assertEqual(len(function_scopes), 2)
171
172 self.assertIn('f', function_scopes[0])
173 self.assertIn('df', function_scopes[1])
174 self.assertIn('m', function_scopes[1])
175
176 self.assertNotIn('m', module_scope)
177
178 def test_global_undefined(self):
179 self.flakes("""
180 global m
181
182 def doctest_stuff():
183 '''
184 >>> m
185 '''
186 """, m.UndefinedName)
187
188 def test_nested_class(self):
189 """Doctest within nested class are processed."""
190 self.flakes("""
191 class C:
192 class D:
193 '''
194 >>> m
195 '''
196 def doctest_stuff(self):
197 '''
198 >>> m
199 '''
200 return 1
201 """, m.UndefinedName, m.UndefinedName)
202
203 def test_ignore_nested_function(self):
204 """Doctest module does not process doctest in nested functions."""
205 # 'syntax error' would cause a SyntaxError if the doctest was processed.
206 # However doctest does not find doctest in nested functions
207 # (https://bugs.python.org/issue1650090). If nested functions were
208 # processed, this use of m should cause UndefinedName, and the
209 # name inner_function should probably exist in the doctest scope.
210 self.flakes("""
211 def doctest_stuff():
212 def inner_function():
213 '''
214 >>> syntax error
215 >>> inner_function()
216 1
217 >>> m
218 '''
219 return 1
220 m = inner_function()
221 return m
222 """)
223
224 def test_inaccessible_scope_class(self):
225 """Doctest may not access class scope."""
226 self.flakes("""
227 class C:
228 def doctest_stuff(self):
229 '''
230 >>> m
231 '''
232 return 1
233 m = 1
234 """, m.UndefinedName)
235
236 def test_importBeforeDoctest(self):
237 self.flakes("""
238 import foo
239
240 def doctest_stuff():
241 '''
242 >>> foo
243 '''
244 """)
245
246 @skip("todo")
247 def test_importBeforeAndInDoctest(self):
248 self.flakes('''
249 import foo
250
251 def doctest_stuff():
252 """
253 >>> import foo
254 >>> foo
255 """
256
257 foo
258 ''', m.RedefinedWhileUnused)
259
260 def test_importInDoctestAndAfter(self):
261 self.flakes('''
262 def doctest_stuff():
263 """
264 >>> import foo
265 >>> foo
266 """
267
268 import foo
269 foo()
270 ''')
271
272 def test_offsetInDoctests(self):
273 exc = self.flakes('''
274
275 def doctest_stuff():
276 """
277 >>> x # line 5
278 """
279
280 ''', m.UndefinedName).messages[0]
281 self.assertEqual(exc.lineno, 5)
282 self.assertEqual(exc.col, 12)
283
284 def test_offsetInLambdasInDoctests(self):
285 exc = self.flakes('''
286
287 def doctest_stuff():
288 """
289 >>> lambda: x # line 5
290 """
291
292 ''', m.UndefinedName).messages[0]
293 self.assertEqual(exc.lineno, 5)
294 self.assertEqual(exc.col, 20)
295
296 def test_offsetAfterDoctests(self):
297 exc = self.flakes('''
298
299 def doctest_stuff():
300 """
301 >>> x = 5
302 """
303
304 x
305
306 ''', m.UndefinedName).messages[0]
307 self.assertEqual(exc.lineno, 8)
308 self.assertEqual(exc.col, 0)
309
310 def test_syntaxErrorInDoctest(self):
311 exceptions = self.flakes(
312 '''
313 def doctest_stuff():
314 """
315 >>> from # line 4
316 >>> fortytwo = 42
317 >>> except Exception:
318 """
319 ''',
320 m.DoctestSyntaxError,
321 m.DoctestSyntaxError,
322 m.DoctestSyntaxError).messages
323 exc = exceptions[0]
324 self.assertEqual(exc.lineno, 4)
325 if not PYPY:
326 self.assertEqual(exc.col, 18)
327 else:
328 self.assertEqual(exc.col, 26)
329
330 # PyPy error column offset is 0,
331 # for the second and third line of the doctest
332 # i.e. at the beginning of the line
333 exc = exceptions[1]
334 self.assertEqual(exc.lineno, 5)
335 if PYPY:
336 self.assertEqual(exc.col, 13)
337 else:
338 self.assertEqual(exc.col, 16)
339 exc = exceptions[2]
340 self.assertEqual(exc.lineno, 6)
341 self.assertEqual(exc.col, 13)
342
343 def test_indentationErrorInDoctest(self):
344 exc = self.flakes('''
345 def doctest_stuff():
346 """
347 >>> if True:
348 ... pass
349 """
350 ''', m.DoctestSyntaxError).messages[0]
351 self.assertEqual(exc.lineno, 5)
352 self.assertEqual(exc.col, 13)
353
354 def test_offsetWithMultiLineArgs(self):
355 (exc1, exc2) = self.flakes(
356 '''
357 def doctest_stuff(arg1,
358 arg2,
359 arg3):
360 """
361 >>> assert
362 >>> this
363 """
364 ''',
365 m.DoctestSyntaxError,
366 m.UndefinedName).messages
367 self.assertEqual(exc1.lineno, 6)
368 self.assertEqual(exc1.col, 19)
369 self.assertEqual(exc2.lineno, 7)
370 self.assertEqual(exc2.col, 12)
371
372 def test_doctestCanReferToFunction(self):
373 self.flakes("""
374 def foo():
375 '''
376 >>> foo
377 '''
378 """)
379
380 def test_doctestCanReferToClass(self):
381 self.flakes("""
382 class Foo():
383 '''
384 >>> Foo
385 '''
386 def bar(self):
387 '''
388 >>> Foo
389 '''
390 """)
391
392 def test_noOffsetSyntaxErrorInDoctest(self):
393 exceptions = self.flakes(
394 '''
395 def buildurl(base, *args, **kwargs):
396 """
397 >>> buildurl('/blah.php', ('a', '&'), ('b', '=')
398 '/blah.php?a=%26&b=%3D'
399 >>> buildurl('/blah.php', a='&', 'b'='=')
400 '/blah.php?b=%3D&a=%26'
401 """
402 pass
403 ''',
404 m.DoctestSyntaxError,
405 m.DoctestSyntaxError).messages
406 exc = exceptions[0]
407 self.assertEqual(exc.lineno, 4)
408 exc = exceptions[1]
409 self.assertEqual(exc.lineno, 6)
410
411 def test_singleUnderscoreInDoctest(self):
412 self.flakes('''
413 def func():
414 """A docstring
415
416 >>> func()
417 1
418 >>> _
419 1
420 """
421 return 1
422 ''')
423
424 def test_globalUnderscoreInDoctest(self):
425 self.flakes("""
426 from gettext import ugettext as _
427
428 def doctest_stuff():
429 '''
430 >>> pass
431 '''
432 """, m.UnusedImport)
433
434
435 class TestOther(_DoctestMixin, TestOther):
436 """Run TestOther with each test wrapped in a doctest."""
437
438
439 class TestImports(_DoctestMixin, TestImports):
440 """Run TestImports with each test wrapped in a doctest."""
441
442
443 class TestUndefinedNames(_DoctestMixin, TestUndefinedNames):
444 """Run TestUndefinedNames with each test wrapped in a doctest."""