Fri, 17 Mar 2017 19:09:39 +0100
Made the built-ins checker configurable.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleAddBuiltinIgnoreDialog.py Fri Mar 17 19:09:39 2017 +0100 @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2017 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to enter the data for a built-in assignment to +be ignored. +""" + +from PyQt5.QtCore import pyqtSlot +from PyQt5.QtWidgets import QDialog, QDialogButtonBox + +from .Ui_CodeStyleAddBuiltinIgnoreDialog import \ + Ui_CodeStyleAddBuiltinIgnoreDialog + + +class CodeStyleAddBuiltinIgnoreDialog(QDialog, + Ui_CodeStyleAddBuiltinIgnoreDialog): + """ + Class implementing a dialog to enter the data for a built-in assignment to + be ignored. + """ + def __init__(self, parent=None): + """ + Constructor + + @param parent reference to the parent widget + @type QWidget + """ + super(CodeStyleAddBuiltinIgnoreDialog, self).__init__(parent) + self.setupUi(self) + + self.__updateOkButton + + msh = self.minimumSizeHint() + self.resize(max(self.width(), msh.width()), msh.height()) + + def __updateOkButton(self): + """ + Private slot to set the state of the OK button. + """ + self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( + bool(self.leftEdit.text()) and + bool(self.rightEdit.text())) + + @pyqtSlot(str) + def on_leftEdit_textChanged(self, txt): + """ + Private slot to handle a change of the text of the left side edit. + + @param txt text of the line edit + @type str + """ + self.__updateOkButton() + + @pyqtSlot(str) + def on_rightEdit_textChanged(self, txt): + """ + Private slot to handle a change of the text of the right side edit. + + @param txt text of the line edit + @type str + """ + self.__updateOkButton() + + def getData(self): + """ + Public method to get the entered data. + + @return tuple containing the left and right hand side of the assignment + @rtype tuple of two str + """ + return self.leftEdit.text(), self.rightEdit.text()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleAddBuiltinIgnoreDialog.ui Fri Mar 17 19:09:39 2017 +0100 @@ -0,0 +1,112 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>CodeStyleAddBuiltinIgnoreDialog</class> + <widget class="QDialog" name="CodeStyleAddBuiltinIgnoreDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>112</height> + </rect> + </property> + <property name="windowTitle"> + <string>Add Built-in Assignment</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0" colspan="2"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Enter the data for a built-in assignment to be ignored:</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Left Side:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="E5ClearableLineEdit" name="leftEdit"> + <property name="placeholderText"> + <string>Enter left hand side of assignment</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Right Side:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="E5ClearableLineEdit" name="rightEdit"> + <property name="placeholderText"> + <string>Enter right hand side of assignment</string> + </property> + </widget> + </item> + <item row="3" column="0" colspan="2"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>E5ClearableLineEdit</class> + <extends>QLineEdit</extends> + <header>E5Gui/E5LineEdit.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>CodeStyleAddBuiltinIgnoreDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>CodeStyleAddBuiltinIgnoreDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui>
--- a/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleChecker.py Thu Mar 16 20:00:31 2017 +0100 +++ b/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleChecker.py Fri Mar 17 19:09:39 2017 +0100 @@ -188,11 +188,13 @@ @param args arguments used by the codeStyleCheck function (list of excludeMessages (str), includeMessages (str), repeatMessages (bool), fixCodes (str), noFixCodes (str), fixIssues (bool), - maxLineLength (int), hangClosing (bool), docType (str), errors - (list of str), eol (str), encoding (str), backup (bool)) - @return tuple of stats (dict) and results (tuple for each found violation - of style (tuple of lineno (int), position (int), text (str), ignored - (bool), fixed (bool), autofixing (bool), fixedMsg (str))) + maxLineLength (int), hangClosing (bool), docType (str), maximum + allowed code complexity (int), dictionary with arguments for the + miscellaneous checker (dict), errors (list of str), eol (str), + encoding (str), backup (bool)) + @return tuple of statistics (dict) and results (tuple for each found + violation of style (tuple of lineno (int), position (int), text (str), + ignored (bool), fixed (bool), autofixing (bool), fixedMsg (str))) """ (excludeMessages, includeMessages, repeatMessages, fixCodes, noFixCodes, fixIssues, maxLineLength, hangClosing, docType, maxComplexity,
--- a/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.py Thu Mar 16 20:00:31 2017 +0100 +++ b/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.py Fri Mar 17 19:09:39 2017 +0100 @@ -95,6 +95,9 @@ self.resultList.headerItem().setText(self.resultList.columnCount(), "") self.resultList.header().setSortIndicator(0, Qt.AscendingOrder) + self.addBuiltinButton.setIcon(UI.PixmapCache.getIcon("plus.png")) + self.deleteBuiltinButton.setIcon(UI.PixmapCache.getIcon("minus.png")) + self.checkProgress.setVisible(False) self.checkProgressLabel.setVisible(False) self.checkProgressLabel.setMaximumWidth(600) @@ -325,6 +328,11 @@ self.__data["CopyrightAuthor"] = "" if "FutureChecker" not in self.__data: self.__data["FutureChecker"] = "" + if "BuiltinsChecker" not in self.__data: + self.__data["BuiltinsChecker"] = { + "str": ["unicode", ], + "chr": ["unichr", ], + } self.excludeFilesEdit.setText(self.__data["ExcludeFiles"]) self.excludeMessagesEdit.setText(self.__data["ExcludeMessages"]) @@ -344,6 +352,7 @@ self.__data["CopyrightMinFileSize"]) self.copyrightAuthorEdit.setText(self.__data["CopyrightAuthor"]) self.__initFuturesList(self.__data["FutureChecker"]) + self.__initBuiltinsIgnoreList(self.__data["BuiltinsChecker"]) def start(self, fn, save=False, repeat=None): """ @@ -430,6 +439,7 @@ "Author": self.copyrightAuthorEdit.text(), }, "FutureChecker": self.__getSelectedFutureImports(), + "BuiltinsChecker": self.__getBuiltinsIgnoreList(), } self.__options = [excludeMessages, includeMessages, repeatMessages, @@ -755,6 +765,7 @@ "CopyrightMinFileSize": self.copyrightFileSizeSpinBox.value(), "CopyrightAuthor": self.copyrightAuthorEdit.text(), "FutureChecker": self.__getSelectedFutureImports(), + "BuiltinsChecker": self.__getBuiltinsIgnoreList(), } if data != self.__data: self.__data = data @@ -936,6 +947,11 @@ Preferences.Prefs.settings.value("PEP8/CopyrightAuthor", "")) self.__initFuturesList( Preferences.Prefs.settings.value("PEP8/FutureChecker", "")) + self.__initBuiltinsIgnoreList(Preferences.toDict( + Preferences.Prefs.settings.value("PEP8/BuiltinsChecker", { + "str": ["unicode", ], + "chr": ["unichr", ], + }))) @pyqtSlot() def on_storeDefaultButton_clicked(self): @@ -976,6 +992,8 @@ "PEP8/CopyrightAuthor", self.copyrightAuthorEdit.text()) Preferences.Prefs.settings.setValue( "PEP8/FutureChecker", self.__getSelectedFutureImports()) + Preferences.Prefs.settings.setValue( + "PEP8/BuiltinsChecker", self.__getBuiltinsIgnoreList()) @pyqtSlot() def on_resetDefaultButton_clicked(self): @@ -1001,6 +1019,10 @@ Preferences.Prefs.settings.setValue("PEP8/CopyrightMinFileSize", 0) Preferences.Prefs.settings.setValue("PEP8/CopyrightAuthor", "") Preferences.Prefs.settings.setValue("PEP8/FutureChecker", "") + Preferences.Prefs.settings.setValue("PEP8/BuiltinsChecker", { + "str": ["unicode", ], + "chr": ["unichr", ], + }) @pyqtSlot(QAbstractButton) def on_buttonBox_clicked(self, button): @@ -1117,6 +1139,7 @@ for row in range(self.futuresList.count()): itm = self.futuresList.item(row) itm.setSelected(itm.text() in expectedImports) + # TODO: change this to checkable items def __getSelectedFutureImports(self): """ @@ -1127,3 +1150,66 @@ """ selectedFutures = [i.text() for i in self.futuresList.selectedItems()] return ", ".join(selectedFutures) + + def __initBuiltinsIgnoreList(self, builtinsIgnoreDict): + """ + Private method to populate the list of shadowed builtins to be ignored. + + @param builtinsIgnoreDict dictionary containing the builtins + assignments to be ignored + @type dict of list of str + """ + self.builtinsAssignmentList.clear() + for left, rightList in builtinsIgnoreDict.items(): + for right in rightList: + QTreeWidgetItem(self.builtinsAssignmentList, [left, right]) + + self.on_builtinsAssignmentList_itemSelectionChanged() + + def __getBuiltinsIgnoreList(self): + """ + Private method to get a dictionary containing the builtins assignments + to be ignored. + + @return dictionary containing the builtins assignments to be ignored + @rtype dict of list of str + """ + builtinsIgnoreDict = {} + for row in range(self.builtinsAssignmentList.topLevelItemCount()): + itm = self.builtinsAssignmentList.topLevelItem(row) + left, right = itm.text(0), itm.text(1) + if left not in builtinsIgnoreDict: + builtinsIgnoreDict[left] = [] + builtinsIgnoreDict[left].append(right) + + return builtinsIgnoreDict + + @pyqtSlot() + def on_builtinsAssignmentList_itemSelectionChanged(self): + """ + Private slot to react upon changes of the selected builtin assignments. + """ + self.deleteBuiltinButton.setEnabled( + len(self.builtinsAssignmentList.selectedItems()) > 0) + + @pyqtSlot() + def on_addBuiltinButton_clicked(self): + """ + Slot documentation goes here. + """ + from .CodeStyleAddBuiltinIgnoreDialog import \ + CodeStyleAddBuiltinIgnoreDialog + dlg = CodeStyleAddBuiltinIgnoreDialog(self) + if dlg.exec_() == QDialog.Accepted: + left, right = dlg.getData() + QTreeWidgetItem(self.builtinsAssignmentList, [left, right]) + + @pyqtSlot() + def on_deleteBuiltinButton_clicked(self): + """ + Private slot to delete the selected items from the list. + """ + for itm in self.builtinsAssignmentList.selectedItems(): + index = self.builtinsAssignmentList.indexOfTopLevelItem(itm) + self.builtinsAssignmentList.takeTopLevelItem(index) + del itm
--- a/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.ui Thu Mar 16 20:00:31 2017 +0100 +++ b/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.ui Fri Mar 17 19:09:39 2017 +0100 @@ -21,8 +21,8 @@ <property name="sizeGripEnabled"> <bool>true</bool> </property> - <layout class="QVBoxLayout" name="verticalLayout_5"> - <item> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> <widget class="QFrame" name="filterFrame"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> @@ -258,8 +258,8 @@ <rect> <x>0</x> <y>0</y> - <width>206</width> - <height>470</height> + <width>561</width> + <height>580</height> </rect> </property> <layout class="QVBoxLayout" name="verticalLayout_2"> @@ -473,6 +473,75 @@ </widget> </item> <item> + <widget class="QGroupBox" name="groupBox_7"> + <property name="title"> + <string>Ignore Built-ins Assignment</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_8"> + <item> + <widget class="QTreeWidget" name="builtinsAssignmentList"> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="rootIsDecorated"> + <bool>false</bool> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <column> + <property name="text"> + <string>Left</string> + </property> + </column> + <column> + <property name="text"> + <string>Right</string> + </property> + </column> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_5"> + <item> + <widget class="QToolButton" name="addBuiltinButton"> + <property name="toolTip"> + <string>Press to add a built-in assignment to be ignored</string> + </property> + <property name="text"> + <string notr="true">+</string> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="deleteBuiltinButton"> + <property name="toolTip"> + <string>Press to delete the selected entries</string> + </property> + <property name="text"> + <string notr="true">-</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> <widget class="QGroupBox" name="groupBox_3"> <property name="title"> <string>McCabe Complexity</string> @@ -608,7 +677,7 @@ </layout> </widget> </item> - <item> + <item row="1" column="0"> <widget class="QTreeWidget" name="resultList"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> @@ -648,7 +717,7 @@ </column> </widget> </item> - <item> + <item row="2" column="0"> <widget class="E5SqueezeLabelPath" name="checkProgressLabel"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> @@ -661,7 +730,7 @@ </property> </widget> </item> - <item> + <item row="3" column="0"> <widget class="QProgressBar" name="checkProgress"> <property name="toolTip"> <string>Shows the progress of the code style check</string> @@ -677,7 +746,7 @@ </property> </widget> </item> - <item> + <item row="4" column="0"> <widget class="QDialogButtonBox" name="buttonBox"> <property name="orientation"> <enum>Qt::Horizontal</enum> @@ -724,6 +793,9 @@ <tabstop>copyrightFileSizeSpinBox</tabstop> <tabstop>copyrightAuthorEdit</tabstop> <tabstop>futuresList</tabstop> + <tabstop>builtinsAssignmentList</tabstop> + <tabstop>addBuiltinButton</tabstop> + <tabstop>deleteBuiltinButton</tabstop> <tabstop>complexitySpinBox</tabstop> <tabstop>startButton</tabstop> <tabstop>fixButton</tabstop>
--- a/Plugins/CheckerPlugins/CodeStyleChecker/MiscellaneousChecker.py Thu Mar 16 20:00:31 2017 +0100 +++ b/Plugins/CheckerPlugins/CodeStyleChecker/MiscellaneousChecker.py Fri Mar 17 19:09:39 2017 +0100 @@ -115,6 +115,10 @@ "MinFilesize": 0, "Author": "", }, + "BuiltinsChecker": { + "str": ["unicode", ], + "chr": ["unichr", ], + } } self.__checkers = [] @@ -491,6 +495,9 @@ """ Private method to check, if built-ins are shadowed. """ + ignoreBuiltinAssignments = self.__args.get( + "BuiltinsChecker", self.__defaultArgs["BuiltinsChecker"]) + for node in ast.walk(self.__tree): if isinstance(node, ast.Assign): # assign statement @@ -499,9 +506,9 @@ element.id in self.__builtins: value = node.value if isinstance(value, ast.Name) and \ - value.id in ["unicode", "unichr"]: + element.id in ignoreBuiltinAssignments and \ + value.id in ignoreBuiltinAssignments[element.id]: # ignore compatibility assignments - # TODO: make this configurable continue self.__error(element.lineno - 1, element.col_offset, "M131", element.id)
--- a/eric6.e4p Thu Mar 16 20:00:31 2017 +0100 +++ b/eric6.e4p Fri Mar 17 19:09:39 2017 +0100 @@ -465,6 +465,7 @@ <Source>PluginManager/__init__.py</Source> <Source>Plugins/AboutPlugin/AboutDialog.py</Source> <Source>Plugins/AboutPlugin/__init__.py</Source> + <Source>Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleAddBuiltinIgnoreDialog.py</Source> <Source>Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleChecker.py</Source> <Source>Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.py</Source> <Source>Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCodeSelectionDialog.py</Source> @@ -1605,6 +1606,7 @@ <Form>PluginManager/PluginInstallDialog.ui</Form> <Form>PluginManager/PluginRepositoryDialog.ui</Form> <Form>PluginManager/PluginUninstallDialog.ui</Form> + <Form>Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleAddBuiltinIgnoreDialog.ui</Form> <Form>Plugins/AboutPlugin/AboutDialog.ui</Form> <Form>Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.ui</Form> <Form>Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCodeSelectionDialog.ui</Form> @@ -1954,14 +1956,14 @@ <Interfaces/> <Others> <Other>.hgignore</Other> - <Other>APIs/Python/zope-2.10.7.api</Other> - <Other>APIs/Python/zope-2.11.2.api</Other> - <Other>APIs/Python/zope-3.3.1.api</Other> <Other>APIs/Python3/PyQt4.bas</Other> <Other>APIs/Python3/PyQt5.bas</Other> <Other>APIs/Python3/QScintilla2.bas</Other> <Other>APIs/Python3/eric6.api</Other> <Other>APIs/Python3/eric6.bas</Other> + <Other>APIs/Python/zope-2.10.7.api</Other> + <Other>APIs/Python/zope-2.11.2.api</Other> + <Other>APIs/Python/zope-3.3.1.api</Other> <Other>APIs/QSS/qss.api</Other> <Other>APIs/Ruby/Ruby-1.8.7.api</Other> <Other>APIs/Ruby/Ruby-1.8.7.bas</Other>