--- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/MiscellaneousChecker.py Thu Jun 27 19:05:28 2019 +0200 +++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/MiscellaneousChecker.py Thu Jun 27 19:21:23 2019 +0200 @@ -13,6 +13,7 @@ import itertools from string import Formatter from collections import defaultdict +import tokenize def composeCallPath(node): @@ -37,36 +38,62 @@ Class implementing a checker for miscellaneous checks. """ Codes = [ + ## Coding line "M101", "M102", + + ## Copyright "M111", "M112", + + ## Shadowed Builtins "M131", "M132", + ## Comprehensions "M191", "M192", "M193", "M194", "M195", "M196", "M197", "M198", + ## Dictionaries with sorted keys "M201", + ## Bugbear "M501", "M502", "M503", "M504", "M505", "M506", "M507", "M508", "M509", "M511", "M512", "M513", "M521", "M522", "M523", "M524", + ## Format Strings "M601", "M611", "M612", "M613", "M621", "M622", "M623", "M624", "M625", "M631", "M632", + + ## Logging "M651", "M652", "M653", "M654", "M655", + ## Future statements "M701", "M702", + + ## Gettext "M711", + ## print "M801", + + ## one element tuple "M811", + + ## Mutable Defaults "M821", "M822", + + ## return statements "M831", "M832", "M833", "M834", + ## line continuation + "M841", + + ## commented code "M891", + ## syntax error "M901", ] @@ -144,10 +171,11 @@ (self.__checkFuture, ("M701", "M702")), (self.__checkGettext, ("M711",)), (self.__checkPrintStatements, ("M801",)), - (self.__checkTuple, ("M811", )), + (self.__checkTuple, ("M811",)), (self.__checkMutableDefault, ("M821", "M822")), (self.__checkReturn, ("M831", "M832", "M833", "M834")), - (self.__checkCommentedCode, ("M891")), + (self.__checkLineContinuation, ("M841",)), + (self.__checkCommentedCode, ("M891",)), ] self.__defaultArgs = { @@ -341,6 +369,30 @@ source, aggressive=aggressive): self.__error(markedLine - 1, 0, "M891") + def __checkLineContinuation(self): + """ + Private method to check öine continuation using '\'. + """ + # generate source lines without comments + linesIterator = iter(self.__source) + tokens = tokenize.generate_tokens(lambda: next(linesIterator)) + comments = [token for token in tokens if token[0] == tokenize.COMMENT] + stripped = self.__source[:] + for comment in comments: + lineno = comment[3][0] + start = comment[2][1] + stop = comment[3][1] + content = stripped[lineno - 1] + withoutComment = content[:start] + content[stop:] + stripped[lineno - 1] = withoutComment.rstrip() + + # perform check with 'cleaned' source + for lineIndex, line in enumerate(stripped): + strippedLine = line.strip() + if (strippedLine.endswith('\\') and + not strippedLine.startswith(('assert', 'with'))): + self.__error(lineIndex, len(line), "M841") + def __checkPrintStatements(self): """ Private method to check for print statements.