Thu, 25 Nov 2021 17:48:51 +0100
Continued implementing a checker for import statements.
--- a/eric7/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleChecker.py Wed Nov 24 20:08:25 2021 +0100 +++ b/eric7/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleChecker.py Thu Nov 25 17:48:51 2021 +0100 @@ -14,18 +14,19 @@ import contextlib import pycodestyle + +from Complexity.ComplexityChecker import ComplexityChecker +from DocStyle.DocStyleChecker import DocStyleChecker +from Imports.ImportsChecker import ImportsChecker +from Miscellaneous.MiscellaneousChecker import MiscellaneousChecker from Naming.NamingStyleChecker import NamingStyleChecker +from PathLib.PathlibChecker import PathlibChecker +from Security.SecurityChecker import SecurityChecker +from Simplify.SimplifyChecker import SimplifyChecker # register the name checker pycodestyle.register_check(NamingStyleChecker, NamingStyleChecker.Codes) -from DocStyle.DocStyleChecker import DocStyleChecker -from Miscellaneous.MiscellaneousChecker import MiscellaneousChecker -from Complexity.ComplexityChecker import ComplexityChecker -from Security.SecurityChecker import SecurityChecker -from PathLib.PathlibChecker import PathlibChecker -from Simplify.SimplifyChecker import SimplifyChecker - def initService(): """ @@ -464,6 +465,14 @@ simplifyChecker.run() stats.update(simplifyChecker.counters) errors += simplifyChecker.errors + + # check import statements + importsChecker = ImportsChecker( + source, filename, tree, select, ignore, [], repeatMessages, {}) + # TODO: add arguments + importsChecker.run() + stats.update(importsChecker.counters) + errors += importsChecker.errors elif syntaxError: errors = [syntaxError]
--- a/eric7/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.py Wed Nov 24 20:08:25 2021 +0100 +++ b/eric7/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.py Thu Nov 25 17:48:51 2021 +0100 @@ -29,6 +29,7 @@ import Utilities from . import pycodestyle +from . import CodeStyleCheckerUtilities from .Miscellaneous.MiscellaneousDefaults import ( MiscellaneousCheckerDefaultArgs @@ -76,6 +77,9 @@ "E": QCoreApplication.translate( "CheckerCategories", "Errors"), + "I": QCoreApplication.translate( + "CheckerCategories", + "Imports"), "M": QCoreApplication.translate( "CheckerCategories", "Miscellaneous"), @@ -300,30 +304,37 @@ result["display"] ] ) - if msgCode.startswith(("W", "-", "C", "M")): - itm.setIcon(1, UI.PixmapCache.getIcon("warning")) - elif msgCode.startswith(("A", "N")): - itm.setIcon(1, UI.PixmapCache.getIcon("namingError")) - elif msgCode.startswith("D"): - itm.setIcon(1, UI.PixmapCache.getIcon("docstringError")) - elif msgCode.startswith("P"): - itm.setIcon(1, UI.PixmapCache.getIcon("dirClosed")) - elif msgCode.startswith("Y"): - itm.setIcon(1, UI.PixmapCache.getIcon("filePython")) - elif msgCode.startswith("S"): - if "severity" in result: - if result["severity"] == "H": - itm.setIcon(1, UI.PixmapCache.getIcon("securityLow")) - elif result["severity"] == "M": - itm.setIcon(1, UI.PixmapCache.getIcon("securityMedium")) - elif result["severity"] == "L": - itm.setIcon(1, UI.PixmapCache.getIcon("securityHigh")) - else: - itm.setIcon(1, UI.PixmapCache.getIcon("securityLow")) - else: - itm.setIcon(1, UI.PixmapCache.getIcon("securityLow")) - else: - itm.setIcon(1, UI.PixmapCache.getIcon("syntaxError")) + + CodeStyleCheckerUtilities.setItemIcon( + itm, 1, msgCode, result.get("severity")) +# # TODO: extract this as a method +# if msgCode.startswith(("W", "-", "C", "M")): +# itm.setIcon(1, UI.PixmapCache.getIcon("warning")) +# elif msgCode.startswith(("A", "N")): +# itm.setIcon(1, UI.PixmapCache.getIcon("namingError")) +# elif msgCode.startswith("D"): +# itm.setIcon(1, UI.PixmapCache.getIcon("docstringError")) +# elif msgCode.startswith("I"): +# itm.setIcon(1, UI.PixmapCache.getIcon("imports")) +# elif msgCode.startswith("P"): +# itm.setIcon(1, UI.PixmapCache.getIcon("dirClosed")) +# elif msgCode.startswith("Y"): +# itm.setIcon(1, UI.PixmapCache.getIcon("filePython")) +# elif msgCode.startswith("S"): +# if "severity" in result: +# if result["severity"] == "H": +# itm.setIcon(1, UI.PixmapCache.getIcon("securityLow")) +# elif result["severity"] == "M": +# itm.setIcon(1, UI.PixmapCache.getIcon("securityMedium")) +# elif result["severity"] == "L": +# itm.setIcon(1, UI.PixmapCache.getIcon("securityHigh")) +# else: +# itm.setIcon(1, UI.PixmapCache.getIcon("securityLow")) +# else: +# itm.setIcon(1, UI.PixmapCache.getIcon("securityLow")) +# else: +# itm.setIcon(1, UI.PixmapCache.getIcon("syntaxError")) + if result["fixed"]: itm.setIcon(0, UI.PixmapCache.getIcon("issueFixed")) elif (
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eric7/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerUtilities.py Thu Nov 25 17:48:51 2021 +0100 @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2021 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing utility functions for the code style checker dialogs. +""" + +import UI.PixmapCache + + +def setItemIcon(itm, column, msgCode, severity=None): + """ + Function to set the icon of the passed message item. + + @param itm reference to the message item + @type QTreeWidgetItem + @param column column for the icon + @type int + @param msgCode message code + @type str + @param severity severity for message code 'S' (defaults to None) + @type str (optional) + """ + if msgCode.startswith(("W", "-", "C", "M")): + itm.setIcon(column, UI.PixmapCache.getIcon("warning")) + elif msgCode.startswith("E"): + itm.setIcon(column, UI.PixmapCache.getIcon("syntaxError")) + elif msgCode.startswith(("A", "N")): + itm.setIcon(column, UI.PixmapCache.getIcon("namingError")) + elif msgCode.startswith("D"): + itm.setIcon(column, UI.PixmapCache.getIcon("docstringError")) + elif msgCode.startswith("I"): + itm.setIcon(column, UI.PixmapCache.getIcon("imports")) + elif msgCode.startswith("P"): + itm.setIcon(column, UI.PixmapCache.getIcon("dirClosed")) + elif msgCode.startswith("Y"): + itm.setIcon(column, UI.PixmapCache.getIcon("filePython")) + elif msgCode.startswith("S"): + if severity is None: + itm.setIcon(column, UI.PixmapCache.getIcon("securityLow")) + else: + if severity == "H": + itm.setIcon(column, UI.PixmapCache.getIcon("securityLow")) + elif severity == "M": + itm.setIcon(column, UI.PixmapCache.getIcon("securityMedium")) + elif severity == "L": + itm.setIcon(column, UI.PixmapCache.getIcon("securityHigh")) + else: + itm.setIcon(column, UI.PixmapCache.getIcon("securityLow")) + else: + # unknown category prefix => warning + itm.setIcon(column, UI.PixmapCache.getIcon("warning"))
--- a/eric7/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCodeSelectionDialog.py Wed Nov 24 20:08:25 2021 +0100 +++ b/eric7/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCodeSelectionDialog.py Thu Nov 25 17:48:51 2021 +0100 @@ -16,7 +16,7 @@ from .translations import getMessageCodes, getTranslatedMessage -import UI.PixmapCache +from . import CodeStyleCheckerUtilities class CodeStyleCodeSelectionDialog(QDialog, Ui_CodeStyleCodeSelectionDialog): @@ -58,40 +58,25 @@ # filter by category selectableCodes = [x for x in selectableCodes if x[0] not in categories] - for code in sorted(selectableCodes): - message = getTranslatedMessage(code, [], example=True) + for msgCode in sorted(selectableCodes): + message = getTranslatedMessage(msgCode, [], example=True) if message is None: # try with extension for ext in ("L", "M", "H", "1"): - message = getTranslatedMessage("{0}.{1}".format(code, ext), - [], example=True) + message = getTranslatedMessage( + "{0}.{1}".format(msgCode, ext), [], example=True + ) if message is not None: break else: continue itm = QTreeWidgetItem(self.codeTable, [ - code, "\n".join(textWrapper.wrap(message))]) - if code.startswith(("W", "C", "M")): - itm.setIcon(0, UI.PixmapCache.getIcon("warning")) - elif code.startswith("E"): - itm.setIcon(0, UI.PixmapCache.getIcon("syntaxError")) - elif code.startswith(("A", "N")): - itm.setIcon(0, UI.PixmapCache.getIcon("namingError")) - elif code.startswith("D"): - itm.setIcon(0, UI.PixmapCache.getIcon("docstringError")) - elif code.startswith("S"): - itm.setIcon(0, UI.PixmapCache.getIcon("securityLow")) - elif code.startswith("P"): - itm.setIcon(0, UI.PixmapCache.getIcon("dirClosed")) - elif code.startswith("Y"): - itm.setIcon(0, UI.PixmapCache.getIcon("filePython")) - else: - # unknown category prefix => warning - itm.setIcon(0, UI.PixmapCache.getIcon("warning")) + msgCode, "\n".join(textWrapper.wrap(message))]) + CodeStyleCheckerUtilities.setItemIcon(itm, 0, msgCode) itm.setFlags(itm.flags() | Qt.ItemFlag.ItemIsUserCheckable) - if code in codeList: + if msgCode in codeList: itm.setCheckState(0, Qt.CheckState.Checked) - codeList.remove(code) + codeList.remove(msgCode) else: itm.setCheckState(0, Qt.CheckState.Unchecked) self.codeTable.resizeColumnToContents(0)
--- a/eric7/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleStatisticsDialog.py Wed Nov 24 20:08:25 2021 +0100 +++ b/eric7/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleStatisticsDialog.py Thu Nov 25 17:48:51 2021 +0100 @@ -15,9 +15,9 @@ from .translations import getTranslatedMessage -from .Ui_CodeStyleStatisticsDialog import Ui_CodeStyleStatisticsDialog +from . import CodeStyleCheckerUtilities -import UI.PixmapCache +from .Ui_CodeStyleStatisticsDialog import Ui_CodeStyleStatisticsDialog class CodeStyleStatisticsDialog(QDialog, Ui_CodeStyleStatisticsDialog): @@ -25,11 +25,11 @@ Class implementing a dialog showing statistical data for the last code style checker run. """ - def __init__(self, statistics, parent=None): + def __init__(self, statisticData, parent=None): """ Constructor - @param statistics dictionary with the statistical data + @param statisticData dictionary with the statistical data @type dict @param parent reference to the parent widget @type QWidget @@ -37,7 +37,7 @@ super().__init__(parent) self.setupUi(self) - stats = statistics.copy() + stats = statisticData.copy() filesCount = stats["_FilesCount"] filesIssues = stats["_FilesIssues"] fixesCount = stats["_IssuesFixed"] @@ -52,15 +52,15 @@ textWrapper = textwrap.TextWrapper(width=80) - for code in sorted(stats.keys()): - message = getTranslatedMessage(code, [], example=True) + for msgCode in sorted(stats.keys()): + message = getTranslatedMessage(msgCode, [], example=True) if message is None: continue - self.__createItem(stats[code], code, + self.__createItem(stats[msgCode], msgCode, "\n".join(textWrapper.wrap(message))) - totalIssues += stats[code]["total"] - ignoresCount += stats[code]["ignored"] + totalIssues += stats[msgCode]["total"] + ignoresCount += stats[msgCode]["ignored"] self.totalIssues.setText( self.tr("%n issue(s) found", "", totalIssues)) @@ -79,35 +79,22 @@ self.statisticsList.resizeColumnToContents(1) self.statisticsList.resizeColumnToContents(2) - def __createItem(self, counts, code, message): + def __createItem(self, counts, msgCode, message): """ Private method to create an entry in the result list. @param counts dictionary containing the total and ignored occurrences of the issue @type dict - @param code of a code style issue message + @param msgCode code of a code style issue message @type str @param message code style issue message to be shown @type str """ itm = QTreeWidgetItem(self.statisticsList, [ - code, "{0:6d}".format(counts["total"] - counts["ignored"]), + msgCode, "{0:6d}".format(counts["total"] - counts["ignored"]), "{0:6d}".format(counts["ignored"]), message]) - if code.startswith(("W", "C", "M")): - itm.setIcon(0, UI.PixmapCache.getIcon("warning")) - elif code.startswith("E"): - itm.setIcon(0, UI.PixmapCache.getIcon("syntaxError")) - elif code.startswith("N"): - itm.setIcon(0, UI.PixmapCache.getIcon("namingError")) - elif code.startswith("D"): - itm.setIcon(0, UI.PixmapCache.getIcon("docstringError")) - elif code.startswith("S"): - itm.setIcon(0, UI.PixmapCache.getIcon("securityLow")) - elif code.startswith("P"): - itm.setIcon(0, UI.PixmapCache.getIcon("dirClosed")) - elif code.startswith("Y"): - itm.setIcon(0, UI.PixmapCache.getIcon("filePython")) + CodeStyleCheckerUtilities.setItemIcon(itm, 0, msgCode) itm.setTextAlignment( 0, Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignVCenter)
--- a/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Imports/translations.py Wed Nov 24 20:08:25 2021 +0100 +++ b/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Imports/translations.py Thu Nov 25 17:48:51 2021 +0100 @@ -14,6 +14,6 @@ } -__importsMessagesSampleArgs = { +_importsMessagesSampleArgs = { }
--- a/eric7/Plugins/CheckerPlugins/CodeStyleChecker/translations.py Wed Nov 24 20:08:25 2021 +0100 +++ b/eric7/Plugins/CheckerPlugins/CodeStyleChecker/translations.py Thu Nov 25 17:48:51 2021 +0100 @@ -21,6 +21,9 @@ from .DocStyle.translations import ( _docStyleMessages, _docStyleMessagesSampleArgs ) +from .Imports.translations import ( + _importsMessages, _importsMessagesSampleArgs +) from .Miscellaneous.translations import ( _miscellaneousMessages, _miscellaneousMessagesSampleArgs ) @@ -503,6 +506,7 @@ "C": _complexityMessages, "D": _docStyleMessages, "E": _pycodestyleErrorMessages, + "I": _importsMessages, "M": _miscellaneousMessages, "N": _namingStyleMessages, "P": _pathlibMessages, @@ -518,6 +522,7 @@ "C": _complexityMessagesSampleArgs, "D": _docStyleMessagesSampleArgs, "E": _pycodestyleErrorMessagesSampleArgs, + "I": _importsMessagesSampleArgs, "M": _miscellaneousMessagesSampleArgs, "S": _securityMessagesSampleArgs, "W": _pycodestyleWarningMessagesSampleArgs,
--- a/eric7/Plugins/PluginCodeStyleChecker.py Wed Nov 24 20:08:25 2021 +0100 +++ b/eric7/Plugins/PluginCodeStyleChecker.py Thu Nov 25 17:48:51 2021 +0100 @@ -199,7 +199,7 @@ def __translateStyleCheck(self, fn, codeStyleCheckerStats, results): """ - Private slot called after perfoming a style check on one file. + Private slot called after performing a style check on one file. @param fn filename of the just checked file @type str