Statistics
| Revision:

gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.app / org.gvsig.scripting.app.mainplugin / src / main / resources-plugin / scripting / lib / pylint / test / extensions / test_check_docs.py @ 745

History | View | Annotate | Download (19.2 KB)

1
"""Unit tests for the pylint checkers in :mod:`pylint.extensions.check_docs`,
2
in particular the parameter documentation checker `ParamDocChecker`
3
"""
4
from __future__ import division, print_function, absolute_import
5

    
6
import unittest
7
import sys
8

    
9
import astroid
10
from astroid import test_utils
11
from pylint.testutils import CheckerTestCase, Message, set_config
12

    
13
from pylint.extensions.check_docs import ParamDocChecker, space_indentation
14

    
15

    
16
class ParamDocCheckerTest(CheckerTestCase):
17
    """Tests for pylint_plugin.ParamDocChecker"""
18
    CHECKER_CLASS = ParamDocChecker
19

    
20
    def test_space_indentation(self):
21
        self.assertEqual(space_indentation('abc'), 0)
22
        self.assertEqual(space_indentation(''), 0)
23
        self.assertEqual(space_indentation('  abc'), 2)
24
        self.assertEqual(space_indentation('\n  abc'), 0)
25
        self.assertEqual(space_indentation('   \n  abc'), 3)
26

    
27
    def test_missing_func_params_in_sphinx_docstring(self):
28
        """Example of a function with missing Sphinx parameter documentation in
29
        the docstring
30
        """
31
        node = test_utils.extract_node("""
32
        def function_foo(x, y, z):
33
            '''docstring ...
34

35
            :param x: bla
36

37
            :param int z: bar
38
            '''
39
            pass
40
        """)
41
        with self.assertAddsMessages(
42
            Message(
43
                msg_id='missing-param-doc',
44
                node=node,
45
                args=('y',)),
46
            Message(
47
                msg_id='missing-type-doc',
48
                node=node,
49
                args=('x, y',))
50
        ):
51
            self.checker.visit_functiondef(node)
52

    
53
    def test_missing_func_params_in_google_docstring(self):
54
        """Example of a function with missing Google style parameter
55
        documentation in the docstring
56
        """
57
        node = test_utils.extract_node("""
58
        def function_foo(x, y, z):
59
            '''docstring ...
60

61
            Args:
62
                x: bla
63
                z (int): bar
64

65
            some other stuff
66
            '''
67
            pass
68
        """)
69
        with self.assertAddsMessages(
70
            Message(
71
                msg_id='missing-param-doc',
72
                node=node,
73
                args=('y',)),
74
            Message(
75
                msg_id='missing-type-doc',
76
                node=node,
77
                args=('x, y',))
78
        ):
79
            self.checker.visit_functiondef(node)
80

    
81
    def test_missing_func_params_in_numpy_docstring(self):
82
        """Example of a function with missing NumPy style parameter
83
        documentation in the docstring
84
        """
85
        node = test_utils.extract_node("""
86
        def function_foo(x, y, z):
87
            '''docstring ...
88

89
            Parameters
90
            ----------
91
            x:
92
                bla
93
            z: int
94
                bar
95

96
            some other stuff
97
            '''
98
            pass
99
        """)
100
        with self.assertAddsMessages(
101
            Message(
102
                msg_id='missing-param-doc',
103
                node=node,
104
                args=('y',)),
105
            Message(
106
                msg_id='missing-type-doc',
107
                node=node,
108
                args=('x, y',))
109
        ):
110
            self.checker.visit_functiondef(node)
111

    
112
    def test_tolerate_no_param_documentation_at_all(self):
113
        """Example of a function with no parameter documentation at all
114

115
        No error message is emitted.
116
        """
117
        node = test_utils.extract_node("""
118
        def function_foo(x, y):
119
            '''docstring ...
120

121
            missing parameter documentation'''
122
            pass
123
        """)
124
        with self.assertNoMessages():
125
            self.checker.visit_functiondef(node)
126

    
127
    @set_config(accept_no_param_doc=False)
128
    def test_don_t_tolerate_no_param_documentation_at_all(self):
129
        """Example of a function with no parameter documentation at all
130

131
        No error message is emitted.
132
        """
133
        node = test_utils.extract_node("""
134
        def function_foo(x, y):
135
            '''docstring ...
136

137
            missing parameter documentation'''
138
            pass
139
        """)
140
        with self.assertAddsMessages(
141
            Message(
142
                msg_id='missing-param-doc',
143
                node=node,
144
                args=('x, y',)),
145
            Message(
146
                msg_id='missing-type-doc',
147
                node=node,
148
                args=('x, y',))
149
        ):
150
            self.checker.visit_functiondef(node)
151

    
152
    def _visit_methods_of_class(self, node):
153
        """Visit all methods of a class node
154

155
        :param node: class node
156
        :type node: :class:`astroid.scoped_nodes.Class`
157
        """
158
        for body_item in node.body:
159
            if (isinstance(body_item, astroid.FunctionDef)
160
                    and hasattr(body_item, 'name')):
161
                self.checker.visit_functiondef(body_item)
162

    
163
    def test_missing_method_params_in_sphinx_docstring(self):
164
        """Example of a class method with missing parameter documentation in
165
        the Sphinx style docstring
166
        """
167
        node = test_utils.extract_node("""
168
        class Foo(object):
169
            def method_foo(self, x, y):
170
                '''docstring ...
171

172
                missing parameter documentation
173

174
                :param x: bla
175
                '''
176
                pass
177
        """)
178
        method_node = node.body[0]
179
        with self.assertAddsMessages(
180
            Message(
181
                msg_id='missing-param-doc',
182
                node=method_node,
183
                args=('y',)),
184
            Message(
185
                msg_id='missing-type-doc',
186
                node=method_node,
187
                args=('x, y',))
188
        ):
189
            self._visit_methods_of_class(node)
190

    
191
    def test_missing_method_params_in_google_docstring(self):
192
        """Example of a class method with missing parameter documentation in
193
        the Google style docstring
194
        """
195
        node = test_utils.extract_node("""
196
        class Foo(object):
197
            def method_foo(self, x, y):
198
                '''docstring ...
199

200
                missing parameter documentation
201

202
                Args:
203
                    x: bla
204
                '''
205
                pass
206
        """)
207
        method_node = node.body[0]
208
        with self.assertAddsMessages(
209
            Message(
210
                msg_id='missing-param-doc',
211
                node=method_node,
212
                args=('y',)),
213
            Message(
214
                msg_id='missing-type-doc',
215
                node=method_node,
216
                args=('x, y',))
217
        ):
218
            self._visit_methods_of_class(node)
219

    
220
    def test_missing_method_params_in_numpy_docstring(self):
221
        """Example of a class method with missing parameter documentation in
222
        the Numpy style docstring
223
        """
224
        node = test_utils.extract_node("""
225
        class Foo(object):
226
            def method_foo(self, x, y):
227
                '''docstring ...
228

229
                missing parameter documentation
230

231
                Parameters
232
                ----------
233
                x:
234
                    bla
235
                '''
236
                pass
237
        """)
238
        method_node = node.body[0]
239
        with self.assertAddsMessages(
240
            Message(
241
                msg_id='missing-param-doc',
242
                node=method_node,
243
                args=('y',)),
244
            Message(
245
                msg_id='missing-type-doc',
246
                node=method_node,
247
                args=('x, y',))
248
        ):
249
            self._visit_methods_of_class(node)
250

    
251
    def test_existing_func_params_in_sphinx_docstring(self):
252
        """Example of a function with correctly documented parameters and
253
        return values (Sphinx style)
254
        """
255
        node = test_utils.extract_node("""
256
        def function_foo(xarg, yarg, zarg):
257
            '''function foo ...
258

259
            :param xarg: bla xarg
260
            :type xarg: int
261

262
            :param yarg: bla yarg
263
            :type yarg: float
264

265
            :param int zarg: bla zarg
266

267
            :return: sum
268
            :rtype: float
269
            '''
270
            return xarg + yarg
271
        """)
272
        with self.assertNoMessages():
273
            self.checker.visit_functiondef(node)
274

    
275
    def test_existing_func_params_in_google_docstring(self):
276
        """Example of a function with correctly documented parameters and
277
        return values (Google style)
278
        """
279
        node = test_utils.extract_node("""
280
        def function_foo(xarg, yarg, zarg):
281
            '''function foo ...
282

283
            Args:
284
                xarg (int): bla xarg
285
                yarg (float): bla
286
                    bla yarg
287
        
288
                zarg (int): bla zarg
289

290
            Returns:
291
                float: sum
292
            '''
293
            return xarg + yarg
294
        """)
295
        with self.assertNoMessages():
296
            self.checker.visit_functiondef(node)
297

    
298
    def test_existing_func_params_in_numpy_docstring(self):
299
        """Example of a function with correctly documented parameters and
300
        return values (Numpy style)
301
        """
302
        node = test_utils.extract_node("""
303
        def function_foo(xarg, yarg, zarg):
304
            '''function foo ...
305

306
            Parameters
307
            ----------
308
            xarg: int
309
                bla xarg
310
            yarg: float
311
                bla yarg
312

313
            zarg: int
314
                bla zarg
315

316
            Returns
317
            -------
318
            float
319
                sum
320
            '''
321
            return xarg + yarg
322
        """)
323
        with self.assertNoMessages():
324
            self.checker.visit_functiondef(node)
325

    
326
    def test_wrong_name_of_func_params_in_sphinx_docstring(self):
327
        """Example of functions with inconsistent parameter names in the
328
        signature and in the Sphinx style documentation
329
        """
330
        node = test_utils.extract_node("""
331
        def function_foo(xarg, yarg, zarg):
332
            '''function foo ...
333

334
            :param xarg1: bla xarg
335
            :type xarg: int
336

337
            :param yarg: bla yarg
338
            :type yarg1: float
339

340
            :param str zarg1: bla zarg
341
            '''
342
            return xarg + yarg
343
        """)
344
        with self.assertAddsMessages(
345
            Message(
346
                msg_id='missing-param-doc',
347
                node=node,
348
                args=('xarg, xarg1, zarg, zarg1',)),
349
            Message(
350
                msg_id='missing-type-doc',
351
                node=node,
352
                args=('yarg, yarg1, zarg, zarg1',)),
353
        ):
354
            self.checker.visit_functiondef(node)
355

    
356
        node = test_utils.extract_node("""
357
        def function_foo(xarg, yarg):
358
            '''function foo ...
359

360
            :param yarg1: bla yarg
361
            :type yarg1: float
362

363
            For the other parameters, see bla.
364
            '''
365
            return xarg + yarg
366
        """)
367
        with self.assertAddsMessages(
368
            Message(
369
                msg_id='missing-param-doc',
370
                node=node,
371
                args=('yarg1',)),
372
            Message(
373
                msg_id='missing-type-doc',
374
                node=node,
375
                args=('yarg1',))
376
        ):
377
            self.checker.visit_functiondef(node)
378

    
379
    def test_wrong_name_of_func_params_in_google_docstring(self):
380
        """Example of functions with inconsistent parameter names in the
381
        signature and in the Google style documentation
382
        """
383
        node = test_utils.extract_node("""
384
        def function_foo(xarg, yarg, zarg):
385
            '''function foo ...
386

387
            Args:
388
                xarg1 (int): bla xarg
389
                yarg (float): bla yarg
390

391
                zarg1 (str): bla zarg
392
            '''
393
            return xarg + yarg
394
        """)
395
        with self.assertAddsMessages(
396
            Message(
397
                msg_id='missing-param-doc',
398
                node=node,
399
                args=('xarg, xarg1, zarg, zarg1',)),
400
            Message(
401
                msg_id='missing-type-doc',
402
                node=node,
403
                args=('xarg, xarg1, zarg, zarg1',)),
404
        ):
405
            self.checker.visit_functiondef(node)
406

    
407
        node = test_utils.extract_node("""
408
        def function_foo(xarg, yarg):
409
            '''function foo ...
410

411
            Args:
412
                yarg1 (float): bla yarg
413

414
            For the other parameters, see bla.
415
            '''
416
            return xarg + yarg
417
        """)
418
        with self.assertAddsMessages(
419
            Message(
420
                msg_id='missing-param-doc',
421
                node=node,
422
                args=('yarg1',)),
423
            Message(
424
                msg_id='missing-type-doc',
425
                node=node,
426
                args=('yarg1',))
427
        ):
428
            self.checker.visit_functiondef(node)
429

    
430
    def test_wrong_name_of_func_params_in_numpy_docstring(self):
431
        """Example of functions with inconsistent parameter names in the
432
        signature and in the Numpy style documentation
433
        """
434
        node = test_utils.extract_node("""
435
        def function_foo(xarg, yarg, zarg):
436
            '''function foo ...
437

438
            Parameters
439
            ----------
440
            xarg1: int
441
                bla xarg
442
            yarg: float
443
                bla yarg
444

445
            zarg1: str
446
                bla zarg
447
            '''
448
            return xarg + yarg
449
        """)
450
        with self.assertAddsMessages(
451
            Message(
452
                msg_id='missing-param-doc',
453
                node=node,
454
                args=('xarg, xarg1, zarg, zarg1',)),
455
            Message(
456
                msg_id='missing-type-doc',
457
                node=node,
458
                args=('xarg, xarg1, zarg, zarg1',)),
459
        ):
460
            self.checker.visit_functiondef(node)
461

    
462
        node = test_utils.extract_node("""
463
        def function_foo(xarg, yarg):
464
            '''function foo ...
465

466
            Parameters
467
            ----------
468
            yarg1: float
469
                bla yarg
470

471
            For the other parameters, see bla.
472
            '''
473
            return xarg + yarg
474
        """)
475
        with self.assertAddsMessages(
476
            Message(
477
                msg_id='missing-param-doc',
478
                node=node,
479
                args=('yarg1',)),
480
            Message(
481
                msg_id='missing-type-doc',
482
                node=node,
483
                args=('yarg1',))
484
        ):
485
            self.checker.visit_functiondef(node)
486

    
487
    def test_see_sentence_for_func_params_in_sphinx_docstring(self):
488
        """Example for the usage of "For the other parameters, see" to avoid
489
        too many repetitions, e.g. in functions or methods adhering to a
490
        given interface (Sphinx style)
491
        """
492
        node = test_utils.extract_node("""
493
        def function_foo(xarg, yarg):
494
            '''function foo ...
495

496
            :param yarg: bla yarg
497
            :type yarg: float
498

499
            For the other parameters, see :func:`bla`
500
            '''
501
            return xarg + yarg
502
        """)
503
        with self.assertNoMessages():
504
            self.checker.visit_functiondef(node)
505

    
506
    def test_see_sentence_for_func_params_in_google_docstring(self):
507
        """Example for the usage of "For the other parameters, see" to avoid
508
        too many repetitions, e.g. in functions or methods adhering to a
509
        given interface (Google style)
510
        """
511
        node = test_utils.extract_node("""
512
        def function_foo(xarg, yarg):
513
            '''function foo ...
514

515
            Args:
516
                yarg (float): bla yarg
517

518
            For the other parameters, see :func:`bla`
519
            '''
520
            return xarg + yarg
521
        """)
522
        with self.assertNoMessages():
523
            self.checker.visit_functiondef(node)
524

    
525
    def test_see_sentence_for_func_params_in_numpy_docstring(self):
526
        """Example for the usage of "For the other parameters, see" to avoid
527
        too many repetitions, e.g. in functions or methods adhering to a
528
        given interface (Numpy style)
529
        """
530
        node = test_utils.extract_node("""
531
        def function_foo(xarg, yarg):
532
            '''function foo ...
533

534
            Parameters
535
            ----------
536
            yarg: float
537
                bla yarg
538

539
            For the other parameters, see :func:`bla`
540
            '''
541
            return xarg + yarg
542
        """)
543
        with self.assertNoMessages():
544
            self.checker.visit_functiondef(node)
545

    
546
    def test_constr_params_in_class_sphinx(self):
547
        """Example of a class with missing constructor parameter documentation
548
        (Sphinx style)
549

550
        Everything is completely analogous to functions.
551
        """
552
        node = test_utils.extract_node("""
553
        class ClassFoo(object):
554
            '''docstring foo
555

556
            :param y: bla
557
            
558
            missing constructor parameter documentation
559
            '''
560

561
            def __init__(self, x, y):
562
                pass
563

564
        """)
565
        with self.assertAddsMessages(
566
            Message(
567
                msg_id='missing-param-doc',
568
                node=node,
569
                args=('x',)),
570
            Message(
571
                msg_id='missing-type-doc',
572
                node=node,
573
                args=('x, y',))
574
        ):
575
            self._visit_methods_of_class(node)
576

    
577
    def test_constr_params_in_class_google(self):
578
        """Example of a class with missing constructor parameter documentation
579
        (Google style)
580

581
        Everything is completely analogous to functions.
582
        """
583
        node = test_utils.extract_node("""
584
        class ClassFoo(object):
585
            '''docstring foo
586

587
            Args:
588
                y: bla
589
            
590
            missing constructor parameter documentation
591
            '''
592

593
            def __init__(self, x, y):
594
                pass
595

596
        """)
597
        with self.assertAddsMessages(
598
            Message(
599
                msg_id='missing-param-doc',
600
                node=node,
601
                args=('x',)),
602
            Message(
603
                msg_id='missing-type-doc',
604
                node=node,
605
                args=('x, y',))
606
        ):
607
            self._visit_methods_of_class(node)
608

    
609
    def test_constr_params_in_class_numpy(self):
610
        """Example of a class with missing constructor parameter documentation
611
        (Numpy style)
612

613
        Everything is completely analogous to functions.
614
        """
615
        node = test_utils.extract_node("""
616
        class ClassFoo(object):
617
            '''docstring foo
618

619
            Parameters
620
            ----------
621
            y:
622
                bla
623
            
624
            missing constructor parameter documentation
625
            '''
626

627
            def __init__(self, x, y):
628
                pass
629

630
        """)
631
        with self.assertAddsMessages(
632
            Message(
633
                msg_id='missing-param-doc',
634
                node=node,
635
                args=('x',)),
636
            Message(
637
                msg_id='missing-type-doc',
638
                node=node,
639
                args=('x, y',))
640
        ):
641
            self._visit_methods_of_class(node)
642

    
643
    @unittest.skipIf(sys.version_info[0] != 3, "Enabled on Python 3")
644
    def test_kwonlyargs_are_taken_in_account(self):
645
        node = test_utils.extract_node('''
646
        def my_func(arg, *, kwonly, missing_kwonly):
647
            """The docstring
648

649
            :param int arg: The argument.
650
            :param bool kwonly: A keyword-arg.
651
            """
652
        ''')
653
        with self.assertAddsMessages(
654
            Message(
655
                msg_id='missing-param-doc',
656
                node=node,
657
                args=('missing_kwonly', )),
658
            Message(
659
                msg_id='missing-type-doc',
660
                node=node,
661
                args=('missing_kwonly', ))):
662
            self.checker.visit_functiondef(node)
663

    
664

    
665
if __name__ == '__main__':
666
    unittest.main()