@@ -95,6 +95,10 @@ def leading_space(string):
9595class Value (object ):
9696
9797 def __init__ (self , * args ):
98+ if len (self ._fields ) != len (args ):
99+ raise ValueError ('got %s arguments for %s fields for %s: %s'
100+ % (len (args ), len (self ._fields ),
101+ self .__class__ .__name__ , self ._fields ))
98102 vars (self ).update (zip (self ._fields , args ))
99103
100104 def __hash__ (self ):
@@ -112,7 +116,7 @@ def __repr__(self):
112116class Definition (Value ):
113117
114118 _fields = ('name' , '_source' , 'start' , 'end' , 'decorators' , 'docstring' ,
115- 'children' , 'parent' )
119+ 'children' , 'parent' , 'skips' )
116120
117121 _human = property (lambda self : humanize (type (self ).__name__ ))
118122 kind = property (lambda self : self ._human .split ()[- 1 ])
@@ -140,13 +144,16 @@ def is_empty_or_comment(line):
140144 return '' .join (reversed (list (filtered_src )))
141145
142146 def __str__ (self ):
143- return 'in %s %s `%s`' % (self ._publicity , self ._human , self .name )
147+ out = 'in %s %s `%s`' % (self ._publicity , self ._human , self .name )
148+ if self .skips :
149+ out += ' (skipping %s)' % self .skips
150+ return out
144151
145152
146153class Module (Definition ):
147154
148155 _fields = ('name' , '_source' , 'start' , 'end' , 'decorators' , 'docstring' ,
149- 'children' , 'parent' , '_all' , 'future_imports' )
156+ 'children' , 'parent' , '_all' , 'future_imports' , 'skips' )
150157 is_public = True
151158 _nest = staticmethod (lambda s : {'def' : Function , 'class' : Class }[s ])
152159 module = property (lambda self : self )
@@ -433,7 +440,7 @@ def parse_module(self):
433440 if self .filename .endswith ('__init__.py' ):
434441 cls = Package
435442 module = cls (self .filename , self .source , start , end ,
436- [], docstring , children , None , self .all )
443+ [], docstring , children , None , self .all , None , '' )
437444 for child in module .children :
438445 child .parent = module
439446 module .future_imports = self .future_imports
@@ -462,7 +469,15 @@ def parse_definition(self, class_):
462469 self .leapfrog (tk .OP , value = ":" )
463470 else :
464471 self .consume (tk .OP )
472+ skips = ''
465473 if self .current .kind in (tk .NEWLINE , tk .COMMENT ):
474+ if self .current .kind == tk .COMMENT :
475+ if self .current .value .startswith ('# noqa' ) or \
476+ 'pydocstyle: noqa' in self .current .value :
477+ skips = 'all'
478+ elif 'pydocstyle: ' in self .current .value :
479+ skips = '' .join (self .current .value .split (
480+ 'pydocstyle: ' )[1 :])
466481 self .leapfrog (tk .INDENT )
467482 assert self .current .kind != tk .INDENT
468483 docstring = self .parse_docstring ()
@@ -479,7 +494,7 @@ def parse_definition(self, class_):
479494 end = self .line
480495 self .leapfrog (tk .NEWLINE )
481496 definition = class_ (name , self .source , start , end ,
482- decorators , docstring , children , None )
497+ decorators , docstring , children , None , skips )
483498 for child in definition .children :
484499 child .parent = definition
485500 log .debug ("finished parsing %s '%s'. Next token is %r (%s)" ,
@@ -1400,7 +1415,10 @@ def check_source(self, source, filename):
14001415 for check in self .checks :
14011416 terminate = False
14021417 if isinstance (definition , check ._check_for ):
1403- error = check (None , definition , definition .docstring )
1418+ if definition .skips != 'all' :
1419+ error = check (None , definition , definition .docstring )
1420+ else :
1421+ error = None
14041422 errors = error if hasattr (error , '__iter__' ) else [error ]
14051423 for error in errors :
14061424 if error is not None :
@@ -1441,7 +1459,10 @@ def check_docstring_missing(self, definition, docstring):
14411459 Method : (lambda : D105 () if is_magic (definition .name )
14421460 else D102 ()),
14431461 Function : D103 , NestedFunction : D103 , Package : D104 }
1444- return codes [type (definition )]()
1462+ code = codes [type (definition )]
1463+ if code .__name__ in definition .skips :
1464+ return
1465+ return code ()
14451466
14461467 @check_for (Definition )
14471468 def check_one_liners (self , definition , docstring ):
@@ -1451,6 +1472,8 @@ def check_one_liners(self, definition, docstring):
14511472 This looks better for one-liners.
14521473
14531474 """
1475+ if 'D200' in definition .skips :
1476+ return
14541477 if docstring :
14551478 lines = ast .literal_eval (docstring ).split ('\n ' )
14561479 if len (lines ) > 1 :
@@ -1472,9 +1495,11 @@ def check_no_blank_before(self, function, docstring): # def
14721495 blanks_before_count = sum (takewhile (bool , reversed (blanks_before )))
14731496 blanks_after_count = sum (takewhile (bool , blanks_after ))
14741497 if blanks_before_count != 0 :
1475- yield D201 (blanks_before_count )
1498+ if 'D201' not in function .skips :
1499+ yield D201 (blanks_before_count )
14761500 if not all (blanks_after ) and blanks_after_count != 0 :
1477- yield D202 (blanks_after_count )
1501+ if 'D202' not in function .skips :
1502+ yield D202 (blanks_after_count )
14781503
14791504 @check_for (Class )
14801505 def check_blank_before_after_class (self , class_ , docstring ):
@@ -1502,11 +1527,12 @@ def check_blank_before_after_class(self, class_, docstring):
15021527 blanks_after = list (map (is_blank , after .split ('\n ' )[1 :]))
15031528 blanks_before_count = sum (takewhile (bool , reversed (blanks_before )))
15041529 blanks_after_count = sum (takewhile (bool , blanks_after ))
1505- if blanks_before_count != 0 :
1530+ if 'D211' not in class_ . skips and blanks_before_count != 0 :
15061531 yield D211 (blanks_before_count )
1507- if blanks_before_count != 1 :
1532+ if 'D203' not in class_ . skips and blanks_before_count != 1 :
15081533 yield D203 (blanks_before_count )
1509- if not all (blanks_after ) and blanks_after_count != 1 :
1534+ if 'D204' not in class_ .skips and (not all (blanks_after ) and
1535+ blanks_after_count != 1 ):
15101536 yield D204 (blanks_after_count )
15111537
15121538 @check_for (Definition )
@@ -1521,6 +1547,8 @@ def check_blank_after_summary(self, definition, docstring):
15211547
15221548 """
15231549 if docstring :
1550+ if 'D205' in definition .skips :
1551+ return
15241552 lines = ast .literal_eval (docstring ).strip ().split ('\n ' )
15251553 if len (lines ) > 1 :
15261554 post_summary_blanks = list (map (is_blank , lines [1 :]))
@@ -1543,13 +1571,16 @@ def check_indent(self, definition, docstring):
15431571 if len (lines ) > 1 :
15441572 lines = lines [1 :] # First line does not need indent.
15451573 indents = [leading_space (l ) for l in lines if not is_blank (l )]
1546- if set (' \t ' ) == set ('' .join (indents ) + indent ):
1547- yield D206 ()
1548- if (len (indents ) > 1 and min (indents [:- 1 ]) > indent or
1549- indents [- 1 ] > indent ):
1550- yield D208 ()
1551- if min (indents ) < indent :
1552- yield D207 ()
1574+ if 'D206' not in definition .skips :
1575+ if set (' \t ' ) == set ('' .join (indents ) + indent ):
1576+ yield D206 ()
1577+ if 'D208' not in definition .skips :
1578+ if (len (indents ) > 1 and min (indents [:- 1 ]) > indent or
1579+ indents [- 1 ] > indent ):
1580+ yield D208 ()
1581+ if 'D207' not in definition .skips :
1582+ if min (indents ) < indent :
1583+ yield D207 ()
15531584
15541585 @check_for (Definition )
15551586 def check_newline_after_last_paragraph (self , definition , docstring ):
@@ -1559,7 +1590,7 @@ def check_newline_after_last_paragraph(self, definition, docstring):
15591590 quotes on a line by themselves.
15601591
15611592 """
1562- if docstring :
1593+ if docstring and 'D209' not in definition . skips :
15631594 lines = [l for l in ast .literal_eval (docstring ).split ('\n ' )
15641595 if not is_blank (l )]
15651596 if len (lines ) > 1 :
@@ -1569,7 +1600,7 @@ def check_newline_after_last_paragraph(self, definition, docstring):
15691600 @check_for (Definition )
15701601 def check_surrounding_whitespaces (self , definition , docstring ):
15711602 """D210: No whitespaces allowed surrounding docstring text."""
1572- if docstring :
1603+ if docstring and 'D210' not in definition . skips :
15731604 lines = ast .literal_eval (docstring ).split ('\n ' )
15741605 if lines [0 ].startswith (' ' ) or \
15751606 len (lines ) == 1 and lines [0 ].endswith (' ' ):
@@ -1595,9 +1626,11 @@ def check_multi_line_summary_start(self, definition, docstring):
15951626 if len (lines ) > 1 :
15961627 first = docstring .split ("\n " )[0 ].strip ().lower ()
15971628 if first in start_triple :
1598- return D212 ()
1629+ if 'D212' not in definition .skips :
1630+ return D212 ()
15991631 else :
1600- return D213 ()
1632+ if 'D213' not in definition .skips :
1633+ return D213 ()
16011634
16021635 @check_for (Definition )
16031636 def check_triple_double_quotes (self , definition , docstring ):
@@ -1612,7 +1645,7 @@ def check_triple_double_quotes(self, definition, docstring):
16121645 """ quotes in its body.
16131646
16141647 '''
1615- if docstring :
1648+ if docstring and 'D300' not in definition . skips :
16161649 opening = docstring [:5 ].lower ()
16171650 if '"""' in ast .literal_eval (docstring ) and opening .startswith (
16181651 ("'''" , "r'''" , "u'''" , "ur'''" )):
@@ -1634,8 +1667,8 @@ def check_backslashes(self, definition, docstring):
16341667 '''
16351668 # Just check that docstring is raw, check_triple_double_quotes
16361669 # ensures the correct quotes.
1637- if docstring and '\\ ' in docstring and not docstring . startswith (
1638- ('r' , 'ur' )):
1670+ if docstring and 'D301' not in definition . skips and \
1671+ ' \\ ' in docstring and not docstring . startswith ( ('r' , 'ur' )):
16391672 return D301 ()
16401673
16411674 @check_for (Definition )
@@ -1650,7 +1683,8 @@ def check_unicode_docstring(self, definition, docstring):
16501683
16511684 # Just check that docstring is unicode, check_triple_double_quotes
16521685 # ensures the correct quotes.
1653- if docstring and sys .version_info [0 ] <= 2 :
1686+ if docstring and sys .version_info [0 ] <= 2 and \
1687+ 'D302' not in definition .skips :
16541688 if not is_ascii (docstring ) and not docstring .startswith (
16551689 ('u' , 'ur' )):
16561690 return D302 ()
@@ -1662,7 +1696,7 @@ def check_ends_with_period(self, definition, docstring):
16621696 The [first line of a] docstring is a phrase ending in a period.
16631697
16641698 """
1665- if docstring :
1699+ if docstring and 'D400' not in definition . skips :
16661700 summary_line = ast .literal_eval (docstring ).strip ().split ('\n ' )[0 ]
16671701 if not summary_line .endswith ('.' ):
16681702 return D400 (summary_line [- 1 ])
@@ -1676,7 +1710,7 @@ def check_imperative_mood(self, function, docstring): # def context
16761710 "Returns the pathname ...".
16771711
16781712 """
1679- if docstring :
1713+ if docstring and 'D401' not in function . skips :
16801714 stripped = ast .literal_eval (docstring ).strip ()
16811715 if stripped :
16821716 first_word = stripped .split ()[0 ]
@@ -1691,7 +1725,7 @@ def check_no_signature(self, function, docstring): # def context
16911725 function/method parameters (which can be obtained by introspection).
16921726
16931727 """
1694- if docstring :
1728+ if docstring and 'D402' not in function . skips :
16951729 first_line = ast .literal_eval (docstring ).strip ().split ('\n ' )[0 ]
16961730 if function .name + '(' in first_line .replace (' ' , '' ):
16971731 return D402 ()
@@ -1703,7 +1737,7 @@ def check_capitalized(self, function, docstring):
17031737 The [first line of a] docstring is a phrase ending in a period.
17041738
17051739 """
1706- if docstring :
1740+ if docstring and 'D403' not in function . skips :
17071741 first_word = ast .literal_eval (docstring ).split ()[0 ]
17081742 if first_word == first_word .upper ():
17091743 return
@@ -1721,7 +1755,7 @@ def check_starts_with_this(self, function, docstring):
17211755 with "This class is [..]" or "This module contains [..]".
17221756
17231757 """
1724- if docstring :
1758+ if docstring and 'D404' not in function . skips :
17251759 first_word = ast .literal_eval (docstring ).split ()[0 ]
17261760 if first_word .lower () == 'this' :
17271761 return D404 ()
0 commit comments