4
4
import string
5
5
import sys
6
6
import tokenize as tk
7
- from itertools import takewhile
7
+ from itertools import takewhile , tee , izip_longest
8
8
from re import compile as re
9
9
from collections import namedtuple
10
10
@@ -34,6 +34,16 @@ def decorator(f):
34
34
return decorator
35
35
36
36
37
+ def pairwise (iterable , default_value ):
38
+ """Return pairs of items from `iterable`.
39
+
40
+ pairwise([1, 2, 3], default_value=None) -> (1, 2) (2, 3), (3, None)
41
+ """
42
+ a , b = tee (iterable )
43
+ _ = next (b , default_value )
44
+ return izip_longest (a , b , fillvalue = default_value )
45
+
46
+
37
47
class ConventionChecker (object ):
38
48
"""Checker for PEP 257 and numpy conventions.
39
49
@@ -462,15 +472,15 @@ def _is_a_docstring_section(context):
462
472
463
473
@classmethod
464
474
def _check_section_underline (cls , section_name , context , indentation ):
465
- """D4{07,08,09,10 }, D215: Section underline checks.
475
+ """D4{07,08,09,12 }, D215: Section underline checks.
466
476
467
477
Check for correct formatting for docstring sections. Checks that:
468
478
* The line that follows the section name contains
469
479
dashes (D40{7,8}).
470
480
* The amount of dashes is equal to the length of the section
471
481
name (D409).
472
- * The line that follows the section header (with or without dashes)
473
- is empty (D410 ).
482
+ * The section's content does not begin in the line that follows
483
+ the section header (D412 ).
474
484
* The indentation of the dashed line is equal to the docstring's
475
485
indentation (D215).
476
486
"""
@@ -486,8 +496,8 @@ def _check_section_underline(cls, section_name, context, indentation):
486
496
487
497
if not dash_line_found :
488
498
yield violations .D407 (section_name )
489
- if next_non_empty_line_offset == 0 :
490
- yield violations .D410 (section_name )
499
+ if next_non_empty_line_offset > 0 :
500
+ yield violations .D412 (section_name )
491
501
else :
492
502
if next_non_empty_line_offset > 0 :
493
503
yield violations .D408 (section_name )
@@ -498,22 +508,24 @@ def _check_section_underline(cls, section_name, context, indentation):
498
508
section_name ,
499
509
len (dash_line .strip ()))
500
510
501
- line_after_dashes = \
502
- context .following_lines [next_non_empty_line_offset + 1 ]
503
- if not is_blank (line_after_dashes ):
504
- yield violations .D410 (section_name )
505
-
506
511
if leading_space (dash_line ) > indentation :
507
512
yield violations .D215 (section_name )
508
513
514
+ if next_non_empty_line_offset + 1 < len (context .following_lines ):
515
+ line_after_dashes = \
516
+ context .following_lines [next_non_empty_line_offset + 1 ]
517
+ if is_blank (line_after_dashes ):
518
+ yield violations .D412 (section_name )
519
+
509
520
@classmethod
510
521
def _check_section (cls , docstring , definition , context ):
511
- """D4{05,06,11}, D214: Section name checks.
522
+ """D4{05,06,10, 11}, D214: Section name checks.
512
523
513
524
Check for valid section names. Checks that:
514
525
* The section name is properly capitalized (D405).
515
526
* The section is not over-indented (D214).
516
527
* The section name has no superfluous suffix to it (D406).
528
+ * There's a blank line after the section (D410).
517
529
* There's a blank line before the section (D411).
518
530
519
531
Also yields all the errors from `_check_section_underline`.
@@ -532,6 +544,10 @@ def _check_section(cls, docstring, definition, context):
532
544
if suffix :
533
545
yield violations .D406 (capitalized_section , context .line .strip ())
534
546
547
+ if (not context .following_lines or
548
+ not is_blank (context .following_lines [- 1 ])):
549
+ yield violations .D410 (capitalized_section )
550
+
535
551
if not is_blank (context .previous_line ):
536
552
yield violations .D411 (capitalized_section )
537
553
@@ -549,13 +565,12 @@ def check_docstring_sections(self, definition, docstring):
549
565
550
566
Short Summary
551
567
-------------
552
-
553
568
This is my summary.
554
569
555
570
Returns
556
571
-------
557
-
558
572
None.
573
+
559
574
'''
560
575
561
576
Section names appear in `SECTION_NAMES`.
@@ -580,18 +595,32 @@ def _suspected_as_section(_line):
580
595
SectionContext = namedtuple ('SectionContext' , ('section_name' ,
581
596
'previous_line' ,
582
597
'line' ,
583
- 'following_lines' ))
598
+ 'following_lines' ,
599
+ 'original_index' ))
584
600
601
+ # First - create a list of possible contexts. Note that the
602
+ # `following_linex` member is until the end of the docstring.
585
603
contexts = (SectionContext (self ._get_leading_words (lines [i ].strip ()),
586
604
lines [i - 1 ],
587
605
lines [i ],
588
- lines [i + 1 :])
606
+ lines [i + 1 :],
607
+ i )
589
608
for i in suspected_section_indices )
590
609
591
- for ctx in contexts :
592
- if self ._is_a_docstring_section (ctx ):
593
- for err in self ._check_section (docstring , definition , ctx ):
594
- yield err
610
+ # Now that we have manageable objects - rule out false positives.
611
+ contexts = (c for c in contexts if self ._is_a_docstring_section (c ))
612
+
613
+ # Now we shall trim the `following lines` field to only reach the
614
+ # next section name.
615
+ for a , b in pairwise (contexts , None ):
616
+ end = - 1 if b is None else b .original_index
617
+ new_ctx = SectionContext (a .section_name ,
618
+ a .previous_line ,
619
+ a .line ,
620
+ lines [a .original_index + 1 :end ],
621
+ a .original_index )
622
+ for err in self ._check_section (docstring , definition , new_ctx ):
623
+ yield err
595
624
596
625
597
626
parse = Parser ()
0 commit comments