31 |
31 |
32 def __init__(self, source, startLine, contextType): |
32 def __init__(self, source, startLine, contextType): |
33 """ |
33 """ |
34 Constructor |
34 Constructor |
35 |
35 |
36 @param source source code of the context (list of string or string) |
36 @param source source code of the context |
37 @param startLine line number the context starts in the source (integer) |
37 @type list of str or str |
38 @param contextType type of the context object (string) |
38 @param startLine line number the context starts in the source |
|
39 @type int |
|
40 @param contextType type of the context object |
|
41 @type str |
39 """ |
42 """ |
40 if isinstance(source, str): |
43 if isinstance(source, str): |
41 self.__source = source.splitlines(True) |
44 self.__source = source.splitlines(True) |
42 else: |
45 else: |
43 self.__source = source[:] |
46 self.__source = source[:] |
53 |
56 |
54 def source(self): |
57 def source(self): |
55 """ |
58 """ |
56 Public method to get the source. |
59 Public method to get the source. |
57 |
60 |
58 @return source (list of string) |
61 @return source |
|
62 @rtype list of str |
59 """ |
63 """ |
60 return self.__source |
64 return self.__source |
61 |
65 |
62 def ssource(self): |
66 def ssource(self): |
63 """ |
67 """ |
64 Public method to get the joined source lines. |
68 Public method to get the joined source lines. |
65 |
69 |
66 @return source (string) |
70 @return source |
|
71 @rtype str |
67 """ |
72 """ |
68 return "".join(self.__source) |
73 return "".join(self.__source) |
69 |
74 |
70 def start(self): |
75 def start(self): |
71 """ |
76 """ |
72 Public method to get the start line number. |
77 Public method to get the start line number. |
73 |
78 |
74 @return start line number (integer) |
79 @return start line number |
|
80 @rtype int |
75 """ |
81 """ |
76 return self.__start |
82 return self.__start |
77 |
83 |
78 def end(self): |
84 def end(self): |
79 """ |
85 """ |
80 Public method to get the end line number. |
86 Public method to get the end line number. |
81 |
87 |
82 @return end line number (integer) |
88 @return end line number |
|
89 @rtype int |
83 """ |
90 """ |
84 return self.__start + len(self.__source) - 1 |
91 return self.__start + len(self.__source) - 1 |
85 |
92 |
86 def indent(self): |
93 def indent(self): |
87 """ |
94 """ |
88 Public method to get the indentation of the first line. |
95 Public method to get the indentation of the first line. |
89 |
96 |
90 @return indentation string (string) |
97 @return indentation string |
|
98 @rtype str |
91 """ |
99 """ |
92 return self.__indent |
100 return self.__indent |
93 |
101 |
94 def contextType(self): |
102 def contextType(self): |
95 """ |
103 """ |
96 Public method to get the context type. |
104 Public method to get the context type. |
97 |
105 |
98 @return context type (string) |
106 @return context type |
|
107 @rtype str |
99 """ |
108 """ |
100 return self.__type |
109 return self.__type |
101 |
110 |
102 def setSpecial(self, special): |
111 def setSpecial(self, special): |
103 """ |
112 """ |
189 docType="pep257", |
200 docType="pep257", |
190 ): |
201 ): |
191 """ |
202 """ |
192 Constructor |
203 Constructor |
193 |
204 |
194 @param source source code to be checked (list of string) |
205 @param source source code to be checked |
195 @param filename name of the source file (string) |
206 @type list of str |
196 @param select list of selected codes (list of string) |
207 @param filename name of the source file |
197 @param ignore list of codes to be ignored (list of string) |
208 @type str |
198 @param expected list of expected codes (list of string) |
209 @param select list of selected codes |
|
210 @type list of str |
|
211 @param ignore list of codes to be ignored |
|
212 @type list of str |
|
213 @param expected list of expected codes |
|
214 @type list of str |
199 @param repeat flag indicating to report each occurrence of a code |
215 @param repeat flag indicating to report each occurrence of a code |
200 (boolean) |
216 @type bool |
201 @param maxLineLength allowed line length (integer) |
217 @param maxLineLength allowed line length |
202 @param docType type of the documentation strings |
218 @type int |
203 (string, one of 'eric' or 'pep257') |
219 @param docType type of the documentation strings (one of 'eric' or 'pep257') |
|
220 @type str |
204 """ |
221 """ |
205 self.__select = tuple(select) |
222 self.__select = tuple(select) |
206 self.__ignore = ("",) if select else tuple(ignore) |
223 self.__ignore = ("",) if select else tuple(ignore) |
207 self.__expected = expected[:] |
224 self.__expected = expected[:] |
208 self.__repeat = repeat |
225 self.__repeat = repeat |
294 ( |
311 ( |
295 self.__checkEricNoBlankBeforeAndAfterClassOrFunction, |
312 self.__checkEricNoBlankBeforeAndAfterClassOrFunction, |
296 ("D244", "D245"), |
313 ("D244", "D245"), |
297 ), |
314 ), |
298 (self.__checkEricException, ("D250", "D251", "D252", "D253")), |
315 (self.__checkEricException, ("D250", "D251", "D252", "D253")), |
|
316 (self.__checkEricDocumentationSequence, ("D270",)), |
|
317 (self.__checkEricDocumentationDeprecatedTags, ("D271",)), |
299 ], |
318 ], |
300 "docstring": [ |
319 "docstring": [ |
301 (self.__checkTripleDoubleQuotes, ("D111",)), |
320 (self.__checkTripleDoubleQuotes, ("D111",)), |
302 (self.__checkBackslashes, ("D112",)), |
321 (self.__checkBackslashes, ("D112",)), |
303 (self.__checkIndent, ("D122",)), |
322 (self.__checkIndent, ("D122",)), |
319 |
338 |
320 def __ignoreCode(self, code): |
339 def __ignoreCode(self, code): |
321 """ |
340 """ |
322 Private method to check if the error code should be ignored. |
341 Private method to check if the error code should be ignored. |
323 |
342 |
324 @param code message code to check for (string) |
343 @param code message code to check for |
325 @return flag indicating to ignore the given code (boolean) |
344 @type str |
|
345 @return flag indicating to ignore the given code |
|
346 @rtype bool |
326 """ |
347 """ |
327 return code.startswith(self.__ignore) and not code.startswith(self.__select) |
348 return code.startswith(self.__ignore) and not code.startswith(self.__select) |
328 |
349 |
329 def __error(self, lineNumber, offset, code, *args): |
350 def __error(self, lineNumber, offset, code, *args): |
330 """ |
351 """ |
331 Private method to record an issue. |
352 Private method to record an issue. |
332 |
353 |
333 @param lineNumber line number of the issue (integer) |
354 @param lineNumber line number of the issue |
334 @param offset position within line of the issue (integer) |
355 @type int |
335 @param code message code (string) |
356 @param offset position within line of the issue |
336 @param args arguments for the message (list) |
357 @type int |
|
358 @param code message code |
|
359 @type str |
|
360 @param args arguments for the message |
|
361 @type list |
337 """ |
362 """ |
338 if self.__ignoreCode(code): |
363 if self.__ignoreCode(code): |
339 return |
364 return |
340 |
365 |
341 if code in self.counters: |
366 if code in self.counters: |
398 |
424 |
399 def __getSummaryLine(self, docstringContext): |
425 def __getSummaryLine(self, docstringContext): |
400 """ |
426 """ |
401 Private method to extract the summary line. |
427 Private method to extract the summary line. |
402 |
428 |
403 @param docstringContext docstring context (DocStyleContext) |
429 @param docstringContext docstring context |
404 @return summary line (string) and the line it was found on (integer) |
430 @type DocStyleContext |
|
431 @return summary line (string) and the line it was found on |
|
432 @rtype int |
405 """ |
433 """ |
406 lines = docstringContext.source() |
434 lines = docstringContext.source() |
407 |
435 |
408 line = ( |
436 line = ( |
409 lines[0] |
437 lines[0] |
422 |
450 |
423 def __getSummaryLines(self, docstringContext): |
451 def __getSummaryLines(self, docstringContext): |
424 """ |
452 """ |
425 Private method to extract the summary lines. |
453 Private method to extract the summary lines. |
426 |
454 |
427 @param docstringContext docstring context (DocStyleContext) |
455 @param docstringContext docstring context |
|
456 @type DocStyleContext |
428 @return summary lines (list of string) and the line it was found on |
457 @return summary lines (list of string) and the line it was found on |
429 (integer) |
458 @rtype int |
430 """ |
459 """ |
431 summaries = [] |
460 summaries = [] |
432 lines = docstringContext.source() |
461 lines = docstringContext.source() |
433 |
462 |
434 line0 = ( |
463 line0 = ( |
471 def __getArgNames(self, node): |
500 def __getArgNames(self, node): |
472 """ |
501 """ |
473 Private method to get the argument names of a function node. |
502 Private method to get the argument names of a function node. |
474 |
503 |
475 @param node AST node to extract arguments names from |
504 @param node AST node to extract arguments names from |
|
505 @type ast.AST |
476 @return tuple of two list of argument names, one for arguments |
506 @return tuple of two list of argument names, one for arguments |
477 and one for keyword arguments (tuple of list of string) |
507 and one for keyword arguments |
|
508 @rtype tuple of (list of str, list of str) |
478 """ |
509 """ |
479 arguments = [] |
510 arguments = [] |
480 arguments.extend([arg.arg for arg in node.args.args]) |
511 arguments.extend([arg.arg for arg in node.args.args]) |
481 if node.args.vararg is not None: |
512 if node.args.vararg is not None: |
482 arguments.append(node.args.vararg.arg) |
513 arguments.append(node.args.vararg.arg) |
493 |
524 |
494 def __parseModuleDocstring(self, source): |
525 def __parseModuleDocstring(self, source): |
495 """ |
526 """ |
496 Private method to extract a docstring given a module source. |
527 Private method to extract a docstring given a module source. |
497 |
528 |
498 @param source source to parse (list of string) |
529 @param source source to parse |
499 @return context of extracted docstring (DocStyleContext) |
530 @type list of str |
|
531 @return context of extracted docstring |
|
532 @rtype DocStyleContext |
500 """ |
533 """ |
501 for kind, value, (line, _char), _, _ in tokenize.generate_tokens( |
534 for kind, value, (line, _char), _, _ in tokenize.generate_tokens( |
502 StringIO("".join(source)).readline |
535 StringIO("".join(source)).readline |
503 ): |
536 ): |
504 if kind in [tokenize.COMMENT, tokenize.NEWLINE, tokenize.NL]: |
537 if kind in [tokenize.COMMENT, tokenize.NEWLINE, tokenize.NL]: |
512 |
545 |
513 def __parseDocstring(self, context, what=""): |
546 def __parseDocstring(self, context, what=""): |
514 """ |
547 """ |
515 Private method to extract a docstring given `def` or `class` source. |
548 Private method to extract a docstring given `def` or `class` source. |
516 |
549 |
517 @param context context data to get the docstring from (DocStyleContext) |
550 @param context context data to get the docstring from |
518 @param what string denoting what is being parsed (string) |
551 @type DocStyleContext |
519 @return context of extracted docstring (DocStyleContext) |
552 @param what string denoting what is being parsed |
|
553 @type str |
|
554 @return context of extracted docstring |
|
555 @rtype DocStyleContext |
520 """ |
556 """ |
521 moduleDocstring = self.__parseModuleDocstring(context.source()) |
557 moduleDocstring = self.__parseModuleDocstring(context.source()) |
522 if what.startswith("module") or context.contextType() == "module": |
558 if what.startswith("module") or context.contextType() == "module": |
523 return moduleDocstring |
559 return moduleDocstring |
524 if moduleDocstring: |
560 if moduleDocstring: |
537 |
573 |
538 def __parseTopLevel(self, keyword): |
574 def __parseTopLevel(self, keyword): |
539 """ |
575 """ |
540 Private method to extract top-level functions or classes. |
576 Private method to extract top-level functions or classes. |
541 |
577 |
542 @param keyword keyword signaling what to extract (string) |
578 @param keyword keyword signaling what to extract |
543 @return extracted function or class contexts (list of DocStyleContext) |
579 @type str |
|
580 @return extracted function or class contexts |
|
581 @rtype list of DocStyleContext |
544 """ |
582 """ |
545 self.__resetReadline() |
583 self.__resetReadline() |
546 tokenGenerator = tokenize.generate_tokens(self.__readline) |
584 tokenGenerator = tokenize.generate_tokens(self.__readline) |
547 kind, value, char = None, None, None |
585 kind, value, char = None, None, None |
548 contexts = [] |
586 contexts = [] |
563 |
601 |
564 def __parseFunctions(self): |
602 def __parseFunctions(self): |
565 """ |
603 """ |
566 Private method to extract top-level functions. |
604 Private method to extract top-level functions. |
567 |
605 |
568 @return extracted function contexts (list of DocStyleContext) |
606 @return extracted function contexts |
|
607 @rtype list of DocStyleContext |
569 """ |
608 """ |
570 if not self.__functionsCache: |
609 if not self.__functionsCache: |
571 self.__functionsCache = self.__parseTopLevel("def") |
610 self.__functionsCache = self.__parseTopLevel("def") |
572 return self.__functionsCache |
611 return self.__functionsCache |
573 |
612 |
574 def __parseClasses(self): |
613 def __parseClasses(self): |
575 """ |
614 """ |
576 Private method to extract top-level classes. |
615 Private method to extract top-level classes. |
577 |
616 |
578 @return extracted class contexts (list of DocStyleContext) |
617 @return extracted class contexts |
|
618 @rtype list of DocStyleContext |
579 """ |
619 """ |
580 if not self.__classesCache: |
620 if not self.__classesCache: |
581 self.__classesCache = self.__parseTopLevel("class") |
621 self.__classesCache = self.__parseTopLevel("class") |
582 return self.__classesCache |
622 return self.__classesCache |
583 |
623 |
584 def __skipIndentedBlock(self, tokenGenerator): |
624 def __skipIndentedBlock(self, tokenGenerator): |
585 """ |
625 """ |
586 Private method to skip over an indented block of source code. |
626 Private method to skip over an indented block of source code. |
587 |
627 |
588 @param tokenGenerator token generator |
628 @param tokenGenerator token generator |
|
629 @type str iterator |
589 @return last token of the indented block |
630 @return last token of the indented block |
|
631 @rtype tuple |
590 """ |
632 """ |
591 kind, value, start, end, raw = next(tokenGenerator) |
633 kind, value, start, end, raw = next(tokenGenerator) |
592 while kind != tokenize.INDENT: |
634 while kind != tokenize.INDENT: |
593 kind, value, start, end, raw = next(tokenGenerator) |
635 kind, value, start, end, raw = next(tokenGenerator) |
594 indent = 1 |
636 indent = 1 |
604 |
646 |
605 def __parseMethods(self): |
647 def __parseMethods(self): |
606 """ |
648 """ |
607 Private method to extract methods of all classes. |
649 Private method to extract methods of all classes. |
608 |
650 |
609 @return extracted method contexts (list of DocStyleContext) |
651 @return extracted method contexts |
|
652 @rtype list of DocStyleContext |
610 """ |
653 """ |
611 if not self.__methodsCache: |
654 if not self.__methodsCache: |
612 contexts = [] |
655 contexts = [] |
613 for classContext in self.__parseClasses(): |
656 for classContext in self.__parseClasses(): |
614 tokenGenerator = tokenize.generate_tokens( |
657 tokenGenerator = tokenize.generate_tokens( |
642 |
685 |
643 def __parseContexts(self, kind): |
686 def __parseContexts(self, kind): |
644 """ |
687 """ |
645 Private method to extract a context from the source. |
688 Private method to extract a context from the source. |
646 |
689 |
647 @param kind kind of context to extract (string) |
690 @param kind kind of context to extract |
648 @return requested contexts (list of DocStyleContext) |
691 @type str |
|
692 @return requested contexts |
|
693 @rtype list of DocStyleContext |
649 """ |
694 """ |
650 if kind == "moduleDocstring": |
695 if kind == "moduleDocstring": |
651 return [DocStyleContext(self.__source, 0, "module")] |
696 return [DocStyleContext(self.__source, 0, "module")] |
652 if kind == "functionDocstring": |
697 if kind == "functionDocstring": |
653 return self.__parseFunctions() |
698 return self.__parseFunctions() |
672 |
717 |
673 def __checkModulesDocstrings(self, docstringContext, context): |
718 def __checkModulesDocstrings(self, docstringContext, context): |
674 """ |
719 """ |
675 Private method to check, if the module has a docstring. |
720 Private method to check, if the module has a docstring. |
676 |
721 |
677 @param docstringContext docstring context (DocStyleContext) |
722 @param docstringContext docstring context |
678 @param context context of the docstring (DocStyleContext) |
723 @type DocStyleContext |
|
724 @param context context of the docstring |
|
725 @type DocStyleContext |
679 """ |
726 """ |
680 if docstringContext is None: |
727 if docstringContext is None: |
681 self.__error(context.start(), 0, "D101") |
728 self.__error(context.start(), 0, "D101") |
682 return |
729 return |
683 |
730 |
695 def __checkFunctionDocstring(self, docstringContext, context): |
742 def __checkFunctionDocstring(self, docstringContext, context): |
696 """ |
743 """ |
697 Private method to check, that all public functions and methods |
744 Private method to check, that all public functions and methods |
698 have a docstring. |
745 have a docstring. |
699 |
746 |
700 @param docstringContext docstring context (DocStyleContext) |
747 @param docstringContext docstring context |
701 @param context context of the docstring (DocStyleContext) |
748 @type DocStyleContext |
|
749 @param context context of the docstring |
|
750 @type DocStyleContext |
702 """ |
751 """ |
703 functionName = context.source()[0].lstrip().split()[1].split("(")[0] |
752 functionName = context.source()[0].lstrip().split()[1].split("(")[0] |
704 if functionName.startswith("_") and not functionName.endswith("__"): |
753 if functionName.startswith("_") and not functionName.endswith("__"): |
705 if self.__docType == "eric": |
754 if self.__docType == "eric": |
706 code = "D203" |
755 code = "D203" |
729 def __checkClassDocstring(self, docstringContext, context): |
778 def __checkClassDocstring(self, docstringContext, context): |
730 """ |
779 """ |
731 Private method to check, that all public functions and methods |
780 Private method to check, that all public functions and methods |
732 have a docstring. |
781 have a docstring. |
733 |
782 |
734 @param docstringContext docstring context (DocStyleContext) |
783 @param docstringContext docstring context |
735 @param context context of the docstring (DocStyleContext) |
784 @type DocStyleContext |
|
785 @param context context of the docstring |
|
786 @type DocStyleContext |
736 """ |
787 """ |
737 className = context.source()[0].lstrip().split()[1].split("(")[0] |
788 className = context.source()[0].lstrip().split()[1].split("(")[0] |
738 if className.startswith("_"): |
789 if className.startswith("_"): |
739 if self.__docType == "eric": |
790 if self.__docType == "eric": |
740 code = "D205" |
791 code = "D205" |
762 def __checkTripleDoubleQuotes(self, docstringContext, context): # noqa: U100 |
813 def __checkTripleDoubleQuotes(self, docstringContext, context): # noqa: U100 |
763 """ |
814 """ |
764 Private method to check, that all docstrings are surrounded |
815 Private method to check, that all docstrings are surrounded |
765 by triple double quotes. |
816 by triple double quotes. |
766 |
817 |
767 @param docstringContext docstring context (DocStyleContext) |
818 @param docstringContext docstring context |
768 @param context context of the docstring (DocStyleContext) |
819 @type DocStyleContext |
|
820 @param context context of the docstring |
|
821 @type DocStyleContext |
769 """ |
822 """ |
770 if docstringContext is None: |
823 if docstringContext is None: |
771 return |
824 return |
772 |
825 |
773 docstring = docstringContext.ssource().strip() |
826 docstring = docstringContext.ssource().strip() |
777 def __checkBackslashes(self, docstringContext, context): # noqa: U100 |
830 def __checkBackslashes(self, docstringContext, context): # noqa: U100 |
778 """ |
831 """ |
779 Private method to check, that all docstrings containing |
832 Private method to check, that all docstrings containing |
780 backslashes are surrounded by raw triple double quotes. |
833 backslashes are surrounded by raw triple double quotes. |
781 |
834 |
782 @param docstringContext docstring context (DocStyleContext) |
835 @param docstringContext docstring context |
783 @param context context of the docstring (DocStyleContext) |
836 @type DocStyleContext |
|
837 @param context context of the docstring |
|
838 @type DocStyleContext |
784 """ |
839 """ |
785 if docstringContext is None: |
840 if docstringContext is None: |
786 return |
841 return |
787 |
842 |
788 docstring = docstringContext.ssource().strip() |
843 docstring = docstringContext.ssource().strip() |
792 def __checkOneLiner(self, docstringContext, context): |
847 def __checkOneLiner(self, docstringContext, context): |
793 """ |
848 """ |
794 Private method to check, that one-liner docstrings fit on |
849 Private method to check, that one-liner docstrings fit on |
795 one line with quotes. |
850 one line with quotes. |
796 |
851 |
797 @param docstringContext docstring context (DocStyleContext) |
852 @param docstringContext docstring context |
798 @param context context of the docstring (DocStyleContext) |
853 @type DocStyleContext |
|
854 @param context context of the docstring |
|
855 @type DocStyleContext |
799 """ |
856 """ |
800 if docstringContext is None: |
857 if docstringContext is None: |
801 return |
858 return |
802 |
859 |
803 lines = docstringContext.source() |
860 lines = docstringContext.source() |
817 |
874 |
818 def __checkIndent(self, docstringContext, context): |
875 def __checkIndent(self, docstringContext, context): |
819 """ |
876 """ |
820 Private method to check, that docstrings are properly indented. |
877 Private method to check, that docstrings are properly indented. |
821 |
878 |
822 @param docstringContext docstring context (DocStyleContext) |
879 @param docstringContext docstring context |
823 @param context context of the docstring (DocStyleContext) |
880 @type DocStyleContext |
|
881 @param context context of the docstring |
|
882 @type DocStyleContext |
824 """ |
883 """ |
825 if docstringContext is None: |
884 if docstringContext is None: |
826 return |
885 return |
827 |
886 |
828 lines = docstringContext.source() |
887 lines = docstringContext.source() |
842 |
901 |
843 def __checkSummary(self, docstringContext, context): # noqa: U100 |
902 def __checkSummary(self, docstringContext, context): # noqa: U100 |
844 """ |
903 """ |
845 Private method to check, that docstring summaries contain some text. |
904 Private method to check, that docstring summaries contain some text. |
846 |
905 |
847 @param docstringContext docstring context (DocStyleContext) |
906 @param docstringContext docstring context |
848 @param context context of the docstring (DocStyleContext) |
907 @type DocStyleContext |
|
908 @param context context of the docstring |
|
909 @type DocStyleContext |
849 """ |
910 """ |
850 if docstringContext is None: |
911 if docstringContext is None: |
851 return |
912 return |
852 |
913 |
853 summary, lineNumber = self.__getSummaryLine(docstringContext) |
914 summary, lineNumber = self.__getSummaryLine(docstringContext) |
856 |
917 |
857 def __checkEndsWithPeriod(self, docstringContext, context): # noqa: U100 |
918 def __checkEndsWithPeriod(self, docstringContext, context): # noqa: U100 |
858 """ |
919 """ |
859 Private method to check, that docstring summaries end with a period. |
920 Private method to check, that docstring summaries end with a period. |
860 |
921 |
861 @param docstringContext docstring context (DocStyleContext) |
922 @param docstringContext docstring context |
862 @param context context of the docstring (DocStyleContext) |
923 @type DocStyleContext |
|
924 @param context context of the docstring |
|
925 @type DocStyleContext |
863 """ |
926 """ |
864 if docstringContext is None: |
927 if docstringContext is None: |
865 return |
928 return |
866 |
929 |
867 summary, lineNumber = self.__getSummaryLine(docstringContext) |
930 summary, lineNumber = self.__getSummaryLine(docstringContext) |
871 def __checkImperativeMood(self, docstringContext, context): # noqa: U100 |
934 def __checkImperativeMood(self, docstringContext, context): # noqa: U100 |
872 """ |
935 """ |
873 Private method to check, that docstring summaries are in |
936 Private method to check, that docstring summaries are in |
874 imperative mood. |
937 imperative mood. |
875 |
938 |
876 @param docstringContext docstring context (DocStyleContext) |
939 @param docstringContext docstring context |
877 @param context context of the docstring (DocStyleContext) |
940 @type DocStyleContext |
|
941 @param context context of the docstring |
|
942 @type DocStyleContext |
878 """ |
943 """ |
879 if docstringContext is None: |
944 if docstringContext is None: |
880 return |
945 return |
881 |
946 |
882 summary, lineNumber = self.__getSummaryLine(docstringContext) |
947 summary, lineNumber = self.__getSummaryLine(docstringContext) |
888 def __checkNoSignature(self, docstringContext, context): |
953 def __checkNoSignature(self, docstringContext, context): |
889 """ |
954 """ |
890 Private method to check, that docstring summaries don't repeat |
955 Private method to check, that docstring summaries don't repeat |
891 the function's signature. |
956 the function's signature. |
892 |
957 |
893 @param docstringContext docstring context (DocStyleContext) |
958 @param docstringContext docstring context |
894 @param context context of the docstring (DocStyleContext) |
959 @type DocStyleContext |
|
960 @param context context of the docstring |
|
961 @type DocStyleContext |
895 """ |
962 """ |
896 if docstringContext is None: |
963 if docstringContext is None: |
897 return |
964 return |
898 |
965 |
899 functionName = context.source()[0].lstrip().split()[1].split("(")[0] |
966 functionName = context.source()[0].lstrip().split()[1].split("(")[0] |
906 |
973 |
907 def __checkReturnType(self, docstringContext, context): |
974 def __checkReturnType(self, docstringContext, context): |
908 """ |
975 """ |
909 Private method to check, that docstrings mention the return value type. |
976 Private method to check, that docstrings mention the return value type. |
910 |
977 |
911 @param docstringContext docstring context (DocStyleContext) |
978 @param docstringContext docstring context |
912 @param context context of the docstring (DocStyleContext) |
979 @type DocStyleContext |
|
980 @param context context of the docstring |
|
981 @type DocStyleContext |
913 """ |
982 """ |
914 if docstringContext is None: |
983 if docstringContext is None: |
915 return |
984 return |
916 |
985 |
917 if "return" not in docstringContext.ssource().lower(): |
986 if "return" not in docstringContext.ssource().lower(): |
932 def __checkNoBlankLineBefore(self, docstringContext, context): |
1001 def __checkNoBlankLineBefore(self, docstringContext, context): |
933 """ |
1002 """ |
934 Private method to check, that function/method docstrings are not |
1003 Private method to check, that function/method docstrings are not |
935 preceded by a blank line. |
1004 preceded by a blank line. |
936 |
1005 |
937 @param docstringContext docstring context (DocStyleContext) |
1006 @param docstringContext docstring context |
938 @param context context of the docstring (DocStyleContext) |
1007 @type DocStyleContext |
|
1008 @param context context of the docstring |
|
1009 @type DocStyleContext |
939 """ |
1010 """ |
940 if docstringContext is None: |
1011 if docstringContext is None: |
941 return |
1012 return |
942 |
1013 |
943 contextLines = context.source() |
1014 contextLines = context.source() |
955 def __checkBlankBeforeAndAfterClass(self, docstringContext, context): |
1026 def __checkBlankBeforeAndAfterClass(self, docstringContext, context): |
956 """ |
1027 """ |
957 Private method to check, that class docstrings have one |
1028 Private method to check, that class docstrings have one |
958 blank line around them. |
1029 blank line around them. |
959 |
1030 |
960 @param docstringContext docstring context (DocStyleContext) |
1031 @param docstringContext docstring context |
961 @param context context of the docstring (DocStyleContext) |
1032 @type DocStyleContext |
|
1033 @param context context of the docstring |
|
1034 @type DocStyleContext |
962 """ |
1035 """ |
963 if docstringContext is None: |
1036 if docstringContext is None: |
964 return |
1037 return |
965 |
1038 |
966 contextLines = context.source() |
1039 contextLines = context.source() |
993 def __checkBlankAfterSummary(self, docstringContext, context): # noqa: U100 |
1066 def __checkBlankAfterSummary(self, docstringContext, context): # noqa: U100 |
994 """ |
1067 """ |
995 Private method to check, that docstring summaries are followed |
1068 Private method to check, that docstring summaries are followed |
996 by a blank line. |
1069 by a blank line. |
997 |
1070 |
998 @param docstringContext docstring context (DocStyleContext) |
1071 @param docstringContext docstring context |
999 @param context context of the docstring (DocStyleContext) |
1072 @type DocStyleContext |
|
1073 @param context context of the docstring |
|
1074 @type DocStyleContext |
1000 """ |
1075 """ |
1001 if docstringContext is None: |
1076 if docstringContext is None: |
1002 return |
1077 return |
1003 |
1078 |
1004 docstrings = docstringContext.source() |
1079 docstrings = docstringContext.source() |
1013 def __checkBlankAfterLastParagraph(self, docstringContext, context): # noqa: U100 |
1088 def __checkBlankAfterLastParagraph(self, docstringContext, context): # noqa: U100 |
1014 """ |
1089 """ |
1015 Private method to check, that the last paragraph of docstrings is |
1090 Private method to check, that the last paragraph of docstrings is |
1016 followed by a blank line. |
1091 followed by a blank line. |
1017 |
1092 |
1018 @param docstringContext docstring context (DocStyleContext) |
1093 @param docstringContext docstring context |
1019 @param context context of the docstring (DocStyleContext) |
1094 @type DocStyleContext |
|
1095 @param context context of the docstring |
|
1096 @type DocStyleContext |
1020 """ |
1097 """ |
1021 if docstringContext is None: |
1098 if docstringContext is None: |
1022 return |
1099 return |
1023 |
1100 |
1024 docstrings = docstringContext.source() |
1101 docstrings = docstringContext.source() |
1036 def __checkEricQuotesOnSeparateLines(self, docstringContext, context): # noqa: U100 |
1113 def __checkEricQuotesOnSeparateLines(self, docstringContext, context): # noqa: U100 |
1037 """ |
1114 """ |
1038 Private method to check, that leading and trailing quotes are on |
1115 Private method to check, that leading and trailing quotes are on |
1039 a line by themselves. |
1116 a line by themselves. |
1040 |
1117 |
1041 @param docstringContext docstring context (DocStyleContext) |
1118 @param docstringContext docstring context |
1042 @param context context of the docstring (DocStyleContext) |
1119 @type DocStyleContext |
|
1120 @param context context of the docstring |
|
1121 @type DocStyleContext |
1043 """ |
1122 """ |
1044 if docstringContext is None: |
1123 if docstringContext is None: |
1045 return |
1124 return |
1046 |
1125 |
1047 lines = docstringContext.source() |
1126 lines = docstringContext.source() |
1052 |
1131 |
1053 def __checkEricEndsWithPeriod(self, docstringContext, context): # noqa: U100 |
1132 def __checkEricEndsWithPeriod(self, docstringContext, context): # noqa: U100 |
1054 """ |
1133 """ |
1055 Private method to check, that docstring summaries end with a period. |
1134 Private method to check, that docstring summaries end with a period. |
1056 |
1135 |
1057 @param docstringContext docstring context (DocStyleContext) |
1136 @param docstringContext docstring context |
1058 @param context context of the docstring (DocStyleContext) |
1137 @type DocStyleContext |
|
1138 @param context context of the docstring |
|
1139 @type DocStyleContext |
1059 """ |
1140 """ |
1060 if docstringContext is None: |
1141 if docstringContext is None: |
1061 return |
1142 return |
1062 |
1143 |
1063 summaryLines, lineNumber = self.__getSummaryLines(docstringContext) |
1144 summaryLines, lineNumber = self.__getSummaryLines(docstringContext) |
1079 def __checkEricReturn(self, docstringContext, context): |
1160 def __checkEricReturn(self, docstringContext, context): |
1080 """ |
1161 """ |
1081 Private method to check, that docstrings contain an @return line |
1162 Private method to check, that docstrings contain an @return line |
1082 if they return anything and don't otherwise. |
1163 if they return anything and don't otherwise. |
1083 |
1164 |
1084 @param docstringContext docstring context (DocStyleContext) |
1165 @param docstringContext docstring context |
1085 @param context context of the docstring (DocStyleContext) |
1166 @type DocStyleContext |
|
1167 @param context context of the docstring |
|
1168 @type DocStyleContext |
1086 """ |
1169 """ |
1087 if docstringContext is None: |
1170 if docstringContext is None: |
1088 return |
1171 return |
1089 |
1172 |
1090 tokens = list(tokenize.generate_tokens(StringIO(context.ssource()).readline)) |
1173 tokens = list(tokenize.generate_tokens(StringIO(context.ssource()).readline)) |
1107 def __checkEricYield(self, docstringContext, context): |
1190 def __checkEricYield(self, docstringContext, context): |
1108 """ |
1191 """ |
1109 Private method to check, that docstrings contain an @yield line |
1192 Private method to check, that docstrings contain an @yield line |
1110 if they return anything and don't otherwise. |
1193 if they return anything and don't otherwise. |
1111 |
1194 |
1112 @param docstringContext docstring context (DocStyleContext) |
1195 @param docstringContext docstring context |
1113 @param context context of the docstring (DocStyleContext) |
1196 @type DocStyleContext |
|
1197 @param context context of the docstring |
|
1198 @type DocStyleContext |
1114 """ |
1199 """ |
1115 if docstringContext is None: |
1200 if docstringContext is None: |
1116 return |
1201 return |
1117 |
1202 |
1118 tokens = list(tokenize.generate_tokens(StringIO(context.ssource()).readline)) |
1203 tokens = list(tokenize.generate_tokens(StringIO(context.ssource()).readline)) |
1129 def __checkEricFunctionArguments(self, docstringContext, context): |
1214 def __checkEricFunctionArguments(self, docstringContext, context): |
1130 """ |
1215 """ |
1131 Private method to check, that docstrings contain an @param and/or |
1216 Private method to check, that docstrings contain an @param and/or |
1132 @keyparam line for each argument. |
1217 @keyparam line for each argument. |
1133 |
1218 |
1134 @param docstringContext docstring context (DocStyleContext) |
1219 @param docstringContext docstring context |
1135 @param context context of the docstring (DocStyleContext) |
1220 @type DocStyleContext |
|
1221 @param context context of the docstring |
|
1222 @type DocStyleContext |
1136 """ |
1223 """ |
1137 if docstringContext is None: |
1224 if docstringContext is None: |
1138 return |
1225 return |
1139 |
1226 |
1140 try: |
1227 try: |
1151 if "self" in argNames: |
1238 if "self" in argNames: |
1152 argNames.remove("self") |
1239 argNames.remove("self") |
1153 if "cls" in argNames: |
1240 if "cls" in argNames: |
1154 argNames.remove("cls") |
1241 argNames.remove("cls") |
1155 |
1242 |
1156 docstring = docstringContext.ssource() |
1243 tagstring = "".join( |
1157 if docstring.count("@param") + docstring.count("@keyparam") < len( |
1244 line.lstrip() |
|
1245 for line in docstringContext.source() |
|
1246 if line.lstrip().startswith("@") |
|
1247 ) |
|
1248 if tagstring.count("@param") + tagstring.count("@keyparam") < len( |
1158 argNames + kwNames |
1249 argNames + kwNames |
1159 ): |
1250 ): |
1160 self.__error(docstringContext.end(), 0, "D236") |
1251 self.__error(docstringContext.end(), 0, "D236") |
1161 elif docstring.count("@param") + docstring.count("@keyparam") > len( |
1252 elif tagstring.count("@param") + tagstring.count("@keyparam") > len( |
1162 argNames + kwNames |
1253 argNames + kwNames |
1163 ): |
1254 ): |
1164 self.__error(docstringContext.end(), 0, "D237") |
1255 self.__error(docstringContext.end(), 0, "D237") |
1165 else: |
1256 else: |
1166 # extract @param and @keyparam from docstring |
1257 # extract @param and @keyparam from docstring |
1190 |
1281 |
1191 Note: This method also checks the raised and documented exceptions for |
1282 Note: This method also checks the raised and documented exceptions for |
1192 completeness (i.e. raised exceptions that are not documented or |
1283 completeness (i.e. raised exceptions that are not documented or |
1193 documented exceptions that are not raised) |
1284 documented exceptions that are not raised) |
1194 |
1285 |
1195 @param docstringContext docstring context (DocStyleContext) |
1286 @param docstringContext docstring context |
1196 @param context context of the docstring (DocStyleContext) |
1287 @type DocStyleContext |
|
1288 @param context context of the docstring |
|
1289 @type DocStyleContext |
1197 """ |
1290 """ |
1198 if docstringContext is None: |
1291 if docstringContext is None: |
1199 return |
1292 return |
1200 |
1293 |
1201 tokens = list(tokenize.generate_tokens(StringIO(context.ssource()).readline)) |
1294 tokens = list(tokenize.generate_tokens(StringIO(context.ssource()).readline)) |
1250 |
1343 |
1251 Note: This method also checks the defined and documented signals for |
1344 Note: This method also checks the defined and documented signals for |
1252 completeness (i.e. defined signals that are not documented or |
1345 completeness (i.e. defined signals that are not documented or |
1253 documented signals that are not defined) |
1346 documented signals that are not defined) |
1254 |
1347 |
1255 @param docstringContext docstring context (DocStyleContext) |
1348 @param docstringContext docstring context |
1256 @param context context of the docstring (DocStyleContext) |
1349 @type DocStyleContext |
|
1350 @param context context of the docstring |
|
1351 @type DocStyleContext |
1257 """ |
1352 """ |
1258 if docstringContext is None: |
1353 if docstringContext is None: |
1259 return |
1354 return |
1260 |
1355 |
1261 tokens = list(tokenize.generate_tokens(StringIO(context.ssource()).readline)) |
1356 tokens = list(tokenize.generate_tokens(StringIO(context.ssource()).readline)) |
1298 def __checkEricBlankAfterSummary(self, docstringContext, context): # noqa: U100 |
1393 def __checkEricBlankAfterSummary(self, docstringContext, context): # noqa: U100 |
1299 """ |
1394 """ |
1300 Private method to check, that docstring summaries are followed |
1395 Private method to check, that docstring summaries are followed |
1301 by a blank line. |
1396 by a blank line. |
1302 |
1397 |
1303 @param docstringContext docstring context (DocStyleContext) |
1398 @param docstringContext docstring context |
1304 @param context context of the docstring (DocStyleContext) |
1399 @type DocStyleContext |
|
1400 @param context context of the docstring |
|
1401 @type DocStyleContext |
1305 """ |
1402 """ |
1306 if docstringContext is None: |
1403 if docstringContext is None: |
1307 return |
1404 return |
1308 |
1405 |
1309 docstrings = docstringContext.source() |
1406 docstrings = docstringContext.source() |
1323 ): |
1420 ): |
1324 """ |
1421 """ |
1325 Private method to check, that class and function/method docstrings |
1422 Private method to check, that class and function/method docstrings |
1326 have no blank line around them. |
1423 have no blank line around them. |
1327 |
1424 |
1328 @param docstringContext docstring context (DocStyleContext) |
1425 @param docstringContext docstring context |
1329 @param context context of the docstring (DocStyleContext) |
1426 @type DocStyleContext |
|
1427 @param context context of the docstring |
|
1428 @type DocStyleContext |
1330 """ |
1429 """ |
1331 if docstringContext is None: |
1430 if docstringContext is None: |
1332 return |
1431 return |
1333 |
1432 |
1334 contextLines = context.source() |
1433 contextLines = context.source() |
1379 ): |
1478 ): |
1380 """ |
1479 """ |
1381 Private method to check, that the last paragraph of docstrings is |
1480 Private method to check, that the last paragraph of docstrings is |
1382 not followed by a blank line. |
1481 not followed by a blank line. |
1383 |
1482 |
1384 @param docstringContext docstring context (DocStyleContext) |
1483 @param docstringContext docstring context |
1385 @param context context of the docstring (DocStyleContext) |
1484 @type DocStyleContext |
|
1485 @param context context of the docstring |
|
1486 @type DocStyleContext |
1386 """ |
1487 """ |
1387 if docstringContext is None: |
1488 if docstringContext is None: |
1388 return |
1489 return |
1389 |
1490 |
1390 docstrings = docstringContext.source() |
1491 docstrings = docstringContext.source() |
1398 def __checkEricSummary(self, docstringContext, context): |
1499 def __checkEricSummary(self, docstringContext, context): |
1399 """ |
1500 """ |
1400 Private method to check, that method docstring summaries start with |
1501 Private method to check, that method docstring summaries start with |
1401 specific words. |
1502 specific words. |
1402 |
1503 |
1403 @param docstringContext docstring context (DocStyleContext) |
1504 @param docstringContext docstring context |
1404 @param context context of the docstring (DocStyleContext) |
1505 @type DocStyleContext |
|
1506 @param context context of the docstring |
|
1507 @type DocStyleContext |
1405 """ |
1508 """ |
1406 if docstringContext is None: |
1509 if docstringContext is None: |
1407 return |
1510 return |
1408 |
1511 |
1409 summary, lineNumber = self.__getSummaryLine(docstringContext) |
1512 summary, lineNumber = self.__getSummaryLine(docstringContext) |
1502 else: |
1605 else: |
1503 if firstWord != "public": |
1606 if firstWord != "public": |
1504 self.__error( |
1607 self.__error( |
1505 docstringContext.start() + lineNumber, 0, "D232", "public" |
1608 docstringContext.start() + lineNumber, 0, "D232", "public" |
1506 ) |
1609 ) |
|
1610 |
|
1611 def __checkEricDocumentationSequence( |
|
1612 self, |
|
1613 docstringContext, |
|
1614 context, # noqa: U100 |
|
1615 ): |
|
1616 """ |
|
1617 Private method to check, that method docstring follows the correct sequence |
|
1618 of entries (e.g. @param is followed by @type). |
|
1619 |
|
1620 @param docstringContext docstring context |
|
1621 @type DocStyleContext |
|
1622 @param context context of the docstring |
|
1623 @type DocStyleContext |
|
1624 """ |
|
1625 if docstringContext is None: |
|
1626 return |
|
1627 |
|
1628 docTokens = [] |
|
1629 for lineno, line in enumerate(docstringContext.source()): |
|
1630 strippedLine = line.lstrip() |
|
1631 if strippedLine.startswith("@"): |
|
1632 docTokens.append((strippedLine.split(None, 1)[0], lineno)) |
|
1633 |
|
1634 for index in range(len(docTokens)): |
|
1635 docToken, lineno = docTokens[index] |
|
1636 try: |
|
1637 docToken2, _ = docTokens[index + 1] |
|
1638 except IndexError: |
|
1639 docToken2 = "" |
|
1640 |
|
1641 if docToken in ("@param", "@keyparam") and docToken2 != "@type": |
|
1642 self.__error( |
|
1643 docstringContext.start() + lineno, 0, "D270", docToken, "@type" |
|
1644 ) |
|
1645 elif docToken == "@return" and docToken2 != "@rtype": |
|
1646 self.__error( |
|
1647 docstringContext.start() + lineno, 0, "D270", docToken, "@rtype" |
|
1648 ) |
|
1649 elif docToken == "@yield" and docToken2 != "@ytype": |
|
1650 self.__error( |
|
1651 docstringContext.start() + lineno, 0, "D270", docToken, "@ytype" |
|
1652 ) |
|
1653 |
|
1654 def __checkEricDocumentationDeprecatedTags( |
|
1655 self, |
|
1656 docstringContext, |
|
1657 context, # noqa: U100 |
|
1658 ): |
|
1659 """ |
|
1660 Private method to check the use of deprecated documentation tags. |
|
1661 |
|
1662 @param docstringContext docstring context |
|
1663 @type DocStyleContext |
|
1664 @param context context of the docstring |
|
1665 @type DocStyleContext |
|
1666 """ |
|
1667 if docstringContext is None: |
|
1668 return |
|
1669 |
|
1670 deprecationsList = { |
|
1671 # key is deprecated tag, value is the tag to be used |
|
1672 "@ireturn": "@return", |
|
1673 "@ptype": "@type", |
|
1674 "@raise": "@exception", |
|
1675 "@throws": "@exception", |
|
1676 } |
|
1677 |
|
1678 for lineno, line in enumerate(docstringContext.source()): |
|
1679 strippedLine = line.lstrip() |
|
1680 if strippedLine.startswith("@"): |
|
1681 # it is a tag line |
|
1682 tag = strippedLine.split(None, 1)[0] |
|
1683 with contextlib.suppress(KeyError): |
|
1684 self.__error( |
|
1685 docstringContext.start() + lineno, |
|
1686 0, |
|
1687 "D271", |
|
1688 tag, |
|
1689 deprecationsList[tag], |
|
1690 ) |