@@ -379,18 +379,30 @@ class Error(object):
379
379
380
380
"""Error in docstring style."""
381
381
382
+ # should be overridden by inheriting classes
383
+ code = None
384
+ _message = None
385
+
382
386
# Options that define how errors are printed:
383
387
explain = False
384
388
source = False
385
389
386
- def __init__ (self , message = None , final = False ):
387
- self .message , self .is_final = message , final
388
- self .definition , self .explanation = [None , None ]
390
+ def __init__ (self , * parameters ):
391
+ self .parameters = parameters
392
+ self .definition = None
393
+ self .explanation = None
394
+
395
+ def set_context (self , definition , explanation ):
396
+ self .definition = definition
397
+ self .explanation = explanation
389
398
390
- code = property (lambda self : self .message .partition (':' )[0 ])
391
399
filename = property (lambda self : self .definition .module .name )
392
400
line = property (lambda self : self .definition .start )
393
401
402
+ @property
403
+ def message (self ):
404
+ return '%s: %s' % (self .code , self ._message ) % self .parameters
405
+
394
406
@property
395
407
def lines (self ):
396
408
source = ''
@@ -430,6 +442,52 @@ def __lt__(self, other):
430
442
return (self .filename , self .line ) < (other .filename , other .line )
431
443
432
444
445
+ errors = []
446
+
447
+
448
+ def register_error (error_cls ):
449
+ errors .append (error_cls )
450
+
451
+
452
+ def error (code , message ):
453
+ _code = code
454
+
455
+ class _Error (Error ):
456
+ code = _code
457
+ _message = message
458
+
459
+ register_error (_Error )
460
+ return _Error
461
+
462
+
463
+ D100 = error ('D100' , 'Missing docstring in public module' )
464
+ D101 = error ('D101' , 'Missing docstring in public class' )
465
+ D102 = error ('D102' , 'Missing docstring in public method' )
466
+ D103 = error ('D103' , 'Missing docstring in public function' )
467
+ D200 = error ('D200' , 'One-line docstring should fit on one line with quotes, '
468
+ 'found %s' )
469
+ D201 = error ('D201' , 'No blank lines allowed before function docstring, '
470
+ 'found %s' )
471
+ D202 = error ('D202' , 'No blank lines allowed after function docstring, '
472
+ 'found %s' )
473
+ D203 = error ('D203' , '1 blank line required before class docstring, found %s' )
474
+ D204 = error ('D204' , '1 blank line required after class docstring, found %s' )
475
+ D205 = error ('D205' , '1 blank line required between summary line and '
476
+ 'description, found %s' )
477
+ D206 = error ('D206' , 'Docstring should be indented with spaces, not tabs' )
478
+ D207 = error ('D207' , 'Docstring is under-indented' )
479
+ D208 = error ('D208' , 'Docstring is over-indented' )
480
+ D209 = error ('D209' , 'Multi-line docstring closing quotes should be on a '
481
+ 'separate line' )
482
+ D210 = error ('D210' , 'No whitespaces allowed surrounding docstring text' )
483
+ D300 = error ('D300' , 'Use """triple double quotes""", found %s-quotes' )
484
+ D301 = error ('D301' , 'Use r""" if any backslashes in a docstring' )
485
+ D302 = error ('D302' , 'Use u""" for Unicode docstrings' )
486
+ D400 = error ('D400' , 'First line should end with a period, not %r' )
487
+ D401 = error ('D401' , 'First line should be in imperative mood: %r, not %r' )
488
+ D402 = error ('D402' , 'First line should not be the function\' s "signature"' )
489
+
490
+
433
491
def get_option_parser ():
434
492
parser = OptionParser (version = __version__ ,
435
493
usage = 'Usage: pep257 [options] [<file|dir>...]' )
@@ -635,10 +693,8 @@ def check_source(self, source, filename):
635
693
if error is not None :
636
694
partition = check .__doc__ .partition ('.\n ' )
637
695
message , _ , explanation = partition
638
- if error .message is None :
639
- error .message = message
640
- error .explanation = explanation
641
- error .definition = definition
696
+ error .set_context (explanation = explanation ,
697
+ definition = definition )
642
698
yield error
643
699
if check ._terminal :
644
700
terminate = True
@@ -668,9 +724,9 @@ def check_docstring_missing(self, definition, docstring):
668
724
"""
669
725
if (not docstring and definition .is_public or
670
726
docstring and is_blank (eval (docstring ))):
671
- codes = {Module : ' D100' , Class : ' D101' , NestedClass : ' D101' ,
672
- Method : ' D102' , Function : ' D103' , NestedFunction : ' D103' }
673
- return Error ( '%s: Docstring missing' % codes [type (definition )])
727
+ codes = {Module : D100 , Class : D101 , NestedClass : D101 ,
728
+ Method : D102 , Function : D103 , NestedFunction : D103 }
729
+ return codes [type (definition )]( )
674
730
675
731
@check_for (Definition )
676
732
def check_one_liners (self , definition , docstring ):
@@ -685,8 +741,7 @@ def check_one_liners(self, definition, docstring):
685
741
if len (lines ) > 1 :
686
742
non_empty_lines = sum (1 for l in lines if not is_blank (l ))
687
743
if non_empty_lines == 1 :
688
- return Error ('D200: One-line docstring should not occupy '
689
- '%s lines' % len (lines ))
744
+ return D200 (len (lines ))
690
745
691
746
@check_for (Function )
692
747
def check_no_blank_before (self , function , docstring ): # def
@@ -704,13 +759,9 @@ def check_no_blank_before(self, function, docstring): # def
704
759
blanks_before_count = sum (takewhile (bool , reversed (blanks_before )))
705
760
blanks_after_count = sum (takewhile (bool , blanks_after ))
706
761
if blanks_before_count != 0 :
707
- yield Error ('D201: No blank lines allowed *before* %s '
708
- 'docstring, found %s'
709
- % (function .kind , blanks_before_count ))
762
+ yield D201 (blanks_before_count )
710
763
if not all (blanks_after ) and blanks_after_count != 0 :
711
- yield Error ('D202: No blank lines allowed *after* %s '
712
- 'docstring, found %s'
713
- % (function .kind , blanks_after_count ))
764
+ yield D202 (blanks_after_count )
714
765
715
766
@check_for (Class )
716
767
def check_blank_before_after_class (slef , class_ , docstring ):
@@ -724,7 +775,7 @@ def check_blank_before_after_class(slef, class_, docstring):
724
775
docstring.
725
776
726
777
"""
727
- # NOTE: this gives flase -positive in this case
778
+ # NOTE: this gives false -positive in this case
728
779
# class Foo:
729
780
#
730
781
# """Docstring."""
@@ -739,11 +790,9 @@ def check_blank_before_after_class(slef, class_, docstring):
739
790
blanks_before_count = sum (takewhile (bool , reversed (blanks_before )))
740
791
blanks_after_count = sum (takewhile (bool , blanks_after ))
741
792
if blanks_before_count != 1 :
742
- yield Error ('D203: Expected 1 blank line *before* class '
743
- 'docstring, found %s' % blanks_before_count )
793
+ yield D203 (blanks_before_count )
744
794
if not all (blanks_after ) and blanks_after_count != 1 :
745
- yield Error ('D204: Expected 1 blank line *after* class '
746
- 'docstring, found %s' % blanks_after_count )
795
+ yield D204 (blanks_after_count )
747
796
748
797
@check_for (Definition )
749
798
def check_blank_after_summary (self , definition , docstring ):
@@ -762,9 +811,7 @@ def check_blank_after_summary(self, definition, docstring):
762
811
post_summary_blanks = list (map (is_blank , lines [1 :]))
763
812
blanks_count = sum (takewhile (bool , post_summary_blanks ))
764
813
if blanks_count != 1 :
765
- yield Error ('D205: Expected 1 blank line between summary '
766
- 'line and description, found %s' %
767
- blanks_count )
814
+ return D205 (blanks_count )
768
815
769
816
@check_for (Definition )
770
817
def check_indent (self , definition , docstring ):
@@ -782,13 +829,12 @@ def check_indent(self, definition, docstring):
782
829
lines = lines [1 :] # First line does not need indent.
783
830
indents = [leading_space (l ) for l in lines if not is_blank (l )]
784
831
if set (' \t ' ) == set ('' .join (indents ) + indent ):
785
- return Error ('D206: Docstring indented with both tabs and '
786
- 'spaces' )
832
+ yield D206 ()
787
833
if (len (indents ) > 1 and min (indents [:- 1 ]) > indent
788
834
or indents [- 1 ] > indent ):
789
- return Error ( ' D208: Docstring is over-indented' )
835
+ yield D208 ( )
790
836
if min (indents ) < indent :
791
- return Error ( ' D207: Docstring is under-indented' )
837
+ yield D207 ( )
792
838
793
839
@check_for (Definition )
794
840
def check_newline_after_last_paragraph (self , definition , docstring ):
@@ -802,8 +848,7 @@ def check_newline_after_last_paragraph(self, definition, docstring):
802
848
lines = [l for l in eval (docstring ).split ('\n ' ) if not is_blank (l )]
803
849
if len (lines ) > 1 :
804
850
if docstring .split ("\n " )[- 1 ].strip () not in ['"""' , "'''" ]:
805
- return Error ('D209: Put multi-line docstring closing '
806
- 'quotes on separate line' )
851
+ return D209 ()
807
852
808
853
@check_for (Definition )
809
854
def check_surrounding_whitespaces (self , definition , docstring ):
@@ -812,8 +857,7 @@ def check_surrounding_whitespaces(self, definition, docstring):
812
857
lines = eval (docstring ).split ('\n ' )
813
858
if lines [0 ].startswith (' ' ) or \
814
859
len (lines ) == 1 and lines [0 ].endswith (' ' ):
815
- return Error ("D210: No whitespaces allowed surrounding "
816
- "docstring text." )
860
+ return D210 ()
817
861
818
862
@check_for (Definition )
819
863
def check_triple_double_quotes (self , definition , docstring ):
@@ -835,7 +879,7 @@ def check_triple_double_quotes(self, definition, docstring):
835
879
return
836
880
if docstring and not docstring .startswith (('"""' , 'r"""' , 'u"""' )):
837
881
quotes = "'''" if "'''" in docstring [:4 ] else "'"
838
- return Error ( ' D300: Expected """-quotes, got %s-quotes' % quotes )
882
+ return D300 ( quotes )
839
883
840
884
@check_for (Definition )
841
885
def check_backslashes (self , definition , docstring ):
@@ -848,7 +892,7 @@ def check_backslashes(self, definition, docstring):
848
892
# Just check that docstring is raw, check_triple_double_quotes
849
893
# ensures the correct quotes.
850
894
if docstring and '\\ ' in docstring and not docstring .startswith ('r' ):
851
- return Error ()
895
+ return D301 ()
852
896
853
897
@check_for (Definition )
854
898
def check_unicode_docstring (self , definition , docstring ):
@@ -861,7 +905,7 @@ def check_unicode_docstring(self, definition, docstring):
861
905
# ensures the correct quotes.
862
906
if docstring and sys .version_info [0 ] <= 2 :
863
907
if not is_ascii (docstring ) and not docstring .startswith ('u' ):
864
- return Error ()
908
+ return D302 ()
865
909
866
910
@check_for (Definition )
867
911
def check_ends_with_period (self , definition , docstring ):
@@ -873,8 +917,7 @@ def check_ends_with_period(self, definition, docstring):
873
917
if docstring :
874
918
summary_line = eval (docstring ).strip ().split ('\n ' )[0 ]
875
919
if not summary_line .endswith ('.' ):
876
- return Error ("D400: First line should end with '.', not %r"
877
- % summary_line [- 1 ])
920
+ return D400 (summary_line [- 1 ])
878
921
879
922
@check_for (Function )
880
923
def check_imperative_mood (self , function , docstring ): # def context
@@ -890,8 +933,7 @@ def check_imperative_mood(self, function, docstring): # def context
890
933
if stripped :
891
934
first_word = stripped .split ()[0 ]
892
935
if first_word .endswith ('s' ) and not first_word .endswith ('ss' ):
893
- return Error ('D401: First line should be imperative: '
894
- '%r, not %r' % (first_word [:- 1 ], first_word ))
936
+ return D401 (first_word [:- 1 ], first_word )
895
937
896
938
@check_for (Function )
897
939
def check_no_signature (self , function , docstring ): # def context
@@ -904,8 +946,7 @@ def check_no_signature(self, function, docstring): # def context
904
946
if docstring :
905
947
first_line = eval (docstring ).strip ().split ('\n ' )[0 ]
906
948
if function .name + '(' in first_line .replace (' ' , '' ):
907
- return Error ("D402: First line should not be %s's signature"
908
- % function .kind )
949
+ return D402 ()
909
950
910
951
# Somewhat hard to determine if return value is mentioned.
911
952
# @check(Function)
0 commit comments