201 Public method to fix the fixable issues. |
199 Public method to fix the fixable issues. |
202 |
200 |
203 @param line line number of issue (integer) |
201 @param line line number of issue (integer) |
204 @param pos character position of issue (integer) |
202 @param pos character position of issue (integer) |
205 @param message message text (string) |
203 @param message message text (string) |
206 @return flag indicating an applied fix (boolean) and a message for |
204 @return value indicating an applied/deferred fix (-1, 0, 1), |
207 the fix (string) |
205 a message for the fix (string) and an ID for a deferred |
|
206 fix (integer) |
208 """ |
207 """ |
209 code = message.split(None, 1)[0].strip() |
208 code = message.split(None, 1)[0].strip() |
210 |
209 |
211 if line <= len(self.__source) and \ |
210 if line <= len(self.__source) and \ |
212 self.__codeMatch(code) and \ |
211 self.__codeMatch(code) and \ |
213 code in self.__fixes: |
212 code in self.__fixes: |
214 res = self.__fixes[code](code, line, pos) |
213 res = self.__fixes[code](code, line, pos) |
215 if res[0]: |
214 if res[0] == 1: |
216 self.__modified = True |
215 self.__modified = True |
217 self.fixed += 1 |
216 self.fixed += 1 |
218 else: |
217 else: |
219 res = (False, "") |
218 res = (0, "", 0) |
220 |
219 |
221 return res |
220 return res |
222 |
221 |
223 def __finalize(self): |
222 def finalize(self): |
224 """ |
223 """ |
225 Private method to apply all deferred fixes. |
224 Public method to apply all deferred fixes. |
226 """ |
225 """ |
|
226 results = {} |
|
227 |
227 # step 1: do fixes operating on logical lines first |
228 # step 1: do fixes operating on logical lines first |
228 for code, line, pos in self.__stackLogical: |
229 for id_, code, line, pos in self.__stackLogical: |
229 self.__fixes[code](code, line, pos, apply=True) |
230 res, msg, _ = self.__fixes[code](code, line, pos, apply=True) |
|
231 if res == 1: |
|
232 self.__modified = True |
|
233 self.fixed += 1 |
|
234 results[id_] = (res, msg) |
230 |
235 |
231 # step 2: do fixes that change the number of lines |
236 # step 2: do fixes that change the number of lines |
232 for code, line, pos in reversed(self.__stack): |
237 for id_, code, line, pos in reversed(self.__stack): |
233 self.__fixes[code](code, line, pos, apply=True) |
238 res, msg, _ = self.__fixes[code](code, line, pos, apply=True) |
|
239 if res == 1: |
|
240 self.__modified = True |
|
241 self.fixed += 1 |
|
242 results[id_] = (res, msg) |
|
243 |
|
244 return results |
|
245 |
|
246 def __getID(self): |
|
247 """ |
|
248 Private method to get the ID for a deferred fix. |
|
249 |
|
250 @return ID for a deferred fix (integer) |
|
251 """ |
|
252 self.__lastID += 1 |
|
253 return self.__lastID |
234 |
254 |
235 def __getEol(self): |
255 def __getEol(self): |
236 """ |
256 """ |
237 Private method to get the applicable eol string. |
257 Private method to get the applicable eol string. |
238 |
258 |
467 @param code code of the issue (string) |
488 @param code code of the issue (string) |
468 @param line line number of the issue (integer) |
489 @param line line number of the issue (integer) |
469 @param pos position inside line (integer) |
490 @param pos position inside line (integer) |
470 @keyparam apply flag indicating, that the fix should be applied |
491 @keyparam apply flag indicating, that the fix should be applied |
471 (boolean) |
492 (boolean) |
472 @return flag indicating an applied fix (boolean) and a message for |
493 @return value indicating an applied/deferred fix (-1, 0, 1), |
473 the fix (string) |
494 a message for the fix (string) and an ID for a deferred |
|
495 fix (integer) |
474 """ |
496 """ |
475 if apply: |
497 if apply: |
476 logical = self.__getLogical(line, pos) |
498 logical = self.__getLogical(line, pos) |
477 if logical: |
499 if logical: |
478 # Fix by adjusting initial indent level. |
500 # Fix by adjusting initial indent level. |
479 self.__fixReindent(line, pos, logical) |
501 self.__fixReindent(line, pos, logical) |
480 else: |
502 if code == "E121": |
481 self.__stackLogical.append((code, line, pos)) |
503 msg = self.trUtf8("Indentation of continuation line corrected.") |
482 if code == "E121": |
504 elif code == "E124": |
483 msg = self.trUtf8("Indentation of continuation line corrected.") |
505 msg = self.trUtf8("Indentation of closing bracket corrected.") |
484 elif code == "E124": |
506 return (1, msg, 0) |
485 msg = self.trUtf8("Indentation of closing bracket corrected.") |
507 else: |
486 return (True, msg) |
508 id = self.__getID() |
|
509 self.__stackLogical.append((id, code, line, pos)) |
|
510 return (-1, "", id) |
487 |
511 |
488 def __fixE122(self, code, line, pos, apply=False): |
512 def __fixE122(self, code, line, pos, apply=False): |
489 """ |
513 """ |
490 Private method to fix a missing indentation of continuation lines |
514 Private method to fix a missing indentation of continuation lines |
491 (E122). |
515 (E122). |
599 if newText == text: |
637 if newText == text: |
600 # fall back to slower method |
638 # fall back to slower method |
601 self.__fixReindent(line, pos, logical) |
639 self.__fixReindent(line, pos, logical) |
602 else: |
640 else: |
603 self.__source[row] = newText |
641 self.__source[row] = newText |
604 else: |
642 return ( |
605 self.__stackLogical.append((code, line, pos)) |
643 1, |
606 return ( |
644 self.trUtf8( |
607 True, |
645 "Indentation level of hanging indentation changed."), |
608 self.trUtf8("Indentation level of hanging indentation changed.")) |
646 0) |
|
647 else: |
|
648 id = self.__getID() |
|
649 self.__stackLogical.append((id, code, line, pos)) |
|
650 return (-1, "", id) |
609 |
651 |
610 def __fixE127(self, code, line, pos, apply=False): |
652 def __fixE127(self, code, line, pos, apply=False): |
611 """ |
653 """ |
612 Private method to fix over/under indented lines (E127, E128). |
654 Private method to fix over/under indented lines (E127, E128). |
613 |
655 |
614 @param code code of the issue (string) |
656 @param code code of the issue (string) |
615 @param line line number of the issue (integer) |
657 @param line line number of the issue (integer) |
616 @param pos position inside line (integer) |
658 @param pos position inside line (integer) |
617 @keyparam apply flag indicating, that the fix should be applied |
659 @keyparam apply flag indicating, that the fix should be applied |
618 (boolean) |
660 (boolean) |
619 @return flag indicating an applied fix (boolean) and a message for |
661 @return value indicating an applied/deferred fix (-1, 0, 1), |
620 the fix (string) |
662 a message for the fix (string) and an ID for a deferred |
|
663 fix (integer) |
621 """ |
664 """ |
622 if apply: |
665 if apply: |
623 logical = self.__getLogical(line, pos) |
666 logical = self.__getLogical(line, pos) |
624 if logical: |
667 if logical: |
625 # Fix by inserting/deleting whitespace to the correct level. |
668 # Fix by inserting/deleting whitespace to the correct level. |
647 if newText == text: |
690 if newText == text: |
648 # fall back to slower method |
691 # fall back to slower method |
649 self.__fixReindent(line, pos, logical) |
692 self.__fixReindent(line, pos, logical) |
650 else: |
693 else: |
651 self.__source[row] = newText |
694 self.__source[row] = newText |
652 else: |
695 return (1, self.trUtf8("Visual indentation corrected."), 0) |
653 self.__stackLogical.append((code, line, pos)) |
696 else: |
654 return (True, self.trUtf8("Visual indentation corrected.")) |
697 id = self.__getID() |
|
698 self.__stackLogical.append((id, code, line, pos)) |
|
699 return (-1, "", id) |
655 |
700 |
656 def __fixE201(self, code, line, pos): |
701 def __fixE201(self, code, line, pos): |
657 """ |
702 """ |
658 Private method to fix extraneous whitespace (E201, E202, |
703 Private method to fix extraneous whitespace (E201, E202, |
659 E203, E211). |
704 E203, E211). |
660 |
705 |
661 @param code code of the issue (string) |
706 @param code code of the issue (string) |
662 @param line line number of the issue (integer) |
707 @param line line number of the issue (integer) |
663 @param pos position inside line (integer) |
708 @param pos position inside line (integer) |
664 @return flag indicating an applied fix (boolean) and a message for |
709 @return value indicating an applied/deferred fix (-1, 0, 1), |
665 the fix (string) |
710 a message for the fix (string) and an ID for a deferred |
|
711 fix (integer) |
666 """ |
712 """ |
667 line = line - 1 |
713 line = line - 1 |
668 text = self.__source[line] |
714 text = self.__source[line] |
669 |
715 |
670 if '"""' in text or "'''" in text or text.rstrip().endswith('\\'): |
716 if '"""' in text or "'''" in text or text.rstrip().endswith('\\'): |
671 return ( |
717 return ( |
672 False, self.trUtf8("Extraneous whitespace cannot be removed.")) |
718 0, self.trUtf8("Extraneous whitespace cannot be removed."), 0) |
673 |
719 |
674 newText = self.__fixWhitespace(text, pos, '') |
720 newText = self.__fixWhitespace(text, pos, '') |
675 if newText == text: |
721 if newText == text: |
676 return (False, "") |
722 return (0, "", 0) |
677 |
723 |
678 self.__source[line] = newText |
724 self.__source[line] = newText |
679 return (True, self.trUtf8("Extraneous whitespace removed.")) |
725 return (1, self.trUtf8("Extraneous whitespace removed."), 0) |
680 |
726 |
681 def __fixE221(self, code, line, pos): |
727 def __fixE221(self, code, line, pos): |
682 """ |
728 """ |
683 Private method to fix extraneous whitespace around operator or |
729 Private method to fix extraneous whitespace around operator or |
684 keyword (E221, E222, E223, E224, E225, E226, E227, E228, E241, |
730 keyword (E221, E222, E223, E224, E225, E226, E227, E228, E241, |
685 E242, E271, E272, E273, E274). |
731 E242, E271, E272, E273, E274). |
686 |
732 |
687 @param code code of the issue (string) |
733 @param code code of the issue (string) |
688 @param line line number of the issue (integer) |
734 @param line line number of the issue (integer) |
689 @param pos position inside line (integer) |
735 @param pos position inside line (integer) |
690 @return flag indicating an applied fix (boolean) and a message for |
736 @return value indicating an applied/deferred fix (-1, 0, 1), |
691 the fix (string) |
737 a message for the fix (string) and an ID for a deferred |
|
738 fix (integer) |
692 """ |
739 """ |
693 line = line - 1 |
740 line = line - 1 |
694 text = self.__source[line] |
741 text = self.__source[line] |
695 |
742 |
696 if '"""' in text or "'''" in text or text.rstrip().endswith('\\'): |
743 if '"""' in text or "'''" in text or text.rstrip().endswith('\\'): |
697 return ( |
744 return ( |
698 False, self.trUtf8("Extraneous whitespace cannot be removed.")) |
745 0, self.trUtf8("Extraneous whitespace cannot be removed."), 0) |
699 |
746 |
700 newText = self.__fixWhitespace(text, pos, ' ') |
747 newText = self.__fixWhitespace(text, pos, ' ') |
701 if newText == text: |
748 if newText == text: |
702 return (False, "") |
749 return (0, "", 0) |
703 |
750 |
704 self.__source[line] = newText |
751 self.__source[line] = newText |
705 if code in ["E225", "E226", "E227", "E228"]: |
752 if code in ["E225", "E226", "E227", "E228"]: |
706 return (True, self.trUtf8("Missing whitespace added.")) |
753 return (1, self.trUtf8("Missing whitespace added."), 0) |
707 else: |
754 else: |
708 return (True, self.trUtf8("Extraneous whitespace removed.")) |
755 return (1, self.trUtf8("Extraneous whitespace removed."), 0) |
709 |
756 |
710 def __fixE231(self, code, line, pos): |
757 def __fixE231(self, code, line, pos): |
711 """ |
758 """ |
712 Private method to fix missing whitespace after ',;:'. |
759 Private method to fix missing whitespace after ',;:'. |
713 |
760 |
714 @param code code of the issue (string) |
761 @param code code of the issue (string) |
715 @param line line number of the issue (integer) |
762 @param line line number of the issue (integer) |
716 @param pos position inside line (integer) |
763 @param pos position inside line (integer) |
717 @return flag indicating an applied fix (boolean) and a message for |
764 @return value indicating an applied/deferred fix (-1, 0, 1), |
718 the fix (string) |
765 a message for the fix (string) and an ID for a deferred |
|
766 fix (integer) |
719 """ |
767 """ |
720 line = line - 1 |
768 line = line - 1 |
721 pos = pos + 1 |
769 pos = pos + 1 |
722 self.__source[line] = self.__source[line][:pos] + \ |
770 self.__source[line] = self.__source[line][:pos] + \ |
723 " " + \ |
771 " " + \ |
724 self.__source[line][pos:] |
772 self.__source[line][pos:] |
725 return (True, self.trUtf8("Missing whitespace added.")) |
773 return (1, self.trUtf8("Missing whitespace added."), 0) |
726 |
774 |
727 def __fixE251(self, code, line, pos): |
775 def __fixE251(self, code, line, pos): |
728 """ |
776 """ |
729 Private method to fix extraneous whitespace around keyword and |
777 Private method to fix extraneous whitespace around keyword and |
730 default parameter equals (E251). |
778 default parameter equals (E251). |
731 |
779 |
732 @param code code of the issue (string) |
780 @param code code of the issue (string) |
733 @param line line number of the issue (integer) |
781 @param line line number of the issue (integer) |
734 @param pos position inside line (integer) |
782 @param pos position inside line (integer) |
735 @return flag indicating an applied fix (boolean) and a message for |
783 @return value indicating an applied/deferred fix (-1, 0, 1), |
736 the fix (string) |
784 a message for the fix (string) and an ID for a deferred |
|
785 fix (integer) |
737 """ |
786 """ |
738 line = line - 1 |
787 line = line - 1 |
739 text = self.__source[line] |
788 text = self.__source[line] |
740 |
789 |
741 # This is necessary since pep8 sometimes reports columns that goes |
790 # This is necessary since pep8 sometimes reports columns that goes |
754 if newText.endswith(('=\\\n', '=\\\r\n', '=\\\r')): |
803 if newText.endswith(('=\\\n', '=\\\r\n', '=\\\r')): |
755 self.__source[line] = newText.rstrip("\n\r \t\\") |
804 self.__source[line] = newText.rstrip("\n\r \t\\") |
756 self.__source[line + 1] = self.__source[line + 1].lstrip() |
805 self.__source[line + 1] = self.__source[line + 1].lstrip() |
757 else: |
806 else: |
758 self.__source[line] = newText |
807 self.__source[line] = newText |
759 return (True, self.trUtf8("Extraneous whitespace removed.")) |
808 return (1, self.trUtf8("Extraneous whitespace removed."), 0) |
760 |
809 |
761 def __fixE261(self, code, line, pos): |
810 def __fixE261(self, code, line, pos): |
762 """ |
811 """ |
763 Private method to fix whitespace before or after inline comment |
812 Private method to fix whitespace before or after inline comment |
764 (E261, E262). |
813 (E261, E262). |
765 |
814 |
766 @param code code of the issue (string) |
815 @param code code of the issue (string) |
767 @param line line number of the issue (integer) |
816 @param line line number of the issue (integer) |
768 @param pos position inside line (integer) |
817 @param pos position inside line (integer) |
769 @return flag indicating an applied fix (boolean) and a message for |
818 @return value indicating an applied/deferred fix (-1, 0, 1), |
770 the fix (string) |
819 a message for the fix (string) and an ID for a deferred |
|
820 fix (integer) |
771 """ |
821 """ |
772 line = line - 1 |
822 line = line - 1 |
773 text = self.__source[line] |
823 text = self.__source[line] |
774 left = text[:pos].rstrip(' \t#') |
824 left = text[:pos].rstrip(' \t#') |
775 right = text[pos:].lstrip(' \t#') |
825 right = text[pos:].lstrip(' \t#') |
776 newText = left + (" # " + right if right.strip() else right) |
826 newText = left + (" # " + right if right.strip() else right) |
777 self.__source[line] = newText |
827 self.__source[line] = newText |
778 return (True, self.trUtf8("Whitespace around comment sign corrected.")) |
828 return (1, self.trUtf8("Whitespace around comment sign corrected."), 0) |
779 |
829 |
780 def __fixE301(self, code, line, pos, apply=False): |
830 def __fixE301(self, code, line, pos, apply=False): |
781 """ |
831 """ |
782 Private method to fix the need for one blank line (E301). |
832 Private method to fix the need for one blank line (E301). |
783 |
833 |
784 @param code code of the issue (string) |
834 @param code code of the issue (string) |
785 @param line line number of the issue (integer) |
835 @param line line number of the issue (integer) |
786 @param pos position inside line (integer) |
836 @param pos position inside line (integer) |
787 @keyparam apply flag indicating, that the fix should be applied |
837 @keyparam apply flag indicating, that the fix should be applied |
788 (boolean) |
838 (boolean) |
789 @return flag indicating an applied fix (boolean) and a message for |
839 @return value indicating an applied/deferred fix (-1, 0, 1), |
790 the fix (string) |
840 a message for the fix (string) and an ID for a deferred |
|
841 fix (integer) |
791 """ |
842 """ |
792 if apply: |
843 if apply: |
793 self.__source.insert(line - 1, self.__getEol()) |
844 self.__source.insert(line - 1, self.__getEol()) |
794 else: |
845 return (1, self.trUtf8("One blank line inserted."), 0) |
795 self.__stack.append((code, line, pos)) |
846 else: |
796 return (True, self.trUtf8("One blank line inserted.")) |
847 id = self.__getID() |
|
848 self.__stack.append((id, code, line, pos)) |
|
849 return (-1, "", id) |
797 |
850 |
798 def __fixE302(self, code, line, pos, apply=False): |
851 def __fixE302(self, code, line, pos, apply=False): |
799 """ |
852 """ |
800 Private method to fix the need for two blank lines (E302). |
853 Private method to fix the need for two blank lines (E302). |
801 |
854 |
802 @param code code of the issue (string) |
855 @param code code of the issue (string) |
803 @param line line number of the issue (integer) |
856 @param line line number of the issue (integer) |
804 @param pos position inside line (integer) |
857 @param pos position inside line (integer) |
805 @keyparam apply flag indicating, that the fix should be applied |
858 @keyparam apply flag indicating, that the fix should be applied |
806 (boolean) |
859 (boolean) |
807 @return flag indicating an applied fix (boolean) and a message for |
860 @return value indicating an applied/deferred fix (-1, 0, 1), |
808 the fix (string) |
861 a message for the fix (string) and an ID for a deferred |
809 """ |
862 fix (integer) |
810 # count blank lines |
863 """ |
811 index = line - 1 |
|
812 blanks = 0 |
|
813 while index: |
|
814 if self.__source[index - 1].strip() == "": |
|
815 blanks += 1 |
|
816 index -= 1 |
|
817 else: |
|
818 break |
|
819 delta = blanks - 2 |
|
820 |
|
821 if apply: |
864 if apply: |
|
865 # count blank lines |
|
866 index = line - 1 |
|
867 blanks = 0 |
|
868 while index: |
|
869 if self.__source[index - 1].strip() == "": |
|
870 blanks += 1 |
|
871 index -= 1 |
|
872 else: |
|
873 break |
|
874 delta = blanks - 2 |
|
875 |
822 line -= 1 |
876 line -= 1 |
823 if delta < 0: |
877 if delta < 0: |
824 # insert blank lines (one or two) |
878 # insert blank lines (one or two) |
825 while delta < 0: |
879 while delta < 0: |
826 self.__source.insert(line, self.__getEol()) |
880 self.__source.insert(line, self.__getEol()) |
829 # delete superfluous blank lines |
883 # delete superfluous blank lines |
830 while delta > 0: |
884 while delta > 0: |
831 del self.__source[line - 1] |
885 del self.__source[line - 1] |
832 line -= 1 |
886 line -= 1 |
833 delta -= 1 |
887 delta -= 1 |
834 else: |
888 |
835 self.__stack.append((code, line, pos)) |
889 if delta < 0: |
836 |
890 msg = self.trUtf8("%n blank line(s) inserted.", "", -delta) |
837 if delta < 0: |
891 elif delta > 0: |
838 msg = self.trUtf8("%n blank line(s) inserted.", "", -delta) |
892 msg = self.trUtf8("%n superfluous lines removed", "", delta) |
839 elif delta > 0: |
893 else: |
840 msg = self.trUtf8("%n superfluous lines removed", "", delta) |
894 msg = "" |
841 else: |
895 return (1, msg, 0) |
842 msg = "" |
896 else: |
843 return (True, msg) |
897 id = self.__getID() |
|
898 self.__stack.append((id, code, line, pos)) |
|
899 return (-1, "", id) |
844 |
900 |
845 def __fixE303(self, code, line, pos, apply=False): |
901 def __fixE303(self, code, line, pos, apply=False): |
846 """ |
902 """ |
847 Private method to fix superfluous blank lines (E303). |
903 Private method to fix superfluous blank lines (E303). |
848 |
904 |
849 @param code code of the issue (string) |
905 @param code code of the issue (string) |
850 @param line line number of the issue (integer) |
906 @param line line number of the issue (integer) |
851 @param pos position inside line (integer) |
907 @param pos position inside line (integer) |
852 @keyparam apply flag indicating, that the fix should be applied |
908 @keyparam apply flag indicating, that the fix should be applied |
853 (boolean) |
909 (boolean) |
854 @return flag indicating an applied fix (boolean) and a message for |
910 @return value indicating an applied/deferred fix (-1, 0, 1), |
855 the fix (string) |
911 a message for the fix (string) and an ID for a deferred |
|
912 fix (integer) |
856 """ |
913 """ |
857 if apply: |
914 if apply: |
858 index = line - 3 |
915 index = line - 3 |
859 while index: |
916 while index: |
860 if self.__source[index].strip() == "": |
917 if self.__source[index].strip() == "": |
861 del self.__source[index] |
918 del self.__source[index] |
862 index -= 1 |
919 index -= 1 |
863 else: |
920 else: |
864 break |
921 break |
865 else: |
922 return (1, self.trUtf8("Superfluous blank lines removed."), 0) |
866 self.__stack.append((code, line, pos)) |
923 else: |
867 return (True, self.trUtf8("Superfluous blank lines removed.")) |
924 id = self.__getID() |
|
925 self.__stack.append((id, code, line, pos)) |
|
926 return (-1, "", id) |
868 |
927 |
869 def __fixE304(self, code, line, pos, apply=False): |
928 def __fixE304(self, code, line, pos, apply=False): |
870 """ |
929 """ |
871 Private method to fix superfluous blank lines after a function |
930 Private method to fix superfluous blank lines after a function |
872 decorator (E304). |
931 decorator (E304). |
874 @param code code of the issue (string) |
933 @param code code of the issue (string) |
875 @param line line number of the issue (integer) |
934 @param line line number of the issue (integer) |
876 @param pos position inside line (integer) |
935 @param pos position inside line (integer) |
877 @keyparam apply flag indicating, that the fix should be applied |
936 @keyparam apply flag indicating, that the fix should be applied |
878 (boolean) |
937 (boolean) |
879 @return flag indicating an applied fix (boolean) and a message for |
938 @return value indicating an applied/deferred fix (-1, 0, 1), |
880 the fix (string) |
939 a message for the fix (string) and an ID for a deferred |
|
940 fix (integer) |
881 """ |
941 """ |
882 if apply: |
942 if apply: |
883 index = line - 2 |
943 index = line - 2 |
884 while index: |
944 while index: |
885 if self.__source[index].strip() == "": |
945 if self.__source[index].strip() == "": |
886 del self.__source[index] |
946 del self.__source[index] |
887 index -= 1 |
947 index -= 1 |
888 else: |
948 else: |
889 break |
949 break |
890 else: |
950 return ( |
891 self.__stack.append((code, line, pos)) |
951 1, |
892 return (True, self.trUtf8( |
952 self.trUtf8("Superfluous blank lines after function" |
893 "Superfluous blank lines after function decorator removed.")) |
953 " decorator removed."), |
|
954 0) |
|
955 else: |
|
956 id = self.__getID() |
|
957 self.__stack.append((id, code, line, pos)) |
|
958 return (-1, "", id) |
894 |
959 |
895 def __fixE401(self, code, line, pos, apply=False): |
960 def __fixE401(self, code, line, pos, apply=False): |
896 """ |
961 """ |
897 Private method to fix multiple imports on one line (E401). |
962 Private method to fix multiple imports on one line (E401). |
898 |
963 |
899 @param code code of the issue (string) |
964 @param code code of the issue (string) |
900 @param line line number of the issue (integer) |
965 @param line line number of the issue (integer) |
901 @param pos position inside line (integer) |
966 @param pos position inside line (integer) |
902 @keyparam apply flag indicating, that the fix should be applied |
967 @keyparam apply flag indicating, that the fix should be applied |
903 (boolean) |
968 (boolean) |
904 @return flag indicating an applied fix (boolean) and a message for |
969 @return value indicating an applied/deferred fix (-1, 0, 1), |
905 the fix (string) |
970 a message for the fix (string) and an ID for a deferred |
|
971 fix (integer) |
906 """ |
972 """ |
907 if apply: |
973 if apply: |
908 line = line - 1 |
974 line = line - 1 |
909 text = self.__source[line] |
975 text = self.__source[line] |
910 if not text.lstrip().startswith("import"): |
976 if not text.lstrip().startswith("import"): |
911 return (False, "") |
977 return (0, "", 0) |
912 |
978 |
913 # pep8 (1.3.1) reports false positive if there is an import |
979 # pep8 (1.3.1) reports false positive if there is an import |
914 # statement followed by a semicolon and some unrelated |
980 # statement followed by a semicolon and some unrelated |
915 # statement with commas in it. |
981 # statement with commas in it. |
916 if ';' in text: |
982 if ';' in text: |
917 return (False, "") |
983 return (0, "", 0) |
918 |
984 |
919 newText = text[:pos].rstrip("\t ,") + self.__getEol() + \ |
985 newText = text[:pos].rstrip("\t ,") + self.__getEol() + \ |
920 self.__getIndent(text) + "import " + text[pos:].lstrip("\t ,") |
986 self.__getIndent(text) + "import " + text[pos:].lstrip("\t ,") |
921 self.__source[line] = newText |
987 self.__source[line] = newText |
922 else: |
988 return (1, self.trUtf8("Imports were put on separate lines."), 0) |
923 self.__stack.append((code, line, pos)) |
989 else: |
924 return (True, self.trUtf8("Imports were put on separate lines.")) |
990 id = self.__getID() |
|
991 self.__stack.append((id, code, line, pos)) |
|
992 return (-1, "", id) |
925 |
993 |
926 def __fixE501(self, code, line, pos, apply=False): |
994 def __fixE501(self, code, line, pos, apply=False): |
927 """ |
995 """ |
928 Private method to fix the long lines by breaking them (E501). |
996 Private method to fix the long lines by breaking them (E501). |
929 |
997 |
930 @param code code of the issue (string) |
998 @param code code of the issue (string) |
931 @param line line number of the issue (integer) |
999 @param line line number of the issue (integer) |
932 @param pos position inside line (integer) |
1000 @param pos position inside line (integer) |
933 @keyparam apply flag indicating, that the fix should be applied |
1001 @keyparam apply flag indicating, that the fix should be applied |
934 (boolean) |
1002 (boolean) |
935 @return flag indicating an applied fix (boolean) and a message for |
1003 @return value indicating an applied/deferred fix (-1, 0, 1), |
936 the fix (string) |
1004 a message for the fix (string) and an ID for a deferred |
|
1005 fix (integer) |
937 """ |
1006 """ |
938 multilineStringLines, docStringLines = self.__multilineStringLines() |
1007 multilineStringLines, docStringLines = self.__multilineStringLines() |
939 if apply: |
1008 if apply: |
940 isDocString = line in docStringLines |
1009 isDocString = line in docStringLines |
941 line = line - 1 |
1010 line = line - 1 |
955 if changed: |
1024 if changed: |
956 if newText != text: |
1025 if newText != text: |
957 self.__source[line] = newText |
1026 self.__source[line] = newText |
958 if newNextText and newNextText != nextText: |
1027 if newNextText and newNextText != nextText: |
959 self.__source[line + 1] = newNextText |
1028 self.__source[line + 1] = newNextText |
960 else: |
1029 return (1, self.trUtf8("Long lines have been shortened."), 0) |
961 self.__stack.append((code, line, pos)) |
1030 else: |
962 return (True, self.trUtf8("Long lines have been shortened.")) |
1031 return (0, "", 0) |
|
1032 else: |
|
1033 id = self.__getID() |
|
1034 self.__stack.append((id, code, line, pos)) |
|
1035 return (-1, "", id) |
963 |
1036 |
964 def __fixE502(self, code, line, pos): |
1037 def __fixE502(self, code, line, pos): |
965 """ |
1038 """ |
966 Private method to fix redundant backslash within brackets (E502). |
1039 Private method to fix redundant backslash within brackets (E502). |
967 |
1040 |
968 @param code code of the issue (string) |
1041 @param code code of the issue (string) |
969 @param line line number of the issue (integer) |
1042 @param line line number of the issue (integer) |
970 @param pos position inside line (integer) |
1043 @param pos position inside line (integer) |
971 @return flag indicating an applied fix (boolean) and a message for |
1044 @return value indicating an applied/deferred fix (-1, 0, 1), |
972 the fix (string) |
1045 a message for the fix (string) and an ID for a deferred |
|
1046 fix (integer) |
973 """ |
1047 """ |
974 self.__source[line - 1] = \ |
1048 self.__source[line - 1] = \ |
975 self.__source[line - 1].rstrip("\n\r \t\\") + self.__getEol() |
1049 self.__source[line - 1].rstrip("\n\r \t\\") + self.__getEol() |
976 return (True, self.trUtf8("Redundant backslash in brackets removed.")) |
1050 return (1, self.trUtf8("Redundant backslash in brackets removed."), 0) |
977 |
1051 |
978 def __fixE701(self, code, line, pos, apply=False): |
1052 def __fixE701(self, code, line, pos, apply=False): |
979 """ |
1053 """ |
980 Private method to fix colon-separated compund statements (E701). |
1054 Private method to fix colon-separated compund statements (E701). |
981 |
1055 |
982 @param code code of the issue (string) |
1056 @param code code of the issue (string) |
983 @param line line number of the issue (integer) |
1057 @param line line number of the issue (integer) |
984 @param pos position inside line (integer) |
1058 @param pos position inside line (integer) |
985 @keyparam apply flag indicating, that the fix should be applied |
1059 @keyparam apply flag indicating, that the fix should be applied |
986 (boolean) |
1060 (boolean) |
987 @return flag indicating an applied fix (boolean) and a message for |
1061 @return value indicating an applied/deferred fix (-1, 0, 1), |
988 the fix (string) |
1062 a message for the fix (string) and an ID for a deferred |
|
1063 fix (integer) |
989 """ |
1064 """ |
990 if apply: |
1065 if apply: |
991 line = line - 1 |
1066 line = line - 1 |
992 text = self.__source[line] |
1067 text = self.__source[line] |
993 pos = pos + 1 |
1068 pos = pos + 1 |
994 |
1069 |
995 newText = text[:pos] + self.__getEol() + self.__getIndent(text) + \ |
1070 newText = text[:pos] + self.__getEol() + self.__getIndent(text) + \ |
996 self.__indentWord + text[pos:].lstrip("\n\r \t\\") + \ |
1071 self.__indentWord + text[pos:].lstrip("\n\r \t\\") + \ |
997 self.__getEol() |
1072 self.__getEol() |
998 self.__source[line] = newText |
1073 self.__source[line] = newText |
999 else: |
1074 return (1, self.trUtf8("Compound statement corrected."), 0) |
1000 self.__stack.append((code, line, pos)) |
1075 else: |
1001 return (True, self.trUtf8("Compound statement corrected.")) |
1076 id = self.__getID() |
|
1077 self.__stack.append((id, code, line, pos)) |
|
1078 return (-1, "", id) |
1002 |
1079 |
1003 def __fixE702(self, code, line, pos, apply=False): |
1080 def __fixE702(self, code, line, pos, apply=False): |
1004 """ |
1081 """ |
1005 Private method to fix semicolon-separated compound statements |
1082 Private method to fix semicolon-separated compound statements |
1006 (E702, E703). |
1083 (E702, E703). |
1025 self.__source[line] = text.rstrip("\n\r \t;") + self.__getEol() |
1103 self.__source[line] = text.rstrip("\n\r \t;") + self.__getEol() |
1026 else: |
1104 else: |
1027 first = text[:pos].rstrip("\n\r \t;") + self.__getEol() |
1105 first = text[:pos].rstrip("\n\r \t;") + self.__getEol() |
1028 second = text[pos:].lstrip("\n\r \t;") |
1106 second = text[pos:].lstrip("\n\r \t;") |
1029 self.__source[line] = first + self.__getIndent(text) + second |
1107 self.__source[line] = first + self.__getIndent(text) + second |
1030 else: |
1108 return (1, self.trUtf8("Compound statement corrected."), 0) |
1031 self.__stack.append((code, line, pos)) |
1109 else: |
1032 return (True, self.trUtf8("Compound statement corrected.")) |
1110 id = self.__getID() |
|
1111 self.__stack.append((id, code, line, pos)) |
|
1112 return (-1, "", id) |
1033 |
1113 |
1034 def __fixE711(self, code, line, pos): |
1114 def __fixE711(self, code, line, pos): |
1035 """ |
1115 """ |
1036 Private method to fix comparison with None (E711, E712). |
1116 Private method to fix comparison with None (E711, E712). |
1037 |
1117 |
1038 @param code code of the issue (string) |
1118 @param code code of the issue (string) |
1039 @param line line number of the issue (integer) |
1119 @param line line number of the issue (integer) |
1040 @param pos position inside line (integer) |
1120 @param pos position inside line (integer) |
1041 @return flag indicating an applied fix (boolean) and a message for |
1121 @return value indicating an applied/deferred fix (-1, 0, 1), |
1042 the fix (string) |
1122 a message for the fix (string) and an ID for a deferred |
|
1123 fix (integer) |
1043 """ |
1124 """ |
1044 line = line - 1 |
1125 line = line - 1 |
1045 text = self.__source[line] |
1126 text = self.__source[line] |
1046 |
1127 |
1047 rightPos = pos + 2 |
1128 rightPos = pos + 2 |
1048 if rightPos >= len(text): |
1129 if rightPos >= len(text): |
1049 return (False, "") |
1130 return (0, "", 0) |
1050 |
1131 |
1051 left = text[:pos].rstrip() |
1132 left = text[:pos].rstrip() |
1052 center = text[pos:rightPos] |
1133 center = text[pos:rightPos] |
1053 right = text[rightPos:].lstrip() |
1134 right = text[rightPos:].lstrip() |
1054 |
1135 |
1055 if not right.startswith(("None", "True", "False")): |
1136 if not right.startswith(("None", "True", "False")): |
1056 return (False, "") |
1137 return (0, "", 0) |
1057 |
1138 |
1058 if center.strip() == "==": |
1139 if center.strip() == "==": |
1059 center = "is" |
1140 center = "is" |
1060 elif center.strip() == "!=": |
1141 elif center.strip() == "!=": |
1061 center = "is not" |
1142 center = "is not" |
1062 else: |
1143 else: |
1063 return (False, "") |
1144 return (0, "", 0) |
1064 |
1145 |
1065 self.__source[line] = " ".join([left, center, right]) |
1146 self.__source[line] = " ".join([left, center, right]) |
1066 return (True, self.trUtf8("Comparison to None/True/False corrected.")) |
1147 return (1, self.trUtf8("Comparison to None/True/False corrected."), 0) |
1067 |
1148 |
1068 def __fixW291(self, code, line, pos): |
1149 def __fixW291(self, code, line, pos): |
1069 """ |
1150 """ |
1070 Private method to fix trailing whitespace (W291, W293). |
1151 Private method to fix trailing whitespace (W291, W293). |
1071 |
1152 |
1072 @param code code of the issue (string) |
1153 @param code code of the issue (string) |
1073 @param line line number of the issue (integer) |
1154 @param line line number of the issue (integer) |
1074 @param pos position inside line (integer) |
1155 @param pos position inside line (integer) |
1075 @return flag indicating an applied fix (boolean) and a message for |
1156 @return value indicating an applied/deferred fix (-1, 0, 1), |
1076 the fix (string) |
1157 a message for the fix (string) and an ID for a deferred |
|
1158 fix (integer) |
1077 """ |
1159 """ |
1078 self.__source[line - 1] = re.sub(r'[\t ]+(\r?)$', r"\1", |
1160 self.__source[line - 1] = re.sub(r'[\t ]+(\r?)$', r"\1", |
1079 self.__source[line - 1]) |
1161 self.__source[line - 1]) |
1080 return (True, self.trUtf8("Whitespace stripped from end of line.")) |
1162 return (1, self.trUtf8("Whitespace stripped from end of line."), 0) |
1081 |
1163 |
1082 def __fixW292(self, code, line, pos): |
1164 def __fixW292(self, code, line, pos): |
1083 """ |
1165 """ |
1084 Private method to fix a missing newline at the end of file (W292). |
1166 Private method to fix a missing newline at the end of file (W292). |
1085 |
1167 |
1086 @param code code of the issue (string) |
1168 @param code code of the issue (string) |
1087 @param line line number of the issue (integer) |
1169 @param line line number of the issue (integer) |
1088 @param pos position inside line (integer) |
1170 @param pos position inside line (integer) |
1089 @return flag indicating an applied fix (boolean) and a message for |
1171 @return value indicating an applied/deferred fix (-1, 0, 1), |
1090 the fix (string) |
1172 a message for the fix (string) and an ID for a deferred |
|
1173 fix (integer) |
1091 """ |
1174 """ |
1092 self.__source[line - 1] += self.__getEol() |
1175 self.__source[line - 1] += self.__getEol() |
1093 return (True, self.trUtf8("newline added to end of file.")) |
1176 return (1, self.trUtf8("newline added to end of file."), 0) |
1094 |
1177 |
1095 def __fixW391(self, code, line, pos): |
1178 def __fixW391(self, code, line, pos): |
1096 """ |
1179 """ |
1097 Private method to fix trailing blank lines (W391). |
1180 Private method to fix trailing blank lines (W391). |
1098 |
1181 |
1099 @param code code of the issue (string) |
1182 @param code code of the issue (string) |
1100 @param line line number of the issue (integer) |
1183 @param line line number of the issue (integer) |
1101 @param pos position inside line (integer) |
1184 @param pos position inside line (integer) |
1102 @return flag indicating an applied fix (boolean) and a message for |
1185 @return value indicating an applied/deferred fix (-1, 0, 1), |
1103 the fix (string) |
1186 a message for the fix (string) and an ID for a deferred |
|
1187 fix (integer) |
1104 """ |
1188 """ |
1105 index = line - 1 |
1189 index = line - 1 |
1106 while index: |
1190 while index: |
1107 if self.__source[index].strip() == "": |
1191 if self.__source[index].strip() == "": |
1108 del self.__source[index] |
1192 del self.__source[index] |
1109 index -= 1 |
1193 index -= 1 |
1110 else: |
1194 else: |
1111 break |
1195 break |
1112 return (True, self.trUtf8( |
1196 return (1, self.trUtf8( |
1113 "Superfluous trailing blank lines removed from end of file.")) |
1197 "Superfluous trailing blank lines removed from end of file."), 0) |
1114 |
1198 |
1115 def __fixW603(self, code, line, pos): |
1199 def __fixW603(self, code, line, pos): |
1116 """ |
1200 """ |
1117 Private method to fix the not equal notation (W603). |
1201 Private method to fix the not equal notation (W603). |
1118 |
1202 |
1119 @param code code of the issue (string) |
1203 @param code code of the issue (string) |
1120 @param line line number of the issue (integer) |
1204 @param line line number of the issue (integer) |
1121 @param pos position inside line (integer) |
1205 @param pos position inside line (integer) |
1122 @return flag indicating an applied fix (boolean) and a message for |
1206 @return value indicating an applied/deferred fix (-1, 0, 1), |
1123 the fix (string) |
1207 a message for the fix (string) and an ID for a deferred |
|
1208 fix (integer) |
1124 """ |
1209 """ |
1125 self.__source[line - 1] = self.__source[line - 1].replace("<>", "!=") |
1210 self.__source[line - 1] = self.__source[line - 1].replace("<>", "!=") |
1126 return (True, self.trUtf8("'<>' replaced by '!='.")) |
1211 return (1, self.trUtf8("'<>' replaced by '!='."), 0) |
1127 |
1212 |
1128 |
1213 |
1129 class Pep8Reindenter(object): |
1214 class Pep8Reindenter(object): |
1130 """ |
1215 """ |
1131 Class to reindent badly-indented code to uniformly use four-space |
1216 Class to reindent badly-indented code to uniformly use four-space |