~ibmcharmers/charms/xenial/ibm-cinder-storwize-svc/trunk

« back to all changes in this revision

Viewing changes to .tox/py35/lib/python3.5/site-packages/pyflakes/test/test_doctests.py

  • Committer: Ankammarao
  • Date: 2017-03-06 05:11:42 UTC
  • Revision ID: achittet@in.ibm.com-20170306051142-dpg27z4es1k56hfn
Marked tests folder executable

Show diffs side-by-side

added added

removed removed

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