src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/CodeStyleCheckerDialog.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9219
964a326c58d4
child 9276
e6748a5e24b9
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
15 import time 15 import time
16 16
17 from PyQt6.QtCore import pyqtSlot, Qt, QTimer, QCoreApplication 17 from PyQt6.QtCore import pyqtSlot, Qt, QTimer, QCoreApplication
18 from PyQt6.QtGui import QIcon 18 from PyQt6.QtGui import QIcon
19 from PyQt6.QtWidgets import ( 19 from PyQt6.QtWidgets import (
20 QDialog, QTreeWidgetItem, QAbstractButton, QDialogButtonBox, QApplication, 20 QDialog,
21 QListWidgetItem, QInputDialog, QLineEdit 21 QTreeWidgetItem,
22 QAbstractButton,
23 QDialogButtonBox,
24 QApplication,
25 QListWidgetItem,
26 QInputDialog,
27 QLineEdit,
22 ) 28 )
23 29
24 from EricWidgets.EricApplication import ericApp 30 from EricWidgets.EricApplication import ericApp
25 31
26 from .Ui_CodeStyleCheckerDialog import Ui_CodeStyleCheckerDialog 32 from .Ui_CodeStyleCheckerDialog import Ui_CodeStyleCheckerDialog
30 import Utilities 36 import Utilities
31 37
32 from . import pycodestyle 38 from . import pycodestyle
33 from . import CodeStyleCheckerUtilities 39 from . import CodeStyleCheckerUtilities
34 40
35 from .Miscellaneous.MiscellaneousDefaults import ( 41 from .Miscellaneous.MiscellaneousDefaults import MiscellaneousCheckerDefaultArgs
36 MiscellaneousCheckerDefaultArgs 42 from .Annotations.AnnotationsCheckerDefaults import AnnotationsCheckerDefaultArgs
37 )
38 from .Annotations.AnnotationsCheckerDefaults import (
39 AnnotationsCheckerDefaultArgs
40 )
41 43
42 44
43 class CodeStyleCheckerDialog(QDialog, Ui_CodeStyleCheckerDialog): 45 class CodeStyleCheckerDialog(QDialog, Ui_CodeStyleCheckerDialog):
44 """ 46 """
45 Class implementing a dialog to show the results of the code style check. 47 Class implementing a dialog to show the results of the code style check.
46 """ 48 """
49
47 filenameRole = Qt.ItemDataRole.UserRole + 1 50 filenameRole = Qt.ItemDataRole.UserRole + 1
48 lineRole = Qt.ItemDataRole.UserRole + 2 51 lineRole = Qt.ItemDataRole.UserRole + 2
49 positionRole = Qt.ItemDataRole.UserRole + 3 52 positionRole = Qt.ItemDataRole.UserRole + 3
50 messageRole = Qt.ItemDataRole.UserRole + 4 53 messageRole = Qt.ItemDataRole.UserRole + 4
51 fixableRole = Qt.ItemDataRole.UserRole + 5 54 fixableRole = Qt.ItemDataRole.UserRole + 5
52 codeRole = Qt.ItemDataRole.UserRole + 6 55 codeRole = Qt.ItemDataRole.UserRole + 6
53 ignoredRole = Qt.ItemDataRole.UserRole + 7 56 ignoredRole = Qt.ItemDataRole.UserRole + 7
54 argsRole = Qt.ItemDataRole.UserRole + 8 57 argsRole = Qt.ItemDataRole.UserRole + 8
55 58
56 availableFutures = [ 59 availableFutures = [
57 'division', 'absolute_import', 'with_statement', 60 "division",
58 'print_function', 'unicode_literals', 'generator_stop', 61 "absolute_import",
59 'annotations'] 62 "with_statement",
60 63 "print_function",
64 "unicode_literals",
65 "generator_stop",
66 "annotations",
67 ]
68
61 cryptoBitSelectionsDsaRsa = [ 69 cryptoBitSelectionsDsaRsa = [
62 "512", "1024", "2048", "4096", "8192", "16384", "32786", 70 "512",
71 "1024",
72 "2048",
73 "4096",
74 "8192",
75 "16384",
76 "32786",
63 ] 77 ]
64 cryptoBitSelectionsEc = [ 78 cryptoBitSelectionsEc = [
65 "160", "224", "256", "384", "512", 79 "160",
80 "224",
81 "256",
82 "384",
83 "512",
66 ] 84 ]
67 85
68 checkCategories = { 86 checkCategories = {
69 "A": QCoreApplication.translate( 87 "A": QCoreApplication.translate("CheckerCategories", "Annotations"),
70 "CheckerCategories", 88 "C": QCoreApplication.translate("CheckerCategories", "Code Complexity"),
71 "Annotations"), 89 "D": QCoreApplication.translate("CheckerCategories", "Documentation"),
72 "C": QCoreApplication.translate( 90 "E": QCoreApplication.translate("CheckerCategories", "Errors"),
73 "CheckerCategories", 91 "I": QCoreApplication.translate("CheckerCategories", "Imports"),
74 "Code Complexity"), 92 "M": QCoreApplication.translate("CheckerCategories", "Miscellaneous"),
75 "D": QCoreApplication.translate( 93 "N": QCoreApplication.translate("CheckerCategories", "Naming"),
76 "CheckerCategories", 94 "P": QCoreApplication.translate("CheckerCategories", "'pathlib' Usage"),
77 "Documentation"), 95 "S": QCoreApplication.translate("CheckerCategories", "Security"),
78 "E": QCoreApplication.translate( 96 "W": QCoreApplication.translate("CheckerCategories", "Warnings"),
79 "CheckerCategories", 97 "Y": QCoreApplication.translate("CheckerCategories", "Simplify Code"),
80 "Errors"),
81 "I": QCoreApplication.translate(
82 "CheckerCategories",
83 "Imports"),
84 "M": QCoreApplication.translate(
85 "CheckerCategories",
86 "Miscellaneous"),
87 "N": QCoreApplication.translate(
88 "CheckerCategories",
89 "Naming"),
90 "P": QCoreApplication.translate(
91 "CheckerCategories",
92 "'pathlib' Usage"),
93 "S": QCoreApplication.translate(
94 "CheckerCategories",
95 "Security"),
96 "W": QCoreApplication.translate(
97 "CheckerCategories",
98 "Warnings"),
99 "Y": QCoreApplication.translate(
100 "CheckerCategories",
101 "Simplify Code"),
102 } 98 }
103 99
104 noResults = 0 100 noResults = 0
105 noFiles = 1 101 noFiles = 1
106 hasResults = 2 102 hasResults = 2
107 103
108 def __init__(self, styleCheckService, project=None, parent=None): 104 def __init__(self, styleCheckService, project=None, parent=None):
109 """ 105 """
110 Constructor 106 Constructor
111 107
112 @param styleCheckService reference to the service 108 @param styleCheckService reference to the service
113 @type CodeStyleCheckService 109 @type CodeStyleCheckService
114 @param project reference to the project if called on project or project 110 @param project reference to the project if called on project or project
115 browser level 111 browser level
116 @type Project 112 @type Project
118 @type QWidget 114 @type QWidget
119 """ 115 """
120 super().__init__(parent) 116 super().__init__(parent)
121 self.setupUi(self) 117 self.setupUi(self)
122 self.setWindowFlags(Qt.WindowType.Window) 118 self.setWindowFlags(Qt.WindowType.Window)
123 119
124 self.__project = project 120 self.__project = project
125 121
126 self.optionsTabWidget.setCurrentIndex(0) 122 self.optionsTabWidget.setCurrentIndex(0)
127 123
128 self.excludeMessagesSelectButton.setIcon( 124 self.excludeMessagesSelectButton.setIcon(UI.PixmapCache.getIcon("select"))
129 UI.PixmapCache.getIcon("select")) 125 self.includeMessagesSelectButton.setIcon(UI.PixmapCache.getIcon("select"))
130 self.includeMessagesSelectButton.setIcon( 126 self.fixIssuesSelectButton.setIcon(UI.PixmapCache.getIcon("select"))
131 UI.PixmapCache.getIcon("select")) 127 self.noFixIssuesSelectButton.setIcon(UI.PixmapCache.getIcon("select"))
132 self.fixIssuesSelectButton.setIcon( 128
133 UI.PixmapCache.getIcon("select"))
134 self.noFixIssuesSelectButton.setIcon(
135 UI.PixmapCache.getIcon("select"))
136
137 self.docTypeComboBox.addItem(self.tr("PEP-257"), "pep257") 129 self.docTypeComboBox.addItem(self.tr("PEP-257"), "pep257")
138 self.docTypeComboBox.addItem(self.tr("Eric"), "eric") 130 self.docTypeComboBox.addItem(self.tr("Eric"), "eric")
139 self.docTypeComboBox.addItem(self.tr("Eric (Blacked)"), "eric_black") 131 self.docTypeComboBox.addItem(self.tr("Eric (Blacked)"), "eric_black")
140 132
141 for category, text in CodeStyleCheckerDialog.checkCategories.items(): 133 for category, text in CodeStyleCheckerDialog.checkCategories.items():
142 itm = QListWidgetItem(text, self.categoriesList) 134 itm = QListWidgetItem(text, self.categoriesList)
143 itm.setData(Qt.ItemDataRole.UserRole, category) 135 itm.setData(Qt.ItemDataRole.UserRole, category)
144 itm.setFlags(itm.flags() | Qt.ItemFlag.ItemIsUserCheckable) 136 itm.setFlags(itm.flags() | Qt.ItemFlag.ItemIsUserCheckable)
145 itm.setCheckState(Qt.CheckState.Unchecked) 137 itm.setCheckState(Qt.CheckState.Unchecked)
146 138
147 for future in CodeStyleCheckerDialog.availableFutures: 139 for future in CodeStyleCheckerDialog.availableFutures:
148 itm = QListWidgetItem(future, self.futuresList) 140 itm = QListWidgetItem(future, self.futuresList)
149 itm.setFlags(itm.flags() | Qt.ItemFlag.ItemIsUserCheckable) 141 itm.setFlags(itm.flags() | Qt.ItemFlag.ItemIsUserCheckable)
150 itm.setCheckState(Qt.CheckState.Unchecked) 142 itm.setCheckState(Qt.CheckState.Unchecked)
151 143
152 self.dsaHighRiskCombo.addItems( 144 self.dsaHighRiskCombo.addItems(CodeStyleCheckerDialog.cryptoBitSelectionsDsaRsa)
153 CodeStyleCheckerDialog.cryptoBitSelectionsDsaRsa)
154 self.dsaMediumRiskCombo.addItems( 145 self.dsaMediumRiskCombo.addItems(
155 CodeStyleCheckerDialog.cryptoBitSelectionsDsaRsa) 146 CodeStyleCheckerDialog.cryptoBitSelectionsDsaRsa
156 self.rsaHighRiskCombo.addItems( 147 )
157 CodeStyleCheckerDialog.cryptoBitSelectionsDsaRsa) 148 self.rsaHighRiskCombo.addItems(CodeStyleCheckerDialog.cryptoBitSelectionsDsaRsa)
158 self.rsaMediumRiskCombo.addItems( 149 self.rsaMediumRiskCombo.addItems(
159 CodeStyleCheckerDialog.cryptoBitSelectionsDsaRsa) 150 CodeStyleCheckerDialog.cryptoBitSelectionsDsaRsa
160 self.ecHighRiskCombo.addItems( 151 )
161 CodeStyleCheckerDialog.cryptoBitSelectionsEc) 152 self.ecHighRiskCombo.addItems(CodeStyleCheckerDialog.cryptoBitSelectionsEc)
162 self.ecMediumRiskCombo.addItems( 153 self.ecMediumRiskCombo.addItems(CodeStyleCheckerDialog.cryptoBitSelectionsEc)
163 CodeStyleCheckerDialog.cryptoBitSelectionsEc) 154
164
165 self.statisticsButton.setEnabled(False) 155 self.statisticsButton.setEnabled(False)
166 self.showButton.setEnabled(False) 156 self.showButton.setEnabled(False)
167 self.cancelButton.setEnabled(True) 157 self.cancelButton.setEnabled(True)
168 self.buttonBox.button( 158 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(False)
169 QDialogButtonBox.StandardButton.Close).setEnabled(False) 159
170
171 self.resultList.headerItem().setText(self.resultList.columnCount(), "") 160 self.resultList.headerItem().setText(self.resultList.columnCount(), "")
172 self.resultList.header().setSortIndicator( 161 self.resultList.header().setSortIndicator(0, Qt.SortOrder.AscendingOrder)
173 0, Qt.SortOrder.AscendingOrder) 162
174
175 self.addBuiltinButton.setIcon(UI.PixmapCache.getIcon("plus")) 163 self.addBuiltinButton.setIcon(UI.PixmapCache.getIcon("plus"))
176 self.deleteBuiltinButton.setIcon(UI.PixmapCache.getIcon("minus")) 164 self.deleteBuiltinButton.setIcon(UI.PixmapCache.getIcon("minus"))
177 self.addWhitelistButton.setIcon(UI.PixmapCache.getIcon("plus")) 165 self.addWhitelistButton.setIcon(UI.PixmapCache.getIcon("plus"))
178 self.deleteWhitelistButton.setIcon(UI.PixmapCache.getIcon("minus")) 166 self.deleteWhitelistButton.setIcon(UI.PixmapCache.getIcon("minus"))
179 167
180 self.restartButton.setEnabled(False) 168 self.restartButton.setEnabled(False)
181 self.fixButton.setEnabled(False) 169 self.fixButton.setEnabled(False)
182 170
183 self.checkProgress.setVisible(False) 171 self.checkProgress.setVisible(False)
184 self.checkProgressLabel.setVisible(False) 172 self.checkProgressLabel.setVisible(False)
185 self.checkProgressLabel.setMaximumWidth(600) 173 self.checkProgressLabel.setMaximumWidth(600)
186 174
187 self.styleCheckService = styleCheckService 175 self.styleCheckService = styleCheckService
188 self.styleCheckService.styleChecked.connect(self.__processResult) 176 self.styleCheckService.styleChecked.connect(self.__processResult)
189 self.styleCheckService.batchFinished.connect(self.__batchFinished) 177 self.styleCheckService.batchFinished.connect(self.__batchFinished)
190 self.styleCheckService.error.connect(self.__processError) 178 self.styleCheckService.error.connect(self.__processError)
191 self.filename = None 179 self.filename = None
192 180
193 self.results = CodeStyleCheckerDialog.noResults 181 self.results = CodeStyleCheckerDialog.noResults
194 self.cancelled = False 182 self.cancelled = False
195 self.__lastFileItem = None 183 self.__lastFileItem = None
196 self.__batch = False 184 self.__batch = False
197 self.__finished = True 185 self.__finished = True
198 self.__errorItem = None 186 self.__errorItem = None
199 self.__timenow = time.monotonic() 187 self.__timenow = time.monotonic()
200 188
201 self.__fileOrFileList = "" 189 self.__fileOrFileList = ""
202 self.__forProject = False 190 self.__forProject = False
203 self.__data = {} 191 self.__data = {}
204 self.__statistics = collections.defaultdict(self.__defaultStatistics) 192 self.__statistics = collections.defaultdict(self.__defaultStatistics)
205 self.__onlyFixes = {} 193 self.__onlyFixes = {}
206 self.__noFixCodesList = [] 194 self.__noFixCodesList = []
207 self.__detectedCodes = [] 195 self.__detectedCodes = []
208 196
209 self.on_loadDefaultButton_clicked() 197 self.on_loadDefaultButton_clicked()
210 198
211 self.mainWidget.setCurrentWidget(self.configureTab) 199 self.mainWidget.setCurrentWidget(self.configureTab)
212 self.optionsTabWidget.setCurrentWidget(self.globalOptionsTab) 200 self.optionsTabWidget.setCurrentWidget(self.globalOptionsTab)
213 201
214 def __defaultStatistics(self): 202 def __defaultStatistics(self):
215 """ 203 """
216 Private method to return the default statistics entry. 204 Private method to return the default statistics entry.
217 205
218 @return dictionary with default statistics entry 206 @return dictionary with default statistics entry
219 @rtype dict 207 @rtype dict
220 """ 208 """
221 return { 209 return {
222 "total": 0, 210 "total": 0,
223 "ignored": 0, 211 "ignored": 0,
224 } 212 }
225 213
226 def __resort(self): 214 def __resort(self):
227 """ 215 """
228 Private method to resort the tree. 216 Private method to resort the tree.
229 """ 217 """
230 self.resultList.sortItems(self.resultList.sortColumn(), 218 self.resultList.sortItems(
231 self.resultList.header().sortIndicatorOrder() 219 self.resultList.sortColumn(), self.resultList.header().sortIndicatorOrder()
232 ) 220 )
233 221
234 def __createErrorItem(self, filename, message): 222 def __createErrorItem(self, filename, message):
235 """ 223 """
236 Private slot to create a new error item in the result list. 224 Private slot to create a new error item in the result list.
237 225
238 @param filename name of the file 226 @param filename name of the file
239 @type str 227 @type str
240 @param message error message 228 @param message error message
241 @type str 229 @type str
242 """ 230 """
243 if self.__errorItem is None: 231 if self.__errorItem is None:
244 self.__errorItem = QTreeWidgetItem(self.resultList, [ 232 self.__errorItem = QTreeWidgetItem(self.resultList, [self.tr("Errors")])
245 self.tr("Errors")])
246 self.__errorItem.setExpanded(True) 233 self.__errorItem.setExpanded(True)
247 self.__errorItem.setForeground(0, Qt.GlobalColor.red) 234 self.__errorItem.setForeground(0, Qt.GlobalColor.red)
248 235
249 msg = "{0} ({1})".format(self.__project.getRelativePath(filename), 236 msg = "{0} ({1})".format(self.__project.getRelativePath(filename), message)
250 message)
251 if not self.resultList.findItems(msg, Qt.MatchFlag.MatchExactly): 237 if not self.resultList.findItems(msg, Qt.MatchFlag.MatchExactly):
252 itm = QTreeWidgetItem(self.__errorItem, [msg]) 238 itm = QTreeWidgetItem(self.__errorItem, [msg])
253 itm.setForeground(0, Qt.GlobalColor.red) 239 itm.setForeground(0, Qt.GlobalColor.red)
254 itm.setFirstColumnSpanned(True) 240 itm.setFirstColumnSpanned(True)
255 241
256 def __createFileErrorItem(self, filename, message): 242 def __createFileErrorItem(self, filename, message):
257 """ 243 """
258 Private method to create an error entry for a given file. 244 Private method to create an error entry for a given file.
259 245
260 @param filename file name of the file 246 @param filename file name of the file
261 @type str 247 @type str
262 @param message error message text 248 @param message error message text
263 @type str 249 @type str
264 """ 250 """
272 "fixed": False, 258 "fixed": False,
273 "autofixing": False, 259 "autofixing": False,
274 "ignored": False, 260 "ignored": False,
275 } 261 }
276 self.__createResultItem(filename, result) 262 self.__createResultItem(filename, result)
277 263
278 def __createResultItem(self, filename, result): 264 def __createResultItem(self, filename, result):
279 """ 265 """
280 Private method to create an entry in the result list. 266 Private method to create an entry in the result list.
281 267
282 @param filename file name of the file 268 @param filename file name of the file
283 @type str 269 @type str
284 @param result dictionary containing check result data 270 @param result dictionary containing check result data
285 @type dict 271 @type dict
286 @return reference to the created item 272 @return reference to the created item
287 @rtype QTreeWidgetItem 273 @rtype QTreeWidgetItem
288 """ 274 """
289 from .CodeStyleFixer import FixableCodeStyleIssues 275 from .CodeStyleFixer import FixableCodeStyleIssues
290 276
291 if self.__lastFileItem is None: 277 if self.__lastFileItem is None:
292 # It's a new file 278 # It's a new file
293 self.__lastFileItem = QTreeWidgetItem(self.resultList, [ 279 self.__lastFileItem = QTreeWidgetItem(
294 self.__project.getRelativePath(filename)]) 280 self.resultList, [self.__project.getRelativePath(filename)]
281 )
295 self.__lastFileItem.setFirstColumnSpanned(True) 282 self.__lastFileItem.setFirstColumnSpanned(True)
296 self.__lastFileItem.setExpanded(True) 283 self.__lastFileItem.setExpanded(True)
297 self.__lastFileItem.setData(0, self.filenameRole, filename) 284 self.__lastFileItem.setData(0, self.filenameRole, filename)
298 285
299 msgCode = result["code"].split(".", 1)[0] 286 msgCode = result["code"].split(".", 1)[0]
300 self.__detectedCodes.append(msgCode) 287 self.__detectedCodes.append(msgCode)
301 288
302 fixable = False 289 fixable = False
303 itm = QTreeWidgetItem( 290 itm = QTreeWidgetItem(
304 self.__lastFileItem, [ 291 self.__lastFileItem,
305 "{0:6}".format(result["line"]), 292 ["{0:6}".format(result["line"]), msgCode, result["display"]],
306 msgCode, 293 )
307 result["display"] 294
308 ] 295 CodeStyleCheckerUtilities.setItemIcon(itm, 1, msgCode, result.get("severity"))
309 ) 296
310
311 CodeStyleCheckerUtilities.setItemIcon(
312 itm, 1, msgCode, result.get("severity"))
313
314 if result["fixed"]: 297 if result["fixed"]:
315 itm.setIcon(0, UI.PixmapCache.getIcon("issueFixed")) 298 itm.setIcon(0, UI.PixmapCache.getIcon("issueFixed"))
316 elif ( 299 elif (
317 msgCode in FixableCodeStyleIssues and 300 msgCode in FixableCodeStyleIssues
318 not result["autofixing"] and 301 and not result["autofixing"]
319 msgCode not in self.__noFixCodesList 302 and msgCode not in self.__noFixCodesList
320 ): 303 ):
321 itm.setIcon(0, UI.PixmapCache.getIcon("issueFixable")) 304 itm.setIcon(0, UI.PixmapCache.getIcon("issueFixable"))
322 fixable = True 305 fixable = True
323 306
324 itm.setTextAlignment(0, Qt.AlignmentFlag.AlignRight) 307 itm.setTextAlignment(0, Qt.AlignmentFlag.AlignRight)
325 itm.setTextAlignment(1, Qt.AlignmentFlag.AlignHCenter) 308 itm.setTextAlignment(1, Qt.AlignmentFlag.AlignHCenter)
326 309
327 itm.setTextAlignment(0, Qt.AlignmentFlag.AlignVCenter) 310 itm.setTextAlignment(0, Qt.AlignmentFlag.AlignVCenter)
328 itm.setTextAlignment(1, Qt.AlignmentFlag.AlignVCenter) 311 itm.setTextAlignment(1, Qt.AlignmentFlag.AlignVCenter)
329 itm.setTextAlignment(2, Qt.AlignmentFlag.AlignVCenter) 312 itm.setTextAlignment(2, Qt.AlignmentFlag.AlignVCenter)
330 313
331 itm.setData(0, self.filenameRole, filename) 314 itm.setData(0, self.filenameRole, filename)
332 itm.setData(0, self.lineRole, int(result["line"])) 315 itm.setData(0, self.lineRole, int(result["line"]))
333 itm.setData(0, self.positionRole, int(result["offset"])) 316 itm.setData(0, self.positionRole, int(result["offset"]))
334 itm.setData(0, self.messageRole, result["display"]) 317 itm.setData(0, self.messageRole, result["display"])
335 itm.setData(0, self.fixableRole, fixable) 318 itm.setData(0, self.fixableRole, fixable)
336 itm.setData(0, self.codeRole, msgCode) 319 itm.setData(0, self.codeRole, msgCode)
337 itm.setData(0, self.ignoredRole, result["ignored"]) 320 itm.setData(0, self.ignoredRole, result["ignored"])
338 itm.setData(0, self.argsRole, result["args"]) 321 itm.setData(0, self.argsRole, result["args"])
339 322
340 if result["ignored"]: 323 if result["ignored"]:
341 font = itm.font(0) 324 font = itm.font(0)
342 font.setItalic(True) 325 font.setItalic(True)
343 for col in range(itm.columnCount()): 326 for col in range(itm.columnCount()):
344 itm.setFont(col, font) 327 itm.setFont(col, font)
345 328
346 return itm 329 return itm
347 330
348 def __modifyFixedResultItem(self, itm, result): 331 def __modifyFixedResultItem(self, itm, result):
349 """ 332 """
350 Private method to modify a result list entry to show its 333 Private method to modify a result list entry to show its
351 positive fixed state. 334 positive fixed state.
352 335
353 @param itm reference to the item to modify 336 @param itm reference to the item to modify
354 @type QTreeWidgetItem 337 @type QTreeWidgetItem
355 @param result dictionary containing check result data 338 @param result dictionary containing check result data
356 @type dict 339 @type dict
357 """ 340 """
358 if result["fixed"]: 341 if result["fixed"]:
359 itm.setText(2, result["display"]) 342 itm.setText(2, result["display"])
360 itm.setIcon(0, UI.PixmapCache.getIcon("issueFixed")) 343 itm.setIcon(0, UI.PixmapCache.getIcon("issueFixed"))
361 344
362 itm.setData(0, self.messageRole, result["display"]) 345 itm.setData(0, self.messageRole, result["display"])
363 else: 346 else:
364 itm.setIcon(0, QIcon()) 347 itm.setIcon(0, QIcon())
365 itm.setData(0, self.fixableRole, False) 348 itm.setData(0, self.fixableRole, False)
366 349
367 def __updateStatistics(self, statistics, fixer, ignoredErrors, securityOk): 350 def __updateStatistics(self, statistics, fixer, ignoredErrors, securityOk):
368 """ 351 """
369 Private method to update the collected statistics. 352 Private method to update the collected statistics.
370 353
371 @param statistics dictionary of statistical data with 354 @param statistics dictionary of statistical data with
372 message code as key and message count as value 355 message code as key and message count as value
373 @type dict 356 @type dict
374 @param fixer reference to the code style fixer 357 @param fixer reference to the code style fixer
375 @type CodeStyleFixer 358 @type CodeStyleFixer
386 self.__statistics[key]["total"] += statistics[key] 369 self.__statistics[key]["total"] += statistics[key]
387 for key in ignoredErrors: 370 for key in ignoredErrors:
388 self.__statistics[key]["ignored"] += ignoredErrors[key] 371 self.__statistics[key]["ignored"] += ignoredErrors[key]
389 self.__statistics["_IssuesFixed"] += fixer 372 self.__statistics["_IssuesFixed"] += fixer
390 self.__statistics["_SecurityOK"] += securityOk 373 self.__statistics["_SecurityOK"] += securityOk
391 374
392 def __updateFixerStatistics(self, fixer): 375 def __updateFixerStatistics(self, fixer):
393 """ 376 """
394 Private method to update the collected fixer related statistics. 377 Private method to update the collected fixer related statistics.
395 378
396 @param fixer reference to the code style fixer 379 @param fixer reference to the code style fixer
397 @type CodeStyleFixer 380 @type CodeStyleFixer
398 """ 381 """
399 self.__statistics["_IssuesFixed"] += fixer 382 self.__statistics["_IssuesFixed"] += fixer
400 383
401 def __resetStatistics(self): 384 def __resetStatistics(self):
402 """ 385 """
403 Private slot to reset the statistics data. 386 Private slot to reset the statistics data.
404 """ 387 """
405 self.__statistics.clear() 388 self.__statistics.clear()
406 self.__statistics["_FilesCount"] = 0 389 self.__statistics["_FilesCount"] = 0
407 self.__statistics["_FilesIssues"] = 0 390 self.__statistics["_FilesIssues"] = 0
408 self.__statistics["_IssuesFixed"] = 0 391 self.__statistics["_IssuesFixed"] = 0
409 self.__statistics["_SecurityOK"] = 0 392 self.__statistics["_SecurityOK"] = 0
410 393
411 def __getBanRelativeImportsValue(self): 394 def __getBanRelativeImportsValue(self):
412 """ 395 """
413 Private method to get the value corresponding the selected button. 396 Private method to get the value corresponding the selected button.
414 397
415 @return value for the BanRelativeImports argument 398 @return value for the BanRelativeImports argument
416 @rtype str 399 @rtype str
417 """ 400 """
418 if self.banParentsButton.isChecked(): 401 if self.banParentsButton.isChecked():
419 return "parents" 402 return "parents"
420 elif self.banAllButton.isChecked(): 403 elif self.banAllButton.isChecked():
421 return "true" 404 return "true"
422 else: 405 else:
423 return "" 406 return ""
424 407
425 def __setBanRelativeImports(self, value): 408 def __setBanRelativeImports(self, value):
426 """ 409 """
427 Private method to set the button according to the ban relative imports 410 Private method to set the button according to the ban relative imports
428 setting. 411 setting.
429 412
430 @param value value of the ban relative imports setting 413 @param value value of the ban relative imports setting
431 @type str 414 @type str
432 """ 415 """
433 if value == "parents": 416 if value == "parents":
434 self.banParentsButton.setChecked(True) 417 self.banParentsButton.setChecked(True)
435 elif value == "true": 418 elif value == "true":
436 self.banAllButton.setChecked(True) 419 self.banAllButton.setChecked(True)
437 else: 420 else:
438 self.allowAllButton.setChecked(True) 421 self.allowAllButton.setChecked(True)
439 422
440 def prepare(self, fileList, project): 423 def prepare(self, fileList, project):
441 """ 424 """
442 Public method to prepare the dialog with a list of filenames. 425 Public method to prepare the dialog with a list of filenames.
443 426
444 @param fileList list of filenames 427 @param fileList list of filenames
445 @type list of str 428 @type list of str
446 @param project reference to the project object 429 @param project reference to the project object
447 @type Project 430 @type Project
448 """ 431 """
449 self.__fileOrFileList = fileList[:] 432 self.__fileOrFileList = fileList[:]
450 self.__project = project 433 self.__project = project
451 self.__forProject = True 434 self.__forProject = True
452 435
453 self.buttonBox.button( 436 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(True)
454 QDialogButtonBox.StandardButton.Close).setEnabled(True) 437 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setDefault(True)
455 self.buttonBox.button(
456 QDialogButtonBox.StandardButton.Close).setDefault(True)
457 self.cancelButton.setEnabled(False) 438 self.cancelButton.setEnabled(False)
458 439
459 self.__data = self.__project.getData("CHECKERSPARMS", "Pep8Checker") 440 self.__data = self.__project.getData("CHECKERSPARMS", "Pep8Checker")
460 if ( 441 if self.__data is None or len(self.__data) < 6:
461 self.__data is None or
462 len(self.__data) < 6
463 ):
464 # initialize the data structure 442 # initialize the data structure
465 self.__data = { 443 self.__data = {
466 "ExcludeFiles": "", 444 "ExcludeFiles": "",
467 "ExcludeMessages": pycodestyle.DEFAULT_IGNORE, 445 "ExcludeMessages": pycodestyle.DEFAULT_IGNORE,
468 "IncludeMessages": "", 446 "IncludeMessages": "",
470 "FixCodes": "", 448 "FixCodes": "",
471 "FixIssues": False, 449 "FixIssues": False,
472 } 450 }
473 if "EnabledCheckerCategories" not in self.__data: 451 if "EnabledCheckerCategories" not in self.__data:
474 self.__data["EnabledCheckerCategories"] = ",".join( 452 self.__data["EnabledCheckerCategories"] = ",".join(
475 CodeStyleCheckerDialog.checkCategories.keys()) 453 CodeStyleCheckerDialog.checkCategories.keys()
454 )
476 if "MaxLineLength" not in self.__data: 455 if "MaxLineLength" not in self.__data:
477 self.__data["MaxLineLength"] = 88 456 self.__data["MaxLineLength"] = 88
478 # better code formatting than pycodestyle.MAX_LINE_LENGTH 457 # better code formatting than pycodestyle.MAX_LINE_LENGTH
479 # see the Black tool 458 # see the Black tool
480 if "MaxDocLineLength" not in self.__data: 459 if "MaxDocLineLength" not in self.__data:
495 if "LineComplexity" not in self.__data: 474 if "LineComplexity" not in self.__data:
496 self.__data["LineComplexity"] = 15 475 self.__data["LineComplexity"] = 15
497 if "LineComplexityScore" not in self.__data: 476 if "LineComplexityScore" not in self.__data:
498 self.__data["LineComplexityScore"] = 10 477 self.__data["LineComplexityScore"] = 10
499 if "ValidEncodings" not in self.__data: 478 if "ValidEncodings" not in self.__data:
500 self.__data["ValidEncodings"] = ( 479 self.__data["ValidEncodings"] = MiscellaneousCheckerDefaultArgs[
501 MiscellaneousCheckerDefaultArgs["CodingChecker"] 480 "CodingChecker"
502 ) 481 ]
503 if ( 482 if (
504 "CopyrightMinFileSize" not in self.__data or 483 "CopyrightMinFileSize" not in self.__data
505 "CopyrightAuthor" not in self.__data 484 or "CopyrightAuthor" not in self.__data
506 ): 485 ):
507 self.__data["CopyrightMinFileSize"] = ( 486 self.__data["CopyrightMinFileSize"] = MiscellaneousCheckerDefaultArgs[
508 MiscellaneousCheckerDefaultArgs[ 487 "CopyrightChecker"
509 "CopyrightChecker"]["MinFilesize"] 488 ]["MinFilesize"]
510 ) 489 self.__data["CopyrightAuthor"] = MiscellaneousCheckerDefaultArgs[
511 self.__data["CopyrightAuthor"] = ( 490 "CopyrightChecker"
512 MiscellaneousCheckerDefaultArgs["CopyrightChecker"]["Author"] 491 ]["Author"]
513 )
514 if "FutureChecker" not in self.__data: 492 if "FutureChecker" not in self.__data:
515 self.__data["FutureChecker"] = "" 493 self.__data["FutureChecker"] = ""
516 if "BuiltinsChecker" not in self.__data: 494 if "BuiltinsChecker" not in self.__data:
517 self.__data["BuiltinsChecker"] = copy.deepcopy( 495 self.__data["BuiltinsChecker"] = copy.deepcopy(
518 MiscellaneousCheckerDefaultArgs["BuiltinsChecker"] 496 MiscellaneousCheckerDefaultArgs["BuiltinsChecker"]
519 ) 497 )
520 498
521 if "CommentedCodeChecker" not in self.__data: 499 if "CommentedCodeChecker" not in self.__data:
522 self.__data["CommentedCodeChecker"] = copy.deepcopy( 500 self.__data["CommentedCodeChecker"] = copy.deepcopy(
523 MiscellaneousCheckerDefaultArgs["CommentedCodeChecker"] 501 MiscellaneousCheckerDefaultArgs["CommentedCodeChecker"]
524 ) 502 )
525 if "WhiteList" not in self.__data["CommentedCodeChecker"]: 503 if "WhiteList" not in self.__data["CommentedCodeChecker"]:
526 self.__data["CommentedCodeChecker"]["WhiteList"] = ( 504 self.__data["CommentedCodeChecker"][
527 MiscellaneousCheckerDefaultArgs[ 505 "WhiteList"
528 "CommentedCodeChecker"]["WhiteList"][:] 506 ] = MiscellaneousCheckerDefaultArgs["CommentedCodeChecker"]["WhiteList"][:]
529 ) 507
530
531 if "AnnotationsChecker" not in self.__data: 508 if "AnnotationsChecker" not in self.__data:
532 self.__data["AnnotationsChecker"] = copy.deepcopy( 509 self.__data["AnnotationsChecker"] = copy.deepcopy(
533 AnnotationsCheckerDefaultArgs) 510 AnnotationsCheckerDefaultArgs
511 )
534 else: 512 else:
535 # We are upgrading from an older data structure 513 # We are upgrading from an older data structure
536 if "MaximumLength" not in self.__data["AnnotationsChecker"]: 514 if "MaximumLength" not in self.__data["AnnotationsChecker"]:
537 # MaximumLength is the sentinel for the first extension 515 # MaximumLength is the sentinel for the first extension
538 self.__data["AnnotationsChecker"].update({ 516 self.__data["AnnotationsChecker"].update(
539 "MaximumLength": 517 {
540 AnnotationsCheckerDefaultArgs["MaximumLength"], 518 "MaximumLength": AnnotationsCheckerDefaultArgs["MaximumLength"],
541 "SuppressNoneReturning": 519 "SuppressNoneReturning": AnnotationsCheckerDefaultArgs[
542 AnnotationsCheckerDefaultArgs["SuppressNoneReturning"], 520 "SuppressNoneReturning"
543 "SuppressDummyArgs": 521 ],
544 AnnotationsCheckerDefaultArgs["SuppressDummyArgs"], 522 "SuppressDummyArgs": AnnotationsCheckerDefaultArgs[
545 "AllowUntypedDefs": 523 "SuppressDummyArgs"
546 AnnotationsCheckerDefaultArgs["AllowUntypedDefs"], 524 ],
547 "AllowUntypedNested": 525 "AllowUntypedDefs": AnnotationsCheckerDefaultArgs[
548 AnnotationsCheckerDefaultArgs["AllowUntypedNested"], 526 "AllowUntypedDefs"
549 "MypyInitReturn": 527 ],
550 AnnotationsCheckerDefaultArgs["MypyInitReturn"], 528 "AllowUntypedNested": AnnotationsCheckerDefaultArgs[
551 "DispatchDecorators": 529 "AllowUntypedNested"
552 AnnotationsCheckerDefaultArgs["DispatchDecorators"], 530 ],
553 "OverloadDecorators": 531 "MypyInitReturn": AnnotationsCheckerDefaultArgs[
554 AnnotationsCheckerDefaultArgs["OverloadDecorators"], 532 "MypyInitReturn"
555 }) 533 ],
556 534 "DispatchDecorators": AnnotationsCheckerDefaultArgs[
535 "DispatchDecorators"
536 ],
537 "OverloadDecorators": AnnotationsCheckerDefaultArgs[
538 "OverloadDecorators"
539 ],
540 }
541 )
542
557 if "SecurityChecker" not in self.__data: 543 if "SecurityChecker" not in self.__data:
558 from .Security.SecurityDefaults import SecurityDefaults 544 from .Security.SecurityDefaults import SecurityDefaults
545
559 self.__data["SecurityChecker"] = { 546 self.__data["SecurityChecker"] = {
560 "HardcodedTmpDirectories": 547 "HardcodedTmpDirectories": SecurityDefaults[
561 SecurityDefaults["hardcoded_tmp_directories"], 548 "hardcoded_tmp_directories"
562 "InsecureHashes": 549 ],
563 SecurityDefaults["insecure_hashes"], 550 "InsecureHashes": SecurityDefaults["insecure_hashes"],
564 "InsecureSslProtocolVersions": 551 "InsecureSslProtocolVersions": SecurityDefaults[
565 SecurityDefaults["insecure_ssl_protocol_versions"], 552 "insecure_ssl_protocol_versions"
566 "WeakKeySizeDsaHigh": 553 ],
567 str(SecurityDefaults["weak_key_size_dsa_high"]), 554 "WeakKeySizeDsaHigh": str(SecurityDefaults["weak_key_size_dsa_high"]),
568 "WeakKeySizeDsaMedium": 555 "WeakKeySizeDsaMedium": str(
569 str(SecurityDefaults["weak_key_size_dsa_medium"]), 556 SecurityDefaults["weak_key_size_dsa_medium"]
570 "WeakKeySizeRsaHigh": 557 ),
571 str(SecurityDefaults["weak_key_size_rsa_high"]), 558 "WeakKeySizeRsaHigh": str(SecurityDefaults["weak_key_size_rsa_high"]),
572 "WeakKeySizeRsaMedium": 559 "WeakKeySizeRsaMedium": str(
573 str(SecurityDefaults["weak_key_size_rsa_medium"]), 560 SecurityDefaults["weak_key_size_rsa_medium"]
574 "WeakKeySizeEcHigh": 561 ),
575 str(SecurityDefaults["weak_key_size_ec_high"]), 562 "WeakKeySizeEcHigh": str(SecurityDefaults["weak_key_size_ec_high"]),
576 "WeakKeySizeEcMedium": 563 "WeakKeySizeEcMedium": str(SecurityDefaults["weak_key_size_ec_medium"]),
577 str(SecurityDefaults["weak_key_size_ec_medium"]), 564 "CheckTypedException": SecurityDefaults["check_typed_exception"],
578 "CheckTypedException":
579 SecurityDefaults["check_typed_exception"],
580 } 565 }
581 566
582 if "ImportsChecker" not in self.__data: 567 if "ImportsChecker" not in self.__data:
583 self.__data["ImportsChecker"] = { 568 self.__data["ImportsChecker"] = {
584 "ApplicationPackageNames": [], 569 "ApplicationPackageNames": [],
585 "BannedModules": [], 570 "BannedModules": [],
586 "BanRelativeImports": "", 571 "BanRelativeImports": "",
587 } 572 }
588 573
589 self.__initCategoriesList(self.__data["EnabledCheckerCategories"]) 574 self.__initCategoriesList(self.__data["EnabledCheckerCategories"])
590 self.excludeFilesEdit.setText(self.__data["ExcludeFiles"]) 575 self.excludeFilesEdit.setText(self.__data["ExcludeFiles"])
591 self.excludeMessagesEdit.setText(self.__data["ExcludeMessages"]) 576 self.excludeMessagesEdit.setText(self.__data["ExcludeMessages"])
592 self.includeMessagesEdit.setText(self.__data["IncludeMessages"]) 577 self.includeMessagesEdit.setText(self.__data["IncludeMessages"])
593 self.repeatCheckBox.setChecked(self.__data["RepeatMessages"]) 578 self.repeatCheckBox.setChecked(self.__data["RepeatMessages"])
599 self.docLineLengthSpinBox.setValue(self.__data["MaxDocLineLength"]) 584 self.docLineLengthSpinBox.setValue(self.__data["MaxDocLineLength"])
600 self.blankBeforeTopLevelSpinBox.setValue(self.__data["BlankLines"][0]) 585 self.blankBeforeTopLevelSpinBox.setValue(self.__data["BlankLines"][0])
601 self.blankBeforeMethodSpinBox.setValue(self.__data["BlankLines"][1]) 586 self.blankBeforeMethodSpinBox.setValue(self.__data["BlankLines"][1])
602 self.hangClosingCheckBox.setChecked(self.__data["HangClosing"]) 587 self.hangClosingCheckBox.setChecked(self.__data["HangClosing"])
603 self.docTypeComboBox.setCurrentIndex( 588 self.docTypeComboBox.setCurrentIndex(
604 self.docTypeComboBox.findData(self.__data["DocstringType"])) 589 self.docTypeComboBox.findData(self.__data["DocstringType"])
590 )
605 self.complexitySpinBox.setValue(self.__data["MaxCodeComplexity"]) 591 self.complexitySpinBox.setValue(self.__data["MaxCodeComplexity"])
606 self.lineComplexitySpinBox.setValue(self.__data["LineComplexity"]) 592 self.lineComplexitySpinBox.setValue(self.__data["LineComplexity"])
607 self.lineComplexityScoreSpinBox.setValue( 593 self.lineComplexityScoreSpinBox.setValue(self.__data["LineComplexityScore"])
608 self.__data["LineComplexityScore"])
609 self.encodingsEdit.setText(self.__data["ValidEncodings"]) 594 self.encodingsEdit.setText(self.__data["ValidEncodings"])
610 self.copyrightFileSizeSpinBox.setValue( 595 self.copyrightFileSizeSpinBox.setValue(self.__data["CopyrightMinFileSize"])
611 self.__data["CopyrightMinFileSize"])
612 self.copyrightAuthorEdit.setText(self.__data["CopyrightAuthor"]) 596 self.copyrightAuthorEdit.setText(self.__data["CopyrightAuthor"])
613 self.__initFuturesList(self.__data["FutureChecker"]) 597 self.__initFuturesList(self.__data["FutureChecker"])
614 self.__initBuiltinsIgnoreList(self.__data["BuiltinsChecker"]) 598 self.__initBuiltinsIgnoreList(self.__data["BuiltinsChecker"])
615 self.aggressiveCheckBox.setChecked( 599 self.aggressiveCheckBox.setChecked(
616 self.__data["CommentedCodeChecker"]["Aggressive"]) 600 self.__data["CommentedCodeChecker"]["Aggressive"]
601 )
617 self.__initCommentedCodeCheckerWhiteList( 602 self.__initCommentedCodeCheckerWhiteList(
618 self.__data["CommentedCodeChecker"]["WhiteList"]) 603 self.__data["CommentedCodeChecker"]["WhiteList"]
619 604 )
605
620 # type annotations 606 # type annotations
621 self.minAnnotationsCoverageSpinBox.setValue( 607 self.minAnnotationsCoverageSpinBox.setValue(
622 self.__data["AnnotationsChecker"]["MinimumCoverage"]) 608 self.__data["AnnotationsChecker"]["MinimumCoverage"]
609 )
623 self.maxAnnotationsComplexitySpinBox.setValue( 610 self.maxAnnotationsComplexitySpinBox.setValue(
624 self.__data["AnnotationsChecker"]["MaximumComplexity"]) 611 self.__data["AnnotationsChecker"]["MaximumComplexity"]
612 )
625 self.maxAnnotationsLengthSpinBox.setValue( 613 self.maxAnnotationsLengthSpinBox.setValue(
626 self.__data["AnnotationsChecker"]["MaximumLength"]) 614 self.__data["AnnotationsChecker"]["MaximumLength"]
615 )
627 self.suppressNoneReturningCheckBox.setChecked( 616 self.suppressNoneReturningCheckBox.setChecked(
628 self.__data["AnnotationsChecker"]["SuppressNoneReturning"]) 617 self.__data["AnnotationsChecker"]["SuppressNoneReturning"]
618 )
629 self.suppressDummyArgsCheckBox.setChecked( 619 self.suppressDummyArgsCheckBox.setChecked(
630 self.__data["AnnotationsChecker"]["SuppressDummyArgs"]) 620 self.__data["AnnotationsChecker"]["SuppressDummyArgs"]
621 )
631 self.allowUntypedDefsCheckBox.setChecked( 622 self.allowUntypedDefsCheckBox.setChecked(
632 self.__data["AnnotationsChecker"]["AllowUntypedDefs"]) 623 self.__data["AnnotationsChecker"]["AllowUntypedDefs"]
624 )
633 self.allowUntypedNestedCheckBox.setChecked( 625 self.allowUntypedNestedCheckBox.setChecked(
634 self.__data["AnnotationsChecker"]["AllowUntypedNested"]) 626 self.__data["AnnotationsChecker"]["AllowUntypedNested"]
627 )
635 self.mypyInitReturnCheckBox.setChecked( 628 self.mypyInitReturnCheckBox.setChecked(
636 self.__data["AnnotationsChecker"]["MypyInitReturn"]) 629 self.__data["AnnotationsChecker"]["MypyInitReturn"]
630 )
637 self.dispatchDecoratorEdit.setText( 631 self.dispatchDecoratorEdit.setText(
638 ", ".join( 632 ", ".join(self.__data["AnnotationsChecker"]["DispatchDecorators"])
639 self.__data["AnnotationsChecker"]["DispatchDecorators"])) 633 )
640 self.overloadDecoratorEdit.setText( 634 self.overloadDecoratorEdit.setText(
641 ", ".join( 635 ", ".join(self.__data["AnnotationsChecker"]["OverloadDecorators"])
642 self.__data["AnnotationsChecker"]["OverloadDecorators"])) 636 )
643 637
644 # security 638 # security
645 self.tmpDirectoriesEdit.setPlainText("\n".join( 639 self.tmpDirectoriesEdit.setPlainText(
646 self.__data["SecurityChecker"]["HardcodedTmpDirectories"])) 640 "\n".join(self.__data["SecurityChecker"]["HardcodedTmpDirectories"])
647 self.hashesEdit.setText(", ".join( 641 )
648 self.__data["SecurityChecker"]["InsecureHashes"])) 642 self.hashesEdit.setText(
649 self.insecureSslProtocolsEdit.setPlainText("\n".join( 643 ", ".join(self.__data["SecurityChecker"]["InsecureHashes"])
650 self.__data["SecurityChecker"]["InsecureSslProtocolVersions"])) 644 )
645 self.insecureSslProtocolsEdit.setPlainText(
646 "\n".join(self.__data["SecurityChecker"]["InsecureSslProtocolVersions"])
647 )
651 self.dsaHighRiskCombo.setCurrentText( 648 self.dsaHighRiskCombo.setCurrentText(
652 self.__data["SecurityChecker"]["WeakKeySizeDsaHigh"]) 649 self.__data["SecurityChecker"]["WeakKeySizeDsaHigh"]
650 )
653 self.dsaMediumRiskCombo.setCurrentText( 651 self.dsaMediumRiskCombo.setCurrentText(
654 self.__data["SecurityChecker"]["WeakKeySizeDsaMedium"]) 652 self.__data["SecurityChecker"]["WeakKeySizeDsaMedium"]
653 )
655 self.rsaHighRiskCombo.setCurrentText( 654 self.rsaHighRiskCombo.setCurrentText(
656 self.__data["SecurityChecker"]["WeakKeySizeRsaHigh"]) 655 self.__data["SecurityChecker"]["WeakKeySizeRsaHigh"]
656 )
657 self.rsaMediumRiskCombo.setCurrentText( 657 self.rsaMediumRiskCombo.setCurrentText(
658 self.__data["SecurityChecker"]["WeakKeySizeRsaMedium"]) 658 self.__data["SecurityChecker"]["WeakKeySizeRsaMedium"]
659 )
659 self.ecHighRiskCombo.setCurrentText( 660 self.ecHighRiskCombo.setCurrentText(
660 self.__data["SecurityChecker"]["WeakKeySizeEcHigh"]) 661 self.__data["SecurityChecker"]["WeakKeySizeEcHigh"]
662 )
661 self.ecMediumRiskCombo.setCurrentText( 663 self.ecMediumRiskCombo.setCurrentText(
662 self.__data["SecurityChecker"]["WeakKeySizeEcMedium"]) 664 self.__data["SecurityChecker"]["WeakKeySizeEcMedium"]
665 )
663 self.typedExceptionsCheckBox.setChecked( 666 self.typedExceptionsCheckBox.setChecked(
664 self.__data["SecurityChecker"]["CheckTypedException"]) 667 self.__data["SecurityChecker"]["CheckTypedException"]
665 668 )
669
666 self.__cleanupData() 670 self.__cleanupData()
667 671
668 def __prepareProgress(self): 672 def __prepareProgress(self):
669 """ 673 """
670 Private method to prepare the progress tab for the next run. 674 Private method to prepare the progress tab for the next run.
671 """ 675 """
672 self.progressList.clear() 676 self.progressList.clear()
674 self.checkProgress.setMaximum(len(self.files)) 678 self.checkProgress.setMaximum(len(self.files))
675 self.checkProgressLabel.setVisible(len(self.files) > 1) 679 self.checkProgressLabel.setVisible(len(self.files) > 1)
676 self.checkProgress.setVisible(len(self.files) > 1) 680 self.checkProgress.setVisible(len(self.files) > 1)
677 if len(self.files) > 1: 681 if len(self.files) > 1:
678 if self.__project: 682 if self.__project:
679 self.progressList.addItems([ 683 self.progressList.addItems(
680 os.path.join("...", self.__project.getRelativePath(f)) 684 [
681 for f in self.files 685 os.path.join("...", self.__project.getRelativePath(f))
682 ]) 686 for f in self.files
687 ]
688 )
683 else: 689 else:
684 self.progressList.addItems(self.files) 690 self.progressList.addItems(self.files)
685 691
686 QApplication.processEvents() 692 QApplication.processEvents()
687 693
688 def start(self, fn, save=False, repeat=None): 694 def start(self, fn, save=False, repeat=None):
689 """ 695 """
690 Public slot to start the code style check. 696 Public slot to start the code style check.
691 697
692 @param fn file or list of files or directory to be checked 698 @param fn file or list of files or directory to be checked
693 @type str or list of str 699 @type str or list of str
694 @param save flag indicating to save the given file/file list/directory 700 @param save flag indicating to save the given file/file list/directory
695 @type bool 701 @type bool
696 @param repeat state of the repeat check box if it is not None 702 @param repeat state of the repeat check box if it is not None
697 @type None or bool 703 @type None or bool
698 """ 704 """
699 if self.__project is None: 705 if self.__project is None:
700 self.__project = ericApp().getObject("Project") 706 self.__project = ericApp().getObject("Project")
701 707
702 self.mainWidget.setCurrentWidget(self.progressTab) 708 self.mainWidget.setCurrentWidget(self.progressTab)
703 709
704 self.cancelled = False 710 self.cancelled = False
705 self.buttonBox.button( 711 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(False)
706 QDialogButtonBox.StandardButton.Close).setEnabled(False)
707 self.cancelButton.setEnabled(True) 712 self.cancelButton.setEnabled(True)
708 self.cancelButton.setDefault(True) 713 self.cancelButton.setDefault(True)
709 self.statisticsButton.setEnabled(False) 714 self.statisticsButton.setEnabled(False)
710 self.showButton.setEnabled(False) 715 self.showButton.setEnabled(False)
711 self.fixButton.setEnabled(False) 716 self.fixButton.setEnabled(False)
713 self.restartButton.setEnabled(False) 718 self.restartButton.setEnabled(False)
714 if repeat is not None: 719 if repeat is not None:
715 self.repeatCheckBox.setChecked(repeat) 720 self.repeatCheckBox.setChecked(repeat)
716 self.checkProgress.setVisible(True) 721 self.checkProgress.setVisible(True)
717 QApplication.processEvents() 722 QApplication.processEvents()
718 723
719 if save: 724 if save:
720 self.__fileOrFileList = fn 725 self.__fileOrFileList = fn
721 726
722 if isinstance(fn, list): 727 if isinstance(fn, list):
723 self.files = fn[:] 728 self.files = fn[:]
724 elif os.path.isdir(fn): 729 elif os.path.isdir(fn):
725 self.files = [] 730 self.files = []
726 extensions = set(Preferences.getPython("Python3Extensions")) 731 extensions = set(Preferences.getPython("Python3Extensions"))
727 for ext in extensions: 732 for ext in extensions:
728 self.files.extend(Utilities.direntries( 733 self.files.extend(Utilities.direntries(fn, True, "*{0}".format(ext), 0))
729 fn, True, '*{0}'.format(ext), 0))
730 else: 734 else:
731 self.files = [fn] 735 self.files = [fn]
732 736
733 # filter the list depending on the filter string 737 # filter the list depending on the filter string
734 if self.files: 738 if self.files:
735 filterString = self.excludeFilesEdit.text() 739 filterString = self.excludeFilesEdit.text()
736 filterList = [f.strip() for f in filterString.split(",") 740 filterList = [f.strip() for f in filterString.split(",") if f.strip()]
737 if f.strip()]
738 for fileFilter in filterList: 741 for fileFilter in filterList:
739 self.files = [ 742 self.files = [
740 f for f in self.files 743 f for f in self.files if not fnmatch.fnmatch(f, fileFilter.strip())
741 if not fnmatch.fnmatch(f, fileFilter.strip())
742 ] 744 ]
743 745
744 self.__errorItem = None 746 self.__errorItem = None
745 self.__resetStatistics() 747 self.__resetStatistics()
746 self.__clearErrors(self.files) 748 self.__clearErrors(self.files)
747 self.__cleanupData() 749 self.__cleanupData()
748 self.__prepareProgress() 750 self.__prepareProgress()
749 751
750 # disable updates of the list for speed 752 # disable updates of the list for speed
751 self.resultList.setUpdatesEnabled(False) 753 self.resultList.setUpdatesEnabled(False)
752 self.resultList.setSortingEnabled(False) 754 self.resultList.setSortingEnabled(False)
753 755
754 if len(self.files) > 0: 756 if len(self.files) > 0:
755 self.securityNoteLabel.setVisible( 757 self.securityNoteLabel.setVisible(
756 "S" in self.__getCategories(True, asList=True)) 758 "S" in self.__getCategories(True, asList=True)
757 759 )
760
758 # extract the configuration values 761 # extract the configuration values
759 excludeMessages = self.__assembleExcludeMessages() 762 excludeMessages = self.__assembleExcludeMessages()
760 includeMessages = self.includeMessagesEdit.text() 763 includeMessages = self.includeMessagesEdit.text()
761 repeatMessages = self.repeatCheckBox.isChecked() 764 repeatMessages = self.repeatCheckBox.isChecked()
762 fixCodes = self.fixIssuesEdit.text() 765 fixCodes = self.fixIssuesEdit.text()
763 noFixCodes = self.noFixIssuesEdit.text() 766 noFixCodes = self.noFixIssuesEdit.text()
764 self.__noFixCodesList = [ 767 self.__noFixCodesList = [
765 c.strip() for c in noFixCodes.split(",") if c.strip() 768 c.strip() for c in noFixCodes.split(",") if c.strip()
766 ] 769 ]
767 fixIssues = self.fixIssuesCheckBox.isChecked() and repeatMessages 770 fixIssues = self.fixIssuesCheckBox.isChecked() and repeatMessages
768 self.showIgnored = ( 771 self.showIgnored = self.ignoredCheckBox.isChecked() and repeatMessages
769 self.ignoredCheckBox.isChecked() and repeatMessages
770 )
771 maxLineLength = self.lineLengthSpinBox.value() 772 maxLineLength = self.lineLengthSpinBox.value()
772 maxDocLineLength = self.docLineLengthSpinBox.value() 773 maxDocLineLength = self.docLineLengthSpinBox.value()
773 blankLines = ( 774 blankLines = (
774 self.blankBeforeTopLevelSpinBox.value(), 775 self.blankBeforeTopLevelSpinBox.value(),
775 self.blankBeforeMethodSpinBox.value() 776 self.blankBeforeMethodSpinBox.value(),
776 ) 777 )
777 hangClosing = self.hangClosingCheckBox.isChecked() 778 hangClosing = self.hangClosingCheckBox.isChecked()
778 docType = self.docTypeComboBox.itemData( 779 docType = self.docTypeComboBox.itemData(self.docTypeComboBox.currentIndex())
779 self.docTypeComboBox.currentIndex())
780 codeComplexityArgs = { 780 codeComplexityArgs = {
781 "McCabeComplexity": self.complexitySpinBox.value(), 781 "McCabeComplexity": self.complexitySpinBox.value(),
782 "LineComplexity": self.lineComplexitySpinBox.value(), 782 "LineComplexity": self.lineComplexitySpinBox.value(),
783 "LineComplexityScore": self.lineComplexityScoreSpinBox.value(), 783 "LineComplexityScore": self.lineComplexityScoreSpinBox.value(),
784 } 784 }
791 "FutureChecker": self.__getSelectedFutureImports(), 791 "FutureChecker": self.__getSelectedFutureImports(),
792 "BuiltinsChecker": self.__getBuiltinsIgnoreList(), 792 "BuiltinsChecker": self.__getBuiltinsIgnoreList(),
793 "CommentedCodeChecker": { 793 "CommentedCodeChecker": {
794 "Aggressive": self.aggressiveCheckBox.isChecked(), 794 "Aggressive": self.aggressiveCheckBox.isChecked(),
795 "WhiteList": self.__getCommentedCodeCheckerWhiteList(), 795 "WhiteList": self.__getCommentedCodeCheckerWhiteList(),
796 } 796 },
797 } 797 }
798 798
799 annotationArgs = { 799 annotationArgs = {
800 "MinimumCoverage": 800 "MinimumCoverage": self.minAnnotationsCoverageSpinBox.value(),
801 self.minAnnotationsCoverageSpinBox.value(), 801 "MaximumComplexity": self.maxAnnotationsComplexitySpinBox.value(),
802 "MaximumComplexity": 802 "MaximumLength": self.maxAnnotationsLengthSpinBox.value(),
803 self.maxAnnotationsComplexitySpinBox.value(), 803 "SuppressNoneReturning": self.suppressNoneReturningCheckBox.isChecked(),
804 "MaximumLength": 804 "SuppressDummyArgs": self.suppressDummyArgsCheckBox.isChecked(),
805 self.maxAnnotationsLengthSpinBox.value(), 805 "AllowUntypedDefs": self.allowUntypedDefsCheckBox.isChecked(),
806 "SuppressNoneReturning": 806 "AllowUntypedNested": self.allowUntypedNestedCheckBox.isChecked(),
807 self.suppressNoneReturningCheckBox.isChecked(), 807 "MypyInitReturn": self.mypyInitReturnCheckBox.isChecked(),
808 "SuppressDummyArgs": 808 "DispatchDecorators": [
809 self.suppressDummyArgsCheckBox.isChecked(), 809 d.strip() for d in self.dispatchDecoratorEdit.text().split(",")
810 "AllowUntypedDefs": 810 ],
811 self.allowUntypedDefsCheckBox.isChecked(), 811 "OverloadDecorators": [
812 "AllowUntypedNested": 812 d.strip() for d in self.overloadDecoratorEdit.text().split(",")
813 self.allowUntypedNestedCheckBox.isChecked(), 813 ],
814 "MypyInitReturn":
815 self.mypyInitReturnCheckBox.isChecked(),
816 "DispatchDecorators":
817 [d.strip()
818 for d in self.dispatchDecoratorEdit.text().split(",")],
819 "OverloadDecorators":
820 [d.strip()
821 for d in self.overloadDecoratorEdit.text().split(",")],
822 } 814 }
823 815
824 securityArgs = { 816 securityArgs = {
825 "hardcoded_tmp_directories": [ 817 "hardcoded_tmp_directories": [
826 t.strip() 818 t.strip()
827 for t in self.tmpDirectoriesEdit.toPlainText().splitlines() 819 for t in self.tmpDirectoriesEdit.toPlainText().splitlines()
828 ], 820 ],
829 "insecure_hashes": [ 821 "insecure_hashes": [
830 h.strip() 822 h.strip() for h in self.hashesEdit.text().split(",")
831 for h in self.hashesEdit.text().split(",")
832 ], 823 ],
833 "insecure_ssl_protocol_versions": [ 824 "insecure_ssl_protocol_versions": [
834 p.strip() 825 p.strip()
835 for p in self.insecureSslProtocolsEdit.toPlainText() 826 for p in self.insecureSslProtocolsEdit.toPlainText().splitlines()
836 .splitlines()
837 ], 827 ],
838 "weak_key_size_dsa_high": 828 "weak_key_size_dsa_high": int(self.dsaHighRiskCombo.currentText()),
839 int(self.dsaHighRiskCombo.currentText()), 829 "weak_key_size_dsa_medium": int(self.dsaMediumRiskCombo.currentText()),
840 "weak_key_size_dsa_medium": 830 "weak_key_size_rsa_high": int(self.rsaHighRiskCombo.currentText()),
841 int(self.dsaMediumRiskCombo.currentText()), 831 "weak_key_size_rsa_medium": int(self.rsaMediumRiskCombo.currentText()),
842 "weak_key_size_rsa_high": 832 "weak_key_size_ec_high": int(self.ecHighRiskCombo.currentText()),
843 int(self.rsaHighRiskCombo.currentText()), 833 "weak_key_size_ec_medium": int(self.ecMediumRiskCombo.currentText()),
844 "weak_key_size_rsa_medium": 834 "check_typed_exception": self.typedExceptionsCheckBox.isChecked(),
845 int(self.rsaMediumRiskCombo.currentText()),
846 "weak_key_size_ec_high":
847 int(self.ecHighRiskCombo.currentText()),
848 "weak_key_size_ec_medium":
849 int(self.ecMediumRiskCombo.currentText()),
850 "check_typed_exception":
851 self.typedExceptionsCheckBox.isChecked(),
852 } 835 }
853 836
854 importsArgs = { 837 importsArgs = {
855 "ApplicationPackageNames": 838 "ApplicationPackageNames": sorted(
856 sorted(self.appPackagesEdit.toPlainText().split()), 839 self.appPackagesEdit.toPlainText().split()
857 "BannedModules": 840 ),
858 sorted(self.bannedModulesEdit.toPlainText().split()), 841 "BannedModules": sorted(self.bannedModulesEdit.toPlainText().split()),
859 "BanRelativeImports": self.__getBanRelativeImportsValue(), 842 "BanRelativeImports": self.__getBanRelativeImportsValue(),
860 } 843 }
861 844
862 self.__options = [excludeMessages, includeMessages, repeatMessages, 845 self.__options = [
863 fixCodes, noFixCodes, fixIssues, maxLineLength, 846 excludeMessages,
864 maxDocLineLength, blankLines, hangClosing, 847 includeMessages,
865 docType, codeComplexityArgs, miscellaneousArgs, 848 repeatMessages,
866 annotationArgs, securityArgs, importsArgs] 849 fixCodes,
867 850 noFixCodes,
851 fixIssues,
852 maxLineLength,
853 maxDocLineLength,
854 blankLines,
855 hangClosing,
856 docType,
857 codeComplexityArgs,
858 miscellaneousArgs,
859 annotationArgs,
860 securityArgs,
861 importsArgs,
862 ]
863
868 # now go through all the files 864 # now go through all the files
869 self.progress = 0 865 self.progress = 0
870 self.files.sort() 866 self.files.sort()
871 self.__timenow = time.monotonic() 867 self.__timenow = time.monotonic()
872 868
873 if len(self.files) == 1: 869 if len(self.files) == 1:
874 self.__batch = False 870 self.__batch = False
875 self.mainWidget.setCurrentWidget(self.resultsTab) 871 self.mainWidget.setCurrentWidget(self.resultsTab)
876 self.check() 872 self.check()
877 else: 873 else:
879 self.checkBatch() 875 self.checkBatch()
880 else: 876 else:
881 self.results = CodeStyleCheckerDialog.noFiles 877 self.results = CodeStyleCheckerDialog.noFiles
882 self.__finished = False 878 self.__finished = False
883 self.__finish() 879 self.__finish()
884 880
885 def __modifyOptions(self, source): 881 def __modifyOptions(self, source):
886 """ 882 """
887 Private method to modify the options based on eflag: entries. 883 Private method to modify the options based on eflag: entries.
888 884
889 This method looks for comment lines like '# eflag: noqa = M601' 885 This method looks for comment lines like '# eflag: noqa = M601'
890 at the end of the source in order to extend the list of excluded 886 at the end of the source in order to extend the list of excluded
891 messages for one file only. 887 messages for one file only.
892 888
893 @param source source text 889 @param source source text
894 @type list of str or str 890 @type list of str or str
895 @return list of checker options 891 @return list of checker options
896 @rtype list 892 @rtype list
897 """ 893 """
902 if excludeMessages: 898 if excludeMessages:
903 excludeMessages += "," 899 excludeMessages += ","
904 excludeMessages += flags["noqa"] 900 excludeMessages += flags["noqa"]
905 options[0] = excludeMessages 901 options[0] = excludeMessages
906 return options 902 return options
907 903
908 def check(self, codestring=''): 904 def check(self, codestring=""):
909 """ 905 """
910 Public method to start a style check for one file. 906 Public method to start a style check for one file.
911 907
912 The results are reported to the __processResult slot. 908 The results are reported to the __processResult slot.
913 909
914 @param codestring optional sourcestring 910 @param codestring optional sourcestring
915 @type str 911 @type str
916 """ 912 """
917 if not self.files: 913 if not self.files:
918 self.checkProgressLabel.setPath("") 914 self.checkProgressLabel.setPath("")
919 self.checkProgress.setMaximum(1) 915 self.checkProgress.setMaximum(1)
920 self.checkProgress.setValue(1) 916 self.checkProgress.setValue(1)
921 self.__finish() 917 self.__finish()
922 return 918 return
923 919
924 self.filename = self.files.pop(0) 920 self.filename = self.files.pop(0)
925 self.checkProgress.setValue(self.progress) 921 self.checkProgress.setValue(self.progress)
926 self.checkProgressLabel.setPath(self.filename) 922 self.checkProgressLabel.setPath(self.filename)
927 QApplication.processEvents() 923 QApplication.processEvents()
928 924
929 if self.cancelled: 925 if self.cancelled:
930 self.__resort() 926 self.__resort()
931 return 927 return
932 928
933 self.__lastFileItem = None 929 self.__lastFileItem = None
934 930
935 if codestring: 931 if codestring:
936 source = codestring.splitlines(True) 932 source = codestring.splitlines(True)
937 encoding = Utilities.get_coding(source) 933 encoding = Utilities.get_coding(source)
938 else: 934 else:
939 try: 935 try:
940 source, encoding = Utilities.readEncodedFile( 936 source, encoding = Utilities.readEncodedFile(self.filename)
941 self.filename)
942 source = source.splitlines(True) 937 source = source.splitlines(True)
943 except (UnicodeError, OSError) as msg: 938 except (UnicodeError, OSError) as msg:
944 self.results = CodeStyleCheckerDialog.hasResults 939 self.results = CodeStyleCheckerDialog.hasResults
945 self.__createFileErrorItem(self.filename, str(msg)) 940 self.__createFileErrorItem(self.filename, str(msg))
946 self.progress += 1 941 self.progress += 1
947 # Continue with next file 942 # Continue with next file
948 self.check() 943 self.check()
949 return 944 return
950 if encoding.endswith( 945 if encoding.endswith(("-selected", "-default", "-guessed", "-ignore")):
951 ('-selected', '-default', '-guessed', '-ignore')): 946 encoding = encoding.rsplit("-", 1)[0]
952 encoding = encoding.rsplit('-', 1)[0] 947
953
954 options = self.__modifyOptions(source) 948 options = self.__modifyOptions(source)
955 949
956 errors = [] 950 errors = []
957 self.__itms = [] 951 self.__itms = []
958 for error, itm in self.__onlyFixes.pop(self.filename, []): 952 for error, itm in self.__onlyFixes.pop(self.filename, []):
959 errors.append(error) 953 errors.append(error)
960 self.__itms.append(itm) 954 self.__itms.append(itm)
961 955
962 eol = self.__getEol(self.filename) 956 eol = self.__getEol(self.filename)
963 args = options + [ 957 args = options + [
964 errors, eol, encoding, Preferences.getEditor("CreateBackupFile") 958 errors,
959 eol,
960 encoding,
961 Preferences.getEditor("CreateBackupFile"),
965 ] 962 ]
966 self.__finished = False 963 self.__finished = False
967 self.styleCheckService.styleCheck( 964 self.styleCheckService.styleCheck(None, self.filename, source, args)
968 None, self.filename, source, args) 965
969
970 def checkBatch(self): 966 def checkBatch(self):
971 """ 967 """
972 Public method to start a style check batch job. 968 Public method to start a style check batch job.
973 969
974 The results are reported to the __processResult slot. 970 The results are reported to the __processResult slot.
975 """ 971 """
976 self.__lastFileItem = None 972 self.__lastFileItem = None
977 973
978 self.checkProgressLabel.setPath(self.tr("Preparing files...")) 974 self.checkProgressLabel.setPath(self.tr("Preparing files..."))
979 975
980 argumentsList = [] 976 argumentsList = []
981 for progress, filename in enumerate(self.files, start=1): 977 for progress, filename in enumerate(self.files, start=1):
982 self.checkProgress.setValue(progress) 978 self.checkProgress.setValue(progress)
983 if time.monotonic() - self.__timenow > 0.01: 979 if time.monotonic() - self.__timenow > 0.01:
984 QApplication.processEvents() 980 QApplication.processEvents()
985 self.__timenow = time.monotonic() 981 self.__timenow = time.monotonic()
986 982
987 try: 983 try:
988 source, encoding = Utilities.readEncodedFile( 984 source, encoding = Utilities.readEncodedFile(filename)
989 filename)
990 source = source.splitlines(True) 985 source = source.splitlines(True)
991 except (UnicodeError, OSError) as msg: 986 except (UnicodeError, OSError) as msg:
992 self.results = CodeStyleCheckerDialog.hasResults 987 self.results = CodeStyleCheckerDialog.hasResults
993 self.__createFileErrorItem(filename, str(msg)) 988 self.__createFileErrorItem(filename, str(msg))
994 continue 989 continue
995 990
996 if encoding.endswith( 991 if encoding.endswith(("-selected", "-default", "-guessed", "-ignore")):
997 ('-selected', '-default', '-guessed', '-ignore')): 992 encoding = encoding.rsplit("-", 1)[0]
998 encoding = encoding.rsplit('-', 1)[0] 993
999
1000 options = self.__modifyOptions(source) 994 options = self.__modifyOptions(source)
1001 995
1002 errors = [] 996 errors = []
1003 self.__itms = [] 997 self.__itms = []
1004 for error, itm in self.__onlyFixes.pop(filename, []): 998 for error, itm in self.__onlyFixes.pop(filename, []):
1005 errors.append(error) 999 errors.append(error)
1006 self.__itms.append(itm) 1000 self.__itms.append(itm)
1007 1001
1008 eol = self.__getEol(filename) 1002 eol = self.__getEol(filename)
1009 args = options + [ 1003 args = options + [
1010 errors, eol, encoding, 1004 errors,
1011 Preferences.getEditor("CreateBackupFile") 1005 eol,
1006 encoding,
1007 Preferences.getEditor("CreateBackupFile"),
1012 ] 1008 ]
1013 argumentsList.append((filename, source, args)) 1009 argumentsList.append((filename, source, args))
1014 1010
1015 # reset the progress bar to the checked files 1011 # reset the progress bar to the checked files
1016 self.checkProgress.setValue(self.progress) 1012 self.checkProgress.setValue(self.progress)
1017 self.checkProgressLabel.setPath(self.tr("Transferring data...")) 1013 self.checkProgressLabel.setPath(self.tr("Transferring data..."))
1018 QApplication.processEvents() 1014 QApplication.processEvents()
1019 1015
1020 self.__finished = False 1016 self.__finished = False
1021 self.styleCheckService.styleBatchCheck(argumentsList) 1017 self.styleCheckService.styleBatchCheck(argumentsList)
1022 1018
1023 def __batchFinished(self): 1019 def __batchFinished(self):
1024 """ 1020 """
1025 Private slot handling the completion of a batch job. 1021 Private slot handling the completion of a batch job.
1026 """ 1022 """
1027 self.checkProgressLabel.setPath("") 1023 self.checkProgressLabel.setPath("")
1028 self.checkProgress.setMaximum(1) 1024 self.checkProgress.setMaximum(1)
1029 self.checkProgress.setValue(1) 1025 self.checkProgress.setValue(1)
1030 self.__finish() 1026 self.__finish()
1031 1027
1032 def __processError(self, fn, msg): 1028 def __processError(self, fn, msg):
1033 """ 1029 """
1034 Private slot to process an error indication from the service. 1030 Private slot to process an error indication from the service.
1035 1031
1036 @param fn filename of the file 1032 @param fn filename of the file
1037 @type str 1033 @type str
1038 @param msg error message 1034 @param msg error message
1039 @type str 1035 @type str
1040 """ 1036 """
1041 self.__createErrorItem(fn, msg) 1037 self.__createErrorItem(fn, msg)
1042 1038
1043 if not self.__batch: 1039 if not self.__batch:
1044 self.check() 1040 self.check()
1045 1041
1046 def __processResult(self, fn, codeStyleCheckerStats, fixes, results): 1042 def __processResult(self, fn, codeStyleCheckerStats, fixes, results):
1047 """ 1043 """
1048 Private slot called after perfoming a style check on one file. 1044 Private slot called after perfoming a style check on one file.
1049 1045
1050 @param fn filename of the just checked file 1046 @param fn filename of the just checked file
1051 @type str 1047 @type str
1052 @param codeStyleCheckerStats stats of style and name check 1048 @param codeStyleCheckerStats stats of style and name check
1053 @type dict 1049 @type dict
1054 @param fixes number of applied fixes 1050 @param fixes number of applied fixes
1056 @param results dictionary containing check result data 1052 @param results dictionary containing check result data
1057 @type dict 1053 @type dict
1058 """ 1054 """
1059 if self.__finished: 1055 if self.__finished:
1060 return 1056 return
1061 1057
1062 # Check if it's the requested file, otherwise ignore signal if not 1058 # Check if it's the requested file, otherwise ignore signal if not
1063 # in batch mode 1059 # in batch mode
1064 if not self.__batch and fn != self.filename: 1060 if not self.__batch and fn != self.filename:
1065 return 1061 return
1066 1062
1067 fixed = None 1063 fixed = None
1068 ignoredErrors = collections.defaultdict(int) 1064 ignoredErrors = collections.defaultdict(int)
1069 securityOk = 0 1065 securityOk = 0
1070 if self.__itms: 1066 if self.__itms:
1071 for itm, result in zip(self.__itms, results): 1067 for itm, result in zip(self.__itms, results):
1072 self.__modifyFixedResultItem(itm, result) 1068 self.__modifyFixedResultItem(itm, result)
1073 self.__updateFixerStatistics(fixes) 1069 self.__updateFixerStatistics(fixes)
1074 else: 1070 else:
1075 self.__lastFileItem = None 1071 self.__lastFileItem = None
1076 1072
1077 for result in results: 1073 for result in results:
1078 if result["ignored"]: 1074 if result["ignored"]:
1079 ignoredErrors[result["code"]] += 1 1075 ignoredErrors[result["code"]] += 1
1080 if self.showIgnored: 1076 if self.showIgnored:
1081 result["display"] = self.tr( 1077 result["display"] = self.tr("{0} (ignored)").format(
1082 "{0} (ignored)" 1078 result["display"]
1083 ).format(result["display"]) 1079 )
1084 else: 1080 else:
1085 continue 1081 continue
1086 1082
1087 elif result["securityOk"]: 1083 elif result["securityOk"]:
1088 securityOk += 1 1084 securityOk += 1
1089 if result["code"].startswith("S"): 1085 if result["code"].startswith("S"):
1090 continue 1086 continue
1091 1087
1092 self.results = CodeStyleCheckerDialog.hasResults 1088 self.results = CodeStyleCheckerDialog.hasResults
1093 self.__createResultItem(fn, result) 1089 self.__createResultItem(fn, result)
1094 1090
1095 self.__updateStatistics( 1091 self.__updateStatistics(
1096 codeStyleCheckerStats, fixes, ignoredErrors, securityOk) 1092 codeStyleCheckerStats, fixes, ignoredErrors, securityOk
1097 1093 )
1094
1098 if fixed: 1095 if fixed:
1099 vm = ericApp().getObject("ViewManager") 1096 vm = ericApp().getObject("ViewManager")
1100 editor = vm.getOpenEditor(fn) 1097 editor = vm.getOpenEditor(fn)
1101 if editor: 1098 if editor:
1102 editor.refresh() 1099 editor.refresh()
1103 1100
1104 self.progress += 1 1101 self.progress += 1
1105 self.__updateProgress(fn) 1102 self.__updateProgress(fn)
1106 1103
1107 if not self.__batch: 1104 if not self.__batch:
1108 self.check() 1105 self.check()
1109 1106
1110 def __updateProgress(self, fn): 1107 def __updateProgress(self, fn):
1111 """ 1108 """
1112 Private method to update the progress tab. 1109 Private method to update the progress tab.
1113 1110
1114 @param fn filename of the just checked file 1111 @param fn filename of the just checked file
1115 @type str 1112 @type str
1116 """ 1113 """
1117 if self.__project: 1114 if self.__project:
1118 fn = os.path.join("...", self.__project.getRelativePath(fn)) 1115 fn = os.path.join("...", self.__project.getRelativePath(fn))
1119 1116
1120 self.checkProgress.setValue(self.progress) 1117 self.checkProgress.setValue(self.progress)
1121 self.checkProgressLabel.setPath(fn) 1118 self.checkProgressLabel.setPath(fn)
1122 1119
1123 # remove file from the list of jobs to do 1120 # remove file from the list of jobs to do
1124 fileItems = self.progressList.findItems(fn, Qt.MatchFlag.MatchExactly) 1121 fileItems = self.progressList.findItems(fn, Qt.MatchFlag.MatchExactly)
1125 if fileItems: 1122 if fileItems:
1126 row = self.progressList.row(fileItems[0]) 1123 row = self.progressList.row(fileItems[0])
1127 self.progressList.takeItem(row) 1124 self.progressList.takeItem(row)
1128 1125
1129 if time.monotonic() - self.__timenow > 0.01: 1126 if time.monotonic() - self.__timenow > 0.01:
1130 QApplication.processEvents() 1127 QApplication.processEvents()
1131 self.__timenow = time.monotonic() 1128 self.__timenow = time.monotonic()
1132 1129
1133 def __finish(self): 1130 def __finish(self):
1134 """ 1131 """
1135 Private slot called when the code style check finished or the user 1132 Private slot called when the code style check finished or the user
1136 pressed the cancel button. 1133 pressed the cancel button.
1137 """ 1134 """
1138 if not self.__finished: 1135 if not self.__finished:
1139 self.__finished = True 1136 self.__finished = True
1140 1137
1141 self.cancelled = True 1138 self.cancelled = True
1142 self.buttonBox.button( 1139 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(
1143 QDialogButtonBox.StandardButton.Close).setEnabled(True) 1140 True
1144 self.buttonBox.button( 1141 )
1145 QDialogButtonBox.StandardButton.Close).setDefault(True) 1142 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setDefault(
1143 True
1144 )
1146 self.cancelButton.setEnabled(False) 1145 self.cancelButton.setEnabled(False)
1147 self.statisticsButton.setEnabled(True) 1146 self.statisticsButton.setEnabled(True)
1148 self.showButton.setEnabled(True) 1147 self.showButton.setEnabled(True)
1149 self.startButton.setEnabled(True) 1148 self.startButton.setEnabled(True)
1150 self.restartButton.setEnabled(True) 1149 self.restartButton.setEnabled(True)
1151 1150
1152 if self.results != CodeStyleCheckerDialog.hasResults: 1151 if self.results != CodeStyleCheckerDialog.hasResults:
1153 if self.results == CodeStyleCheckerDialog.noResults: 1152 if self.results == CodeStyleCheckerDialog.noResults:
1154 QTreeWidgetItem( 1153 QTreeWidgetItem(self.resultList, [self.tr("No issues found.")])
1155 self.resultList, [self.tr('No issues found.')])
1156 else: 1154 else:
1157 QTreeWidgetItem( 1155 QTreeWidgetItem(
1158 self.resultList, 1156 self.resultList,
1159 [self.tr('No files found (check your ignore list).')]) 1157 [self.tr("No files found (check your ignore list).")],
1158 )
1160 QApplication.processEvents() 1159 QApplication.processEvents()
1161 self.showButton.setEnabled(False) 1160 self.showButton.setEnabled(False)
1162 else: 1161 else:
1163 self.showButton.setEnabled(True) 1162 self.showButton.setEnabled(True)
1164 for col in range(self.resultList.columnCount()): 1163 for col in range(self.resultList.columnCount()):
1165 self.resultList.resizeColumnToContents(col) 1164 self.resultList.resizeColumnToContents(col)
1166 self.resultList.header().setStretchLastSection(True) 1165 self.resultList.header().setStretchLastSection(True)
1167 1166
1168 if self.__detectedCodes: 1167 if self.__detectedCodes:
1169 self.filterComboBox.addItem("") 1168 self.filterComboBox.addItem("")
1170 self.filterComboBox.addItems(sorted(set(self.__detectedCodes))) 1169 self.filterComboBox.addItems(sorted(set(self.__detectedCodes)))
1171 self.filterComboBox.setEnabled(True) 1170 self.filterComboBox.setEnabled(True)
1172 self.filterButton.setEnabled(True) 1171 self.filterButton.setEnabled(True)
1173 1172
1174 self.checkProgress.setVisible(False) 1173 self.checkProgress.setVisible(False)
1175 self.checkProgressLabel.setVisible(False) 1174 self.checkProgressLabel.setVisible(False)
1176 1175
1177 self.__resort() 1176 self.__resort()
1178 self.resultList.setUpdatesEnabled(True) 1177 self.resultList.setUpdatesEnabled(True)
1179 self.resultList.setSortingEnabled(True) 1178 self.resultList.setSortingEnabled(True)
1180 1179
1181 self.mainWidget.setCurrentWidget(self.resultsTab) 1180 self.mainWidget.setCurrentWidget(self.resultsTab)
1182 1181
1183 def __getEol(self, fn): 1182 def __getEol(self, fn):
1184 """ 1183 """
1185 Private method to get the applicable eol string. 1184 Private method to get the applicable eol string.
1186 1185
1187 @param fn filename where to determine the line ending 1186 @param fn filename where to determine the line ending
1188 @type str 1187 @type str
1189 @return eol string 1188 @return eol string
1190 @rtype str 1189 @rtype str
1191 """ 1190 """
1193 self.__project.getEolString() 1192 self.__project.getEolString()
1194 if self.__project.isOpen() and self.__project.isProjectFile(fn) 1193 if self.__project.isOpen() and self.__project.isProjectFile(fn)
1195 else Utilities.linesep() 1194 else Utilities.linesep()
1196 ) 1195 )
1197 return eol 1196 return eol
1198 1197
1199 @pyqtSlot() 1198 @pyqtSlot()
1200 def on_startButton_clicked(self): 1199 def on_startButton_clicked(self):
1201 """ 1200 """
1202 Private slot to start a code style check run. 1201 Private slot to start a code style check run.
1203 """ 1202 """
1204 self.__cleanupData() 1203 self.__cleanupData()
1205 1204
1206 if self.__forProject: 1205 if self.__forProject:
1207 data = { 1206 data = {
1208 "EnabledCheckerCategories": self.__getCategories(True), 1207 "EnabledCheckerCategories": self.__getCategories(True),
1209 "ExcludeFiles": self.excludeFilesEdit.text(), 1208 "ExcludeFiles": self.excludeFilesEdit.text(),
1210 "ExcludeMessages": self.excludeMessagesEdit.text(), 1209 "ExcludeMessages": self.excludeMessagesEdit.text(),
1216 "ShowIgnored": self.ignoredCheckBox.isChecked(), 1215 "ShowIgnored": self.ignoredCheckBox.isChecked(),
1217 "MaxLineLength": self.lineLengthSpinBox.value(), 1216 "MaxLineLength": self.lineLengthSpinBox.value(),
1218 "MaxDocLineLength": self.docLineLengthSpinBox.value(), 1217 "MaxDocLineLength": self.docLineLengthSpinBox.value(),
1219 "BlankLines": ( 1218 "BlankLines": (
1220 self.blankBeforeTopLevelSpinBox.value(), 1219 self.blankBeforeTopLevelSpinBox.value(),
1221 self.blankBeforeMethodSpinBox.value() 1220 self.blankBeforeMethodSpinBox.value(),
1222 ), 1221 ),
1223 "HangClosing": self.hangClosingCheckBox.isChecked(), 1222 "HangClosing": self.hangClosingCheckBox.isChecked(),
1224 "DocstringType": self.docTypeComboBox.itemData( 1223 "DocstringType": self.docTypeComboBox.itemData(
1225 self.docTypeComboBox.currentIndex()), 1224 self.docTypeComboBox.currentIndex()
1225 ),
1226 "MaxCodeComplexity": self.complexitySpinBox.value(), 1226 "MaxCodeComplexity": self.complexitySpinBox.value(),
1227 "LineComplexity": self.lineComplexitySpinBox.value(), 1227 "LineComplexity": self.lineComplexitySpinBox.value(),
1228 "LineComplexityScore": self.lineComplexityScoreSpinBox.value(), 1228 "LineComplexityScore": self.lineComplexityScoreSpinBox.value(),
1229 "ValidEncodings": self.encodingsEdit.text(), 1229 "ValidEncodings": self.encodingsEdit.text(),
1230 "CopyrightMinFileSize": self.copyrightFileSizeSpinBox.value(), 1230 "CopyrightMinFileSize": self.copyrightFileSizeSpinBox.value(),
1234 "CommentedCodeChecker": { 1234 "CommentedCodeChecker": {
1235 "Aggressive": self.aggressiveCheckBox.isChecked(), 1235 "Aggressive": self.aggressiveCheckBox.isChecked(),
1236 "WhiteList": self.__getCommentedCodeCheckerWhiteList(), 1236 "WhiteList": self.__getCommentedCodeCheckerWhiteList(),
1237 }, 1237 },
1238 "AnnotationsChecker": { 1238 "AnnotationsChecker": {
1239 "MinimumCoverage": 1239 "MinimumCoverage": self.minAnnotationsCoverageSpinBox.value(),
1240 self.minAnnotationsCoverageSpinBox.value(), 1240 "MaximumComplexity": self.maxAnnotationsComplexitySpinBox.value(),
1241 "MaximumComplexity": 1241 "MaximumLength": self.maxAnnotationsLengthSpinBox.value(),
1242 self.maxAnnotationsComplexitySpinBox.value(), 1242 "SuppressNoneReturning": (
1243 "MaximumLength": 1243 self.suppressNoneReturningCheckBox.isChecked()
1244 self.maxAnnotationsLengthSpinBox.value(), 1244 ),
1245 "SuppressNoneReturning": 1245 "SuppressDummyArgs": self.suppressDummyArgsCheckBox.isChecked(),
1246 self.suppressNoneReturningCheckBox.isChecked(), 1246 "AllowUntypedDefs": self.allowUntypedDefsCheckBox.isChecked(),
1247 "SuppressDummyArgs": 1247 "AllowUntypedNested": self.allowUntypedNestedCheckBox.isChecked(),
1248 self.suppressDummyArgsCheckBox.isChecked(), 1248 "MypyInitReturn": self.mypyInitReturnCheckBox.isChecked(),
1249 "AllowUntypedDefs": 1249 "DispatchDecorators": [
1250 self.allowUntypedDefsCheckBox.isChecked(), 1250 d.strip() for d in self.dispatchDecoratorEdit.text().split(",")
1251 "AllowUntypedNested": 1251 ],
1252 self.allowUntypedNestedCheckBox.isChecked(), 1252 "OverloadDecorators": [
1253 "MypyInitReturn": 1253 d.strip() for d in self.overloadDecoratorEdit.text().split(",")
1254 self.mypyInitReturnCheckBox.isChecked(), 1254 ],
1255 "DispatchDecorators":
1256 [d.strip()
1257 for d in self.dispatchDecoratorEdit.text().split(",")
1258 ],
1259 "OverloadDecorators":
1260 [d.strip()
1261 for d in self.overloadDecoratorEdit.text().split(",")
1262 ],
1263 }, 1255 },
1264 "SecurityChecker": { 1256 "SecurityChecker": {
1265 "HardcodedTmpDirectories": [ 1257 "HardcodedTmpDirectories": [
1266 t.strip() 1258 t.strip()
1267 for t in self.tmpDirectoriesEdit.toPlainText() 1259 for t in self.tmpDirectoriesEdit.toPlainText().splitlines()
1268 .splitlines()
1269 ], 1260 ],
1270 "InsecureHashes": [ 1261 "InsecureHashes": [
1271 h.strip() 1262 h.strip() for h in self.hashesEdit.text().split(",")
1272 for h in self.hashesEdit.text().split(",")
1273 ], 1263 ],
1274 "InsecureSslProtocolVersions": [ 1264 "InsecureSslProtocolVersions": [
1275 p.strip() 1265 p.strip()
1276 for p in self.insecureSslProtocolsEdit.toPlainText() 1266 for p in (
1277 .splitlines() 1267 self.insecureSslProtocolsEdit.toPlainText().splitlines()
1268 )
1278 ], 1269 ],
1279 "WeakKeySizeDsaHigh": 1270 "WeakKeySizeDsaHigh": self.dsaHighRiskCombo.currentText(),
1280 self.dsaHighRiskCombo.currentText(), 1271 "WeakKeySizeDsaMedium": self.dsaMediumRiskCombo.currentText(),
1281 "WeakKeySizeDsaMedium": 1272 "WeakKeySizeRsaHigh": self.rsaHighRiskCombo.currentText(),
1282 self.dsaMediumRiskCombo.currentText(), 1273 "WeakKeySizeRsaMedium": self.rsaMediumRiskCombo.currentText(),
1283 "WeakKeySizeRsaHigh": 1274 "WeakKeySizeEcHigh": self.ecHighRiskCombo.currentText(),
1284 self.rsaHighRiskCombo.currentText(), 1275 "WeakKeySizeEcMedium": self.ecMediumRiskCombo.currentText(),
1285 "WeakKeySizeRsaMedium": 1276 "CheckTypedException": self.typedExceptionsCheckBox.isChecked(),
1286 self.rsaMediumRiskCombo.currentText(),
1287 "WeakKeySizeEcHigh":
1288 self.ecHighRiskCombo.currentText(),
1289 "WeakKeySizeEcMedium":
1290 self.ecMediumRiskCombo.currentText(),
1291 "CheckTypedException":
1292 self.typedExceptionsCheckBox.isChecked(),
1293 }, 1277 },
1294 "ImportsChecker": { 1278 "ImportsChecker": {
1295 "ApplicationPackageNames": 1279 "ApplicationPackageNames": sorted(
1296 sorted(self.appPackagesEdit.toPlainText().split()), 1280 self.appPackagesEdit.toPlainText().split()
1297 "BannedModules": 1281 ),
1298 sorted(self.bannedModulesEdit.toPlainText().split()), 1282 "BannedModules": sorted(
1283 self.bannedModulesEdit.toPlainText().split()
1284 ),
1299 "BanRelativeImports": self.__getBanRelativeImportsValue(), 1285 "BanRelativeImports": self.__getBanRelativeImportsValue(),
1300 }, 1286 },
1301 } 1287 }
1302 if ( 1288 if json.dumps(data, sort_keys=True) != json.dumps(
1303 json.dumps(data, sort_keys=True) != 1289 self.__data, sort_keys=True
1304 json.dumps(self.__data, sort_keys=True)
1305 ): 1290 ):
1306 self.__data = data 1291 self.__data = data
1307 self.__project.setData("CHECKERSPARMS", "Pep8Checker", 1292 self.__project.setData("CHECKERSPARMS", "Pep8Checker", self.__data)
1308 self.__data) 1293
1309
1310 self.resultList.clear() 1294 self.resultList.clear()
1311 self.results = CodeStyleCheckerDialog.noResults 1295 self.results = CodeStyleCheckerDialog.noResults
1312 self.cancelled = False 1296 self.cancelled = False
1313 self.__detectedCodes.clear() 1297 self.__detectedCodes.clear()
1314 self.filterComboBox.clear() 1298 self.filterComboBox.clear()
1315 self.filterComboBox.setEnabled(False) 1299 self.filterComboBox.setEnabled(False)
1316 self.filterButton.setEnabled(False) 1300 self.filterButton.setEnabled(False)
1317 1301
1318 self.start(self.__fileOrFileList) 1302 self.start(self.__fileOrFileList)
1319 1303
1320 @pyqtSlot() 1304 @pyqtSlot()
1321 def on_restartButton_clicked(self): 1305 def on_restartButton_clicked(self):
1322 """ 1306 """
1323 Private slot to restart a code style check run. 1307 Private slot to restart a code style check run.
1324 """ 1308 """
1325 self.on_startButton_clicked() 1309 self.on_startButton_clicked()
1326 1310
1327 def __selectCodes(self, edit, categories, showFixCodes): 1311 def __selectCodes(self, edit, categories, showFixCodes):
1328 """ 1312 """
1329 Private method to select message codes via a selection dialog. 1313 Private method to select message codes via a selection dialog.
1330 1314
1331 @param edit reference of the line edit to be populated 1315 @param edit reference of the line edit to be populated
1332 @type QLineEdit 1316 @type QLineEdit
1333 @param categories list of message categories to omit 1317 @param categories list of message categories to omit
1334 @type list of str 1318 @type list of str
1335 @param showFixCodes flag indicating to show a list of fixable 1319 @param showFixCodes flag indicating to show a list of fixable
1336 issues 1320 issues
1337 @type bool 1321 @type bool
1338 """ 1322 """
1339 from .CodeStyleCodeSelectionDialog import CodeStyleCodeSelectionDialog 1323 from .CodeStyleCodeSelectionDialog import CodeStyleCodeSelectionDialog
1340 dlg = CodeStyleCodeSelectionDialog(edit.text(), categories, 1324
1341 showFixCodes, self) 1325 dlg = CodeStyleCodeSelectionDialog(edit.text(), categories, showFixCodes, self)
1342 if dlg.exec() == QDialog.DialogCode.Accepted: 1326 if dlg.exec() == QDialog.DialogCode.Accepted:
1343 edit.setText(dlg.getSelectedCodes()) 1327 edit.setText(dlg.getSelectedCodes())
1344 1328
1345 @pyqtSlot() 1329 @pyqtSlot()
1346 def on_excludeMessagesSelectButton_clicked(self): 1330 def on_excludeMessagesSelectButton_clicked(self):
1347 """ 1331 """
1348 Private slot to select the message codes to be excluded via a 1332 Private slot to select the message codes to be excluded via a
1349 selection dialog. 1333 selection dialog.
1350 """ 1334 """
1351 self.__selectCodes(self.excludeMessagesEdit, 1335 self.__selectCodes(
1352 self.__getCategories(False, asList=True), 1336 self.excludeMessagesEdit, self.__getCategories(False, asList=True), False
1353 False) 1337 )
1354 1338
1355 @pyqtSlot() 1339 @pyqtSlot()
1356 def on_includeMessagesSelectButton_clicked(self): 1340 def on_includeMessagesSelectButton_clicked(self):
1357 """ 1341 """
1358 Private slot to select the message codes to be included via a 1342 Private slot to select the message codes to be included via a
1359 selection dialog. 1343 selection dialog.
1360 """ 1344 """
1361 self.__selectCodes(self.includeMessagesEdit, 1345 self.__selectCodes(
1362 self.__getCategories(True, asList=True), 1346 self.includeMessagesEdit, self.__getCategories(True, asList=True), False
1363 False) 1347 )
1364 1348
1365 @pyqtSlot() 1349 @pyqtSlot()
1366 def on_fixIssuesSelectButton_clicked(self): 1350 def on_fixIssuesSelectButton_clicked(self):
1367 """ 1351 """
1368 Private slot to select the issue codes to be fixed via a 1352 Private slot to select the issue codes to be fixed via a
1369 selection dialog. 1353 selection dialog.
1370 """ 1354 """
1371 self.__selectCodes(self.fixIssuesEdit, [], True) 1355 self.__selectCodes(self.fixIssuesEdit, [], True)
1372 1356
1373 @pyqtSlot() 1357 @pyqtSlot()
1374 def on_noFixIssuesSelectButton_clicked(self): 1358 def on_noFixIssuesSelectButton_clicked(self):
1375 """ 1359 """
1376 Private slot to select the issue codes not to be fixed via a 1360 Private slot to select the issue codes not to be fixed via a
1377 selection dialog. 1361 selection dialog.
1378 """ 1362 """
1379 self.__selectCodes(self.noFixIssuesEdit, [], True) 1363 self.__selectCodes(self.noFixIssuesEdit, [], True)
1380 1364
1381 @pyqtSlot(QTreeWidgetItem, int) 1365 @pyqtSlot(QTreeWidgetItem, int)
1382 def on_resultList_itemActivated(self, item, column): 1366 def on_resultList_itemActivated(self, item, column):
1383 """ 1367 """
1384 Private slot to handle the activation of an item. 1368 Private slot to handle the activation of an item.
1385 1369
1386 @param item reference to the activated item 1370 @param item reference to the activated item
1387 @type QTreeWidgetItem 1371 @type QTreeWidgetItem
1388 @param column column the item was activated in 1372 @param column column the item was activated in
1389 @type int 1373 @type int
1390 """ 1374 """
1391 if self.results != CodeStyleCheckerDialog.hasResults: 1375 if self.results != CodeStyleCheckerDialog.hasResults:
1392 return 1376 return
1393 1377
1394 if item.parent(): 1378 if item.parent():
1395 fn = os.path.abspath(item.data(0, self.filenameRole)) 1379 fn = os.path.abspath(item.data(0, self.filenameRole))
1396 lineno = item.data(0, self.lineRole) 1380 lineno = item.data(0, self.lineRole)
1397 position = item.data(0, self.positionRole) 1381 position = item.data(0, self.positionRole)
1398 message = item.data(0, self.messageRole) 1382 message = item.data(0, self.messageRole)
1399 code = item.data(0, self.codeRole) 1383 code = item.data(0, self.codeRole)
1400 1384
1401 vm = ericApp().getObject("ViewManager") 1385 vm = ericApp().getObject("ViewManager")
1402 vm.openSourceFile(fn, lineno=lineno, pos=position + 1) 1386 vm.openSourceFile(fn, lineno=lineno, pos=position + 1)
1403 editor = vm.getOpenEditor(fn) 1387 editor = vm.getOpenEditor(fn)
1404 1388
1405 if code in ["E901", "E902"]: 1389 if code in ["E901", "E902"]:
1406 editor.toggleSyntaxError(lineno, 0, True, message, True) 1390 editor.toggleSyntaxError(lineno, 0, True, message, True)
1407 else: 1391 else:
1408 editor.toggleWarning( 1392 editor.toggleWarning(
1409 lineno, 0, True, message, warningType=editor.WarningStyle) 1393 lineno, 0, True, message, warningType=editor.WarningStyle
1410 1394 )
1395
1411 editor.updateVerticalScrollBar() 1396 editor.updateVerticalScrollBar()
1412 1397
1413 @pyqtSlot() 1398 @pyqtSlot()
1414 def on_resultList_itemSelectionChanged(self): 1399 def on_resultList_itemSelectionChanged(self):
1415 """ 1400 """
1416 Private slot to change the dialog state depending on the selection. 1401 Private slot to change the dialog state depending on the selection.
1417 """ 1402 """
1418 self.fixButton.setEnabled(len(self.__getSelectedFixableItems()) > 0) 1403 self.fixButton.setEnabled(len(self.__getSelectedFixableItems()) > 0)
1419 1404
1420 @pyqtSlot() 1405 @pyqtSlot()
1421 def on_showButton_clicked(self): 1406 def on_showButton_clicked(self):
1422 """ 1407 """
1423 Private slot to handle the "Show" button press. 1408 Private slot to handle the "Show" button press.
1424 """ 1409 """
1425 vm = ericApp().getObject("ViewManager") 1410 vm = ericApp().getObject("ViewManager")
1426 1411
1427 selectedIndexes = [] 1412 selectedIndexes = []
1428 for index in range(self.resultList.topLevelItemCount()): 1413 for index in range(self.resultList.topLevelItemCount()):
1429 if self.resultList.topLevelItem(index).isSelected(): 1414 if self.resultList.topLevelItem(index).isSelected():
1430 selectedIndexes.append(index) 1415 selectedIndexes.append(index)
1431 if len(selectedIndexes) == 0: 1416 if len(selectedIndexes) == 0:
1439 for cindex in range(itm.childCount()): 1424 for cindex in range(itm.childCount()):
1440 citm = itm.child(cindex) 1425 citm = itm.child(cindex)
1441 lineno = citm.data(0, self.lineRole) 1426 lineno = citm.data(0, self.lineRole)
1442 message = citm.data(0, self.messageRole) 1427 message = citm.data(0, self.messageRole)
1443 editor.toggleWarning( 1428 editor.toggleWarning(
1444 lineno, 0, True, message, warningType=editor.WarningStyle) 1429 lineno, 0, True, message, warningType=editor.WarningStyle
1445 1430 )
1431
1446 # go through the list again to clear warning markers for files, 1432 # go through the list again to clear warning markers for files,
1447 # that are ok 1433 # that are ok
1448 openFiles = vm.getOpenFilenames() 1434 openFiles = vm.getOpenFilenames()
1449 errorFiles = [] 1435 errorFiles = []
1450 for index in range(self.resultList.topLevelItemCount()): 1436 for index in range(self.resultList.topLevelItemCount()):
1451 itm = self.resultList.topLevelItem(index) 1437 itm = self.resultList.topLevelItem(index)
1452 errorFiles.append( 1438 errorFiles.append(os.path.abspath(itm.data(0, self.filenameRole)))
1453 os.path.abspath(itm.data(0, self.filenameRole)))
1454 for file in openFiles: 1439 for file in openFiles:
1455 if file not in errorFiles: 1440 if file not in errorFiles:
1456 editor = vm.getOpenEditor(file) 1441 editor = vm.getOpenEditor(file)
1457 editor.clearStyleWarnings() 1442 editor.clearStyleWarnings()
1458 1443
1459 editor = vm.activeWindow() 1444 editor = vm.activeWindow()
1460 editor.updateVerticalScrollBar() 1445 editor.updateVerticalScrollBar()
1461 1446
1462 @pyqtSlot() 1447 @pyqtSlot()
1463 def on_statisticsButton_clicked(self): 1448 def on_statisticsButton_clicked(self):
1464 """ 1449 """
1465 Private slot to show the statistics dialog. 1450 Private slot to show the statistics dialog.
1466 """ 1451 """
1467 from .CodeStyleStatisticsDialog import CodeStyleStatisticsDialog 1452 from .CodeStyleStatisticsDialog import CodeStyleStatisticsDialog
1453
1468 dlg = CodeStyleStatisticsDialog(self.__statistics, self) 1454 dlg = CodeStyleStatisticsDialog(self.__statistics, self)
1469 dlg.exec() 1455 dlg.exec()
1470 1456
1471 @pyqtSlot() 1457 @pyqtSlot()
1472 def on_loadDefaultButton_clicked(self): 1458 def on_loadDefaultButton_clicked(self):
1473 """ 1459 """
1474 Private slot to load the default configuration values. 1460 Private slot to load the default configuration values.
1475 """ 1461 """
1476 self.__initCategoriesList(Preferences.getSettings().value( 1462 self.__initCategoriesList(
1477 "PEP8/EnabledCheckerCategories", 1463 Preferences.getSettings().value(
1478 ",".join(CodeStyleCheckerDialog.checkCategories.keys()))) 1464 "PEP8/EnabledCheckerCategories",
1479 self.excludeFilesEdit.setText(Preferences.getSettings().value( 1465 ",".join(CodeStyleCheckerDialog.checkCategories.keys()),
1480 "PEP8/ExcludeFilePatterns", "")) 1466 )
1481 self.excludeMessagesEdit.setText(Preferences.getSettings().value( 1467 )
1482 "PEP8/ExcludeMessages", pycodestyle.DEFAULT_IGNORE)) 1468 self.excludeFilesEdit.setText(
1483 self.includeMessagesEdit.setText(Preferences.getSettings().value( 1469 Preferences.getSettings().value("PEP8/ExcludeFilePatterns", "")
1484 "PEP8/IncludeMessages", "")) 1470 )
1485 self.repeatCheckBox.setChecked(Preferences.toBool( 1471 self.excludeMessagesEdit.setText(
1486 Preferences.getSettings().value("PEP8/RepeatMessages", False))) 1472 Preferences.getSettings().value(
1487 self.fixIssuesEdit.setText(Preferences.getSettings().value( 1473 "PEP8/ExcludeMessages", pycodestyle.DEFAULT_IGNORE
1488 "PEP8/FixCodes", "")) 1474 )
1489 self.noFixIssuesEdit.setText(Preferences.getSettings().value( 1475 )
1490 "PEP8/NoFixCodes", "E501")) 1476 self.includeMessagesEdit.setText(
1491 self.fixIssuesCheckBox.setChecked(Preferences.toBool( 1477 Preferences.getSettings().value("PEP8/IncludeMessages", "")
1492 Preferences.getSettings().value("PEP8/FixIssues", False))) 1478 )
1493 self.ignoredCheckBox.setChecked(Preferences.toBool( 1479 self.repeatCheckBox.setChecked(
1494 Preferences.getSettings().value("PEP8/ShowIgnored", False))) 1480 Preferences.toBool(
1495 self.lineLengthSpinBox.setValue(int( 1481 Preferences.getSettings().value("PEP8/RepeatMessages", False)
1496 Preferences.getSettings().value("PEP8/MaxLineLength", 88))) 1482 )
1497 self.docLineLengthSpinBox.setValue(int( 1483 )
1498 Preferences.getSettings().value("PEP8/MaxDocLineLength", 88))) 1484 self.fixIssuesEdit.setText(Preferences.getSettings().value("PEP8/FixCodes", ""))
1485 self.noFixIssuesEdit.setText(
1486 Preferences.getSettings().value("PEP8/NoFixCodes", "E501")
1487 )
1488 self.fixIssuesCheckBox.setChecked(
1489 Preferences.toBool(Preferences.getSettings().value("PEP8/FixIssues", False))
1490 )
1491 self.ignoredCheckBox.setChecked(
1492 Preferences.toBool(
1493 Preferences.getSettings().value("PEP8/ShowIgnored", False)
1494 )
1495 )
1496 self.lineLengthSpinBox.setValue(
1497 int(Preferences.getSettings().value("PEP8/MaxLineLength", 88))
1498 )
1499 self.docLineLengthSpinBox.setValue(
1500 int(Preferences.getSettings().value("PEP8/MaxDocLineLength", 88))
1501 )
1499 self.blankBeforeTopLevelSpinBox.setValue( 1502 self.blankBeforeTopLevelSpinBox.setValue(
1500 int(Preferences.getSettings().value( 1503 int(Preferences.getSettings().value("PEP8/BlankLinesBeforeTopLevel", 2))
1501 "PEP8/BlankLinesBeforeTopLevel", 2))) 1504 )
1502 self.blankBeforeMethodSpinBox.setValue( 1505 self.blankBeforeMethodSpinBox.setValue(
1503 int(Preferences.getSettings().value( 1506 int(Preferences.getSettings().value("PEP8/BlankLinesBeforeMethod", 1))
1504 "PEP8/BlankLinesBeforeMethod", 1))) 1507 )
1505 self.hangClosingCheckBox.setChecked(Preferences.toBool( 1508 self.hangClosingCheckBox.setChecked(
1506 Preferences.getSettings().value("PEP8/HangClosing", False))) 1509 Preferences.toBool(
1507 self.docTypeComboBox.setCurrentIndex(self.docTypeComboBox.findData( 1510 Preferences.getSettings().value("PEP8/HangClosing", False)
1508 Preferences.getSettings().value("PEP8/DocstringType", "pep257"))) 1511 )
1509 self.complexitySpinBox.setValue(int(Preferences.getSettings().value( 1512 )
1510 "PEP8/MaxCodeComplexity", 10))) 1513 self.docTypeComboBox.setCurrentIndex(
1514 self.docTypeComboBox.findData(
1515 Preferences.getSettings().value("PEP8/DocstringType", "pep257")
1516 )
1517 )
1518 self.complexitySpinBox.setValue(
1519 int(Preferences.getSettings().value("PEP8/MaxCodeComplexity", 10))
1520 )
1511 self.lineComplexitySpinBox.setValue( 1521 self.lineComplexitySpinBox.setValue(
1512 int(Preferences.getSettings().value( 1522 int(Preferences.getSettings().value("PEP8/LineComplexity", 15))
1513 "PEP8/LineComplexity", 15))) 1523 )
1514 self.lineComplexityScoreSpinBox.setValue( 1524 self.lineComplexityScoreSpinBox.setValue(
1515 int(Preferences.getSettings().value( 1525 int(Preferences.getSettings().value("PEP8/LineComplexityScore", 10))
1516 "PEP8/LineComplexityScore", 10))) 1526 )
1517 self.encodingsEdit.setText(Preferences.getSettings().value( 1527 self.encodingsEdit.setText(
1518 "PEP8/ValidEncodings",
1519 MiscellaneousCheckerDefaultArgs["CodingChecker"]
1520 ))
1521 self.copyrightFileSizeSpinBox.setValue(int(
1522 Preferences.getSettings().value( 1528 Preferences.getSettings().value(
1523 "PEP8/CopyrightMinFileSize", 1529 "PEP8/ValidEncodings", MiscellaneousCheckerDefaultArgs["CodingChecker"]
1524 MiscellaneousCheckerDefaultArgs[ 1530 )
1525 "CopyrightChecker"]["MinFilesize"] 1531 )
1526 ) 1532 self.copyrightFileSizeSpinBox.setValue(
1527 )) 1533 int(
1534 Preferences.getSettings().value(
1535 "PEP8/CopyrightMinFileSize",
1536 MiscellaneousCheckerDefaultArgs["CopyrightChecker"]["MinFilesize"],
1537 )
1538 )
1539 )
1528 self.copyrightAuthorEdit.setText( 1540 self.copyrightAuthorEdit.setText(
1529 Preferences.getSettings().value( 1541 Preferences.getSettings().value(
1530 "PEP8/CopyrightAuthor", 1542 "PEP8/CopyrightAuthor",
1531 MiscellaneousCheckerDefaultArgs["CopyrightChecker"]["Author"] 1543 MiscellaneousCheckerDefaultArgs["CopyrightChecker"]["Author"],
1532 ) 1544 )
1533 ) 1545 )
1534 self.__initFuturesList( 1546 self.__initFuturesList(
1535 Preferences.getSettings().value("PEP8/FutureChecker", "")) 1547 Preferences.getSettings().value("PEP8/FutureChecker", "")
1536 self.__initBuiltinsIgnoreList(Preferences.toDict( 1548 )
1537 Preferences.getSettings().value( 1549 self.__initBuiltinsIgnoreList(
1538 "PEP8/BuiltinsChecker", 1550 Preferences.toDict(
1539 MiscellaneousCheckerDefaultArgs["BuiltinsChecker"] 1551 Preferences.getSettings().value(
1540 )) 1552 "PEP8/BuiltinsChecker",
1541 ) 1553 MiscellaneousCheckerDefaultArgs["BuiltinsChecker"],
1542 self.aggressiveCheckBox.setChecked(Preferences.toBool( 1554 )
1543 Preferences.getSettings().value( 1555 )
1544 "PEP8/AggressiveSearch", 1556 )
1545 MiscellaneousCheckerDefaultArgs[ 1557 self.aggressiveCheckBox.setChecked(
1546 "CommentedCodeChecker"]["Aggressive"] 1558 Preferences.toBool(
1547 ))) 1559 Preferences.getSettings().value(
1548 self.__initCommentedCodeCheckerWhiteList(Preferences.toList( 1560 "PEP8/AggressiveSearch",
1549 Preferences.getSettings().value( 1561 MiscellaneousCheckerDefaultArgs["CommentedCodeChecker"][
1550 "PEP8/CommentedCodeWhitelist", 1562 "Aggressive"
1551 MiscellaneousCheckerDefaultArgs[ 1563 ],
1552 "CommentedCodeChecker"]["WhiteList"] 1564 )
1553 ) 1565 )
1554 )) 1566 )
1555 1567 self.__initCommentedCodeCheckerWhiteList(
1568 Preferences.toList(
1569 Preferences.getSettings().value(
1570 "PEP8/CommentedCodeWhitelist",
1571 MiscellaneousCheckerDefaultArgs["CommentedCodeChecker"][
1572 "WhiteList"
1573 ],
1574 )
1575 )
1576 )
1577
1556 # Type Annotations Checker 1578 # Type Annotations Checker
1557 self.minAnnotationsCoverageSpinBox.setValue(int( 1579 self.minAnnotationsCoverageSpinBox.setValue(
1558 Preferences.getSettings().value( 1580 int(
1559 "PEP8/MinimumAnnotationsCoverage", 1581 Preferences.getSettings().value(
1560 AnnotationsCheckerDefaultArgs["MinimumCoverage"]))) 1582 "PEP8/MinimumAnnotationsCoverage",
1561 self.maxAnnotationsComplexitySpinBox.setValue(int( 1583 AnnotationsCheckerDefaultArgs["MinimumCoverage"],
1562 Preferences.getSettings().value( 1584 )
1563 "PEP8/MaximumAnnotationComplexity", 1585 )
1564 AnnotationsCheckerDefaultArgs["MaximumComplexity"]))) 1586 )
1565 self.maxAnnotationsLengthSpinBox.setValue(int( 1587 self.maxAnnotationsComplexitySpinBox.setValue(
1566 Preferences.getSettings().value( 1588 int(
1567 "PEP8/MaximumAnnotationLength", 1589 Preferences.getSettings().value(
1568 AnnotationsCheckerDefaultArgs["MaximumLength"]))) 1590 "PEP8/MaximumAnnotationComplexity",
1569 self.suppressNoneReturningCheckBox.setChecked(Preferences.toBool( 1591 AnnotationsCheckerDefaultArgs["MaximumComplexity"],
1570 Preferences.getSettings().value( 1592 )
1571 "PEP8/SuppressNoneReturning", 1593 )
1572 AnnotationsCheckerDefaultArgs["SuppressNoneReturning"]))) 1594 )
1573 self.suppressDummyArgsCheckBox.setChecked(Preferences.toBool( 1595 self.maxAnnotationsLengthSpinBox.setValue(
1574 Preferences.getSettings().value( 1596 int(
1575 "PEP8/SuppressDummyArgs", 1597 Preferences.getSettings().value(
1576 AnnotationsCheckerDefaultArgs["SuppressDummyArgs"]))) 1598 "PEP8/MaximumAnnotationLength",
1577 self.allowUntypedDefsCheckBox.setChecked(Preferences.toBool( 1599 AnnotationsCheckerDefaultArgs["MaximumLength"],
1578 Preferences.getSettings().value( 1600 )
1579 "PEP8/AllowUntypedDefs", 1601 )
1580 AnnotationsCheckerDefaultArgs["AllowUntypedDefs"]))) 1602 )
1581 self.allowUntypedNestedCheckBox.setChecked(Preferences.toBool( 1603 self.suppressNoneReturningCheckBox.setChecked(
1582 Preferences.getSettings().value( 1604 Preferences.toBool(
1583 "PEP8/AllowUntypedNested", 1605 Preferences.getSettings().value(
1584 AnnotationsCheckerDefaultArgs["AllowUntypedNested"]))) 1606 "PEP8/SuppressNoneReturning",
1585 self.mypyInitReturnCheckBox.setChecked(Preferences.toBool( 1607 AnnotationsCheckerDefaultArgs["SuppressNoneReturning"],
1586 Preferences.getSettings().value( 1608 )
1587 "PEP8/MypyInitReturn", 1609 )
1588 AnnotationsCheckerDefaultArgs["MypyInitReturn"]))) 1610 )
1589 self.dispatchDecoratorEdit.setText(", ".join(Preferences.toList( 1611 self.suppressDummyArgsCheckBox.setChecked(
1590 Preferences.getSettings().value( 1612 Preferences.toBool(
1591 "PEP8/DispatchDecorators", 1613 Preferences.getSettings().value(
1592 AnnotationsCheckerDefaultArgs["DispatchDecorators"])))) 1614 "PEP8/SuppressDummyArgs",
1593 self.overloadDecoratorEdit.setText(", ".join(Preferences.toList( 1615 AnnotationsCheckerDefaultArgs["SuppressDummyArgs"],
1594 Preferences.getSettings().value( 1616 )
1595 "PEP8/OverloadDecorators", 1617 )
1596 AnnotationsCheckerDefaultArgs["OverloadDecorators"])))) 1618 )
1597 1619 self.allowUntypedDefsCheckBox.setChecked(
1620 Preferences.toBool(
1621 Preferences.getSettings().value(
1622 "PEP8/AllowUntypedDefs",
1623 AnnotationsCheckerDefaultArgs["AllowUntypedDefs"],
1624 )
1625 )
1626 )
1627 self.allowUntypedNestedCheckBox.setChecked(
1628 Preferences.toBool(
1629 Preferences.getSettings().value(
1630 "PEP8/AllowUntypedNested",
1631 AnnotationsCheckerDefaultArgs["AllowUntypedNested"],
1632 )
1633 )
1634 )
1635 self.mypyInitReturnCheckBox.setChecked(
1636 Preferences.toBool(
1637 Preferences.getSettings().value(
1638 "PEP8/MypyInitReturn",
1639 AnnotationsCheckerDefaultArgs["MypyInitReturn"],
1640 )
1641 )
1642 )
1643 self.dispatchDecoratorEdit.setText(
1644 ", ".join(
1645 Preferences.toList(
1646 Preferences.getSettings().value(
1647 "PEP8/DispatchDecorators",
1648 AnnotationsCheckerDefaultArgs["DispatchDecorators"],
1649 )
1650 )
1651 )
1652 )
1653 self.overloadDecoratorEdit.setText(
1654 ", ".join(
1655 Preferences.toList(
1656 Preferences.getSettings().value(
1657 "PEP8/OverloadDecorators",
1658 AnnotationsCheckerDefaultArgs["OverloadDecorators"],
1659 )
1660 )
1661 )
1662 )
1663
1598 # Security Checker 1664 # Security Checker
1599 from .Security.SecurityDefaults import SecurityDefaults 1665 from .Security.SecurityDefaults import SecurityDefaults
1600 self.tmpDirectoriesEdit.setPlainText("\n".join( 1666
1601 Preferences.toList(Preferences.getSettings().value( 1667 self.tmpDirectoriesEdit.setPlainText(
1602 "PEP8/HardcodedTmpDirectories", 1668 "\n".join(
1603 SecurityDefaults["hardcoded_tmp_directories"])))) 1669 Preferences.toList(
1604 self.hashesEdit.setText(", ".join( 1670 Preferences.getSettings().value(
1605 Preferences.toList(Preferences.getSettings().value( 1671 "PEP8/HardcodedTmpDirectories",
1606 "PEP8/InsecureHashes", 1672 SecurityDefaults["hardcoded_tmp_directories"],
1607 SecurityDefaults["insecure_hashes"])))), 1673 )
1608 self.insecureSslProtocolsEdit.setPlainText("\n".join( 1674 )
1609 Preferences.toList(Preferences.getSettings().value( 1675 )
1610 "PEP8/InsecureSslProtocolVersions", 1676 )
1611 SecurityDefaults["insecure_ssl_protocol_versions"])))), 1677 self.hashesEdit.setText(
1678 ", ".join(
1679 Preferences.toList(
1680 Preferences.getSettings().value(
1681 "PEP8/InsecureHashes", SecurityDefaults["insecure_hashes"]
1682 )
1683 )
1684 )
1685 ),
1686 self.insecureSslProtocolsEdit.setPlainText(
1687 "\n".join(
1688 Preferences.toList(
1689 Preferences.getSettings().value(
1690 "PEP8/InsecureSslProtocolVersions",
1691 SecurityDefaults["insecure_ssl_protocol_versions"],
1692 )
1693 )
1694 )
1695 ),
1612 self.dsaHighRiskCombo.setCurrentText( 1696 self.dsaHighRiskCombo.setCurrentText(
1613 Preferences.getSettings().value( 1697 Preferences.getSettings().value(
1614 "PEP8/WeakKeySizeDsaHigh", 1698 "PEP8/WeakKeySizeDsaHigh",
1615 str(SecurityDefaults["weak_key_size_dsa_high"]))) 1699 str(SecurityDefaults["weak_key_size_dsa_high"]),
1700 )
1701 )
1616 self.dsaMediumRiskCombo.setCurrentText( 1702 self.dsaMediumRiskCombo.setCurrentText(
1617 Preferences.getSettings().value( 1703 Preferences.getSettings().value(
1618 "PEP8/WeakKeySizeDsaMedium", 1704 "PEP8/WeakKeySizeDsaMedium",
1619 str(SecurityDefaults["weak_key_size_dsa_medium"]))), 1705 str(SecurityDefaults["weak_key_size_dsa_medium"]),
1706 )
1707 ),
1620 self.rsaHighRiskCombo.setCurrentText( 1708 self.rsaHighRiskCombo.setCurrentText(
1621 Preferences.getSettings().value( 1709 Preferences.getSettings().value(
1622 "PEP8/WeakKeySizeRsaHigh", 1710 "PEP8/WeakKeySizeRsaHigh",
1623 str(SecurityDefaults["weak_key_size_rsa_high"]))), 1711 str(SecurityDefaults["weak_key_size_rsa_high"]),
1712 )
1713 ),
1624 self.rsaMediumRiskCombo.setCurrentText( 1714 self.rsaMediumRiskCombo.setCurrentText(
1625 Preferences.getSettings().value( 1715 Preferences.getSettings().value(
1626 "PEP8/WeakKeySizeRsaMedium", 1716 "PEP8/WeakKeySizeRsaMedium",
1627 str(SecurityDefaults["weak_key_size_rsa_medium"]))), 1717 str(SecurityDefaults["weak_key_size_rsa_medium"]),
1718 )
1719 ),
1628 self.ecHighRiskCombo.setCurrentText( 1720 self.ecHighRiskCombo.setCurrentText(
1629 Preferences.getSettings().value( 1721 Preferences.getSettings().value(
1630 "PEP8/WeakKeySizeEcHigh", 1722 "PEP8/WeakKeySizeEcHigh", str(SecurityDefaults["weak_key_size_ec_high"])
1631 str(SecurityDefaults["weak_key_size_ec_high"]))), 1723 )
1724 ),
1632 self.ecMediumRiskCombo.setCurrentText( 1725 self.ecMediumRiskCombo.setCurrentText(
1633 Preferences.getSettings().value( 1726 Preferences.getSettings().value(
1634 "PEP8/WeakKeySizeEcMedium", 1727 "PEP8/WeakKeySizeEcMedium",
1635 str(SecurityDefaults["weak_key_size_ec_medium"]))), 1728 str(SecurityDefaults["weak_key_size_ec_medium"]),
1636 self.typedExceptionsCheckBox.setChecked(Preferences.toBool( 1729 )
1637 Preferences.getSettings().value( 1730 ),
1638 "PEP8/CheckTypedException", 1731 self.typedExceptionsCheckBox.setChecked(
1639 SecurityDefaults["check_typed_exception"]))), 1732 Preferences.toBool(
1640 1733 Preferences.getSettings().value(
1734 "PEP8/CheckTypedException",
1735 SecurityDefaults["check_typed_exception"],
1736 )
1737 )
1738 ),
1739
1641 # Imports Checker 1740 # Imports Checker
1642 self.appPackagesEdit.setPlainText(" ".join( 1741 self.appPackagesEdit.setPlainText(
1643 sorted(Preferences.toList(Preferences.getSettings().value( 1742 " ".join(
1644 "PEP8/ApplicationPackageNames", []))))) 1743 sorted(
1645 self.bannedModulesEdit.setPlainText(" ".join( 1744 Preferences.toList(
1646 sorted(Preferences.toList(Preferences.getSettings().value( 1745 Preferences.getSettings().value(
1647 "PEP8/BannedModules", []))))) 1746 "PEP8/ApplicationPackageNames", []
1747 )
1748 )
1749 )
1750 )
1751 )
1752 self.bannedModulesEdit.setPlainText(
1753 " ".join(
1754 sorted(
1755 Preferences.toList(
1756 Preferences.getSettings().value("PEP8/BannedModules", [])
1757 )
1758 )
1759 )
1760 )
1648 self.__setBanRelativeImports( 1761 self.__setBanRelativeImports(
1649 Preferences.getSettings().value( 1762 Preferences.getSettings().value("PEP8/BanRelativeImports", "")
1650 "PEP8/BanRelativeImports", "")) 1763 )
1651 1764
1652 self.__cleanupData() 1765 self.__cleanupData()
1653 1766
1654 @pyqtSlot() 1767 @pyqtSlot()
1655 def on_storeDefaultButton_clicked(self): 1768 def on_storeDefaultButton_clicked(self):
1656 """ 1769 """
1657 Private slot to store the current configuration values as 1770 Private slot to store the current configuration values as
1658 default values. 1771 default values.
1659 """ 1772 """
1660 Preferences.getSettings().setValue( 1773 Preferences.getSettings().setValue(
1661 "PEP8/EnabledCheckerCategories", self.__getCategories(True)) 1774 "PEP8/EnabledCheckerCategories", self.__getCategories(True)
1662 Preferences.getSettings().setValue( 1775 )
1663 "PEP8/ExcludeFilePatterns", self.excludeFilesEdit.text()) 1776 Preferences.getSettings().setValue(
1664 Preferences.getSettings().setValue( 1777 "PEP8/ExcludeFilePatterns", self.excludeFilesEdit.text()
1665 "PEP8/ExcludeMessages", self.excludeMessagesEdit.text()) 1778 )
1666 Preferences.getSettings().setValue( 1779 Preferences.getSettings().setValue(
1667 "PEP8/IncludeMessages", self.includeMessagesEdit.text()) 1780 "PEP8/ExcludeMessages", self.excludeMessagesEdit.text()
1668 Preferences.getSettings().setValue( 1781 )
1669 "PEP8/RepeatMessages", self.repeatCheckBox.isChecked()) 1782 Preferences.getSettings().setValue(
1670 Preferences.getSettings().setValue( 1783 "PEP8/IncludeMessages", self.includeMessagesEdit.text()
1671 "PEP8/FixCodes", self.fixIssuesEdit.text()) 1784 )
1672 Preferences.getSettings().setValue( 1785 Preferences.getSettings().setValue(
1673 "PEP8/NoFixCodes", self.noFixIssuesEdit.text()) 1786 "PEP8/RepeatMessages", self.repeatCheckBox.isChecked()
1674 Preferences.getSettings().setValue( 1787 )
1675 "PEP8/FixIssues", self.fixIssuesCheckBox.isChecked()) 1788 Preferences.getSettings().setValue("PEP8/FixCodes", self.fixIssuesEdit.text())
1676 Preferences.getSettings().setValue( 1789 Preferences.getSettings().setValue(
1677 "PEP8/ShowIgnored", self.ignoredCheckBox.isChecked()) 1790 "PEP8/NoFixCodes", self.noFixIssuesEdit.text()
1678 Preferences.getSettings().setValue( 1791 )
1679 "PEP8/MaxLineLength", self.lineLengthSpinBox.value()) 1792 Preferences.getSettings().setValue(
1680 Preferences.getSettings().setValue( 1793 "PEP8/FixIssues", self.fixIssuesCheckBox.isChecked()
1681 "PEP8/MaxDocLineLength", self.docLineLengthSpinBox.value()) 1794 )
1682 Preferences.getSettings().setValue( 1795 Preferences.getSettings().setValue(
1683 "PEP8/BlankLinesBeforeTopLevel", 1796 "PEP8/ShowIgnored", self.ignoredCheckBox.isChecked()
1684 self.blankBeforeTopLevelSpinBox.value()) 1797 )
1685 Preferences.getSettings().setValue( 1798 Preferences.getSettings().setValue(
1686 "PEP8/BlankLinesBeforeMethod", 1799 "PEP8/MaxLineLength", self.lineLengthSpinBox.value()
1687 self.blankBeforeMethodSpinBox.value()) 1800 )
1688 Preferences.getSettings().setValue( 1801 Preferences.getSettings().setValue(
1689 "PEP8/HangClosing", self.hangClosingCheckBox.isChecked()) 1802 "PEP8/MaxDocLineLength", self.docLineLengthSpinBox.value()
1690 Preferences.getSettings().setValue( 1803 )
1691 "PEP8/DocstringType", self.docTypeComboBox.itemData( 1804 Preferences.getSettings().setValue(
1692 self.docTypeComboBox.currentIndex())) 1805 "PEP8/BlankLinesBeforeTopLevel", self.blankBeforeTopLevelSpinBox.value()
1693 Preferences.getSettings().setValue( 1806 )
1694 "PEP8/MaxCodeComplexity", self.complexitySpinBox.value()) 1807 Preferences.getSettings().setValue(
1695 Preferences.getSettings().setValue( 1808 "PEP8/BlankLinesBeforeMethod", self.blankBeforeMethodSpinBox.value()
1696 "PEP8/LineComplexity", self.lineComplexitySpinBox.value()) 1809 )
1697 Preferences.getSettings().setValue( 1810 Preferences.getSettings().setValue(
1698 "PEP8/LineComplexityScore", 1811 "PEP8/HangClosing", self.hangClosingCheckBox.isChecked()
1699 self.lineComplexityScoreSpinBox.value()) 1812 )
1700 Preferences.getSettings().setValue( 1813 Preferences.getSettings().setValue(
1701 "PEP8/ValidEncodings", self.encodingsEdit.text()) 1814 "PEP8/DocstringType",
1702 Preferences.getSettings().setValue( 1815 self.docTypeComboBox.itemData(self.docTypeComboBox.currentIndex()),
1703 "PEP8/CopyrightMinFileSize", self.copyrightFileSizeSpinBox.value()) 1816 )
1704 Preferences.getSettings().setValue( 1817 Preferences.getSettings().setValue(
1705 "PEP8/CopyrightAuthor", self.copyrightAuthorEdit.text()) 1818 "PEP8/MaxCodeComplexity", self.complexitySpinBox.value()
1706 Preferences.getSettings().setValue( 1819 )
1707 "PEP8/FutureChecker", self.__getSelectedFutureImports()) 1820 Preferences.getSettings().setValue(
1708 Preferences.getSettings().setValue( 1821 "PEP8/LineComplexity", self.lineComplexitySpinBox.value()
1709 "PEP8/BuiltinsChecker", self.__getBuiltinsIgnoreList()) 1822 )
1710 Preferences.getSettings().setValue( 1823 Preferences.getSettings().setValue(
1711 "PEP8/AggressiveSearch", self.aggressiveCheckBox.isChecked()) 1824 "PEP8/LineComplexityScore", self.lineComplexityScoreSpinBox.value()
1712 Preferences.getSettings().setValue( 1825 )
1713 "PEP8/CommentedCodeWhitelist", 1826 Preferences.getSettings().setValue(
1714 self.__getCommentedCodeCheckerWhiteList()) 1827 "PEP8/ValidEncodings", self.encodingsEdit.text()
1715 1828 )
1829 Preferences.getSettings().setValue(
1830 "PEP8/CopyrightMinFileSize", self.copyrightFileSizeSpinBox.value()
1831 )
1832 Preferences.getSettings().setValue(
1833 "PEP8/CopyrightAuthor", self.copyrightAuthorEdit.text()
1834 )
1835 Preferences.getSettings().setValue(
1836 "PEP8/FutureChecker", self.__getSelectedFutureImports()
1837 )
1838 Preferences.getSettings().setValue(
1839 "PEP8/BuiltinsChecker", self.__getBuiltinsIgnoreList()
1840 )
1841 Preferences.getSettings().setValue(
1842 "PEP8/AggressiveSearch", self.aggressiveCheckBox.isChecked()
1843 )
1844 Preferences.getSettings().setValue(
1845 "PEP8/CommentedCodeWhitelist", self.__getCommentedCodeCheckerWhiteList()
1846 )
1847
1716 # Type Annotations Checker 1848 # Type Annotations Checker
1717 Preferences.getSettings().setValue( 1849 Preferences.getSettings().setValue(
1718 "PEP8/MinimumAnnotationsCoverage", 1850 "PEP8/MinimumAnnotationsCoverage",
1719 self.minAnnotationsCoverageSpinBox.value()) 1851 self.minAnnotationsCoverageSpinBox.value(),
1852 )
1720 Preferences.getSettings().setValue( 1853 Preferences.getSettings().setValue(
1721 "PEP8/MaximumAnnotationComplexity", 1854 "PEP8/MaximumAnnotationComplexity",
1722 self.maxAnnotationsComplexitySpinBox.value()) 1855 self.maxAnnotationsComplexitySpinBox.value(),
1723 Preferences.getSettings().setValue( 1856 )
1724 "PEP8/MaximumAnnotationLength", 1857 Preferences.getSettings().setValue(
1725 self.maxAnnotationsLengthSpinBox.value()) 1858 "PEP8/MaximumAnnotationLength", self.maxAnnotationsLengthSpinBox.value()
1726 Preferences.getSettings().setValue( 1859 )
1727 "PEP8/SuppressNoneReturning", 1860 Preferences.getSettings().setValue(
1728 self.suppressNoneReturningCheckBox.isChecked()) 1861 "PEP8/SuppressNoneReturning", self.suppressNoneReturningCheckBox.isChecked()
1729 Preferences.getSettings().setValue( 1862 )
1730 "PEP8/SuppressDummyArgs", 1863 Preferences.getSettings().setValue(
1731 self.suppressDummyArgsCheckBox.isChecked()) 1864 "PEP8/SuppressDummyArgs", self.suppressDummyArgsCheckBox.isChecked()
1732 Preferences.getSettings().setValue( 1865 )
1733 "PEP8/AllowUntypedDefs", 1866 Preferences.getSettings().setValue(
1734 self.allowUntypedDefsCheckBox.isChecked()) 1867 "PEP8/AllowUntypedDefs", self.allowUntypedDefsCheckBox.isChecked()
1735 Preferences.getSettings().setValue( 1868 )
1736 "PEP8/AllowUntypedNested", 1869 Preferences.getSettings().setValue(
1737 self.allowUntypedNestedCheckBox.isChecked()) 1870 "PEP8/AllowUntypedNested", self.allowUntypedNestedCheckBox.isChecked()
1738 Preferences.getSettings().setValue( 1871 )
1739 "PEP8/MypyInitReturn", 1872 Preferences.getSettings().setValue(
1740 self.mypyInitReturnCheckBox.isChecked()) 1873 "PEP8/MypyInitReturn", self.mypyInitReturnCheckBox.isChecked()
1874 )
1741 Preferences.getSettings().setValue( 1875 Preferences.getSettings().setValue(
1742 "PEP8/DispatchDecorators", 1876 "PEP8/DispatchDecorators",
1743 [d.strip() 1877 [d.strip() for d in self.dispatchDecoratorEdit.text().split(",")],
1744 for d in self.dispatchDecoratorEdit.text().split(",")]) 1878 )
1745 Preferences.getSettings().setValue( 1879 Preferences.getSettings().setValue(
1746 "PEP8/OverloadDecorators", 1880 "PEP8/OverloadDecorators",
1747 [d.strip() 1881 [d.strip() for d in self.overloadDecoratorEdit.text().split(",")],
1748 for d in self.overloadDecoratorEdit.text().split(",")]) 1882 )
1749 1883
1750 # Security Checker 1884 # Security Checker
1751 Preferences.getSettings().setValue( 1885 Preferences.getSettings().setValue(
1752 "PEP8/HardcodedTmpDirectories", 1886 "PEP8/HardcodedTmpDirectories",
1753 [t.strip() 1887 [t.strip() for t in self.tmpDirectoriesEdit.toPlainText().splitlines()],
1754 for t in self.tmpDirectoriesEdit.toPlainText().splitlines() 1888 ),
1755 ]),
1756 Preferences.getSettings().setValue( 1889 Preferences.getSettings().setValue(
1757 "PEP8/InsecureHashes", 1890 "PEP8/InsecureHashes",
1758 [h.strip() 1891 [h.strip() for h in self.hashesEdit.text().split(",")],
1759 for h in self.hashesEdit.text().split(",") 1892 ),
1760 ]),
1761 Preferences.getSettings().setValue( 1893 Preferences.getSettings().setValue(
1762 "PEP8/InsecureSslProtocolVersions", 1894 "PEP8/InsecureSslProtocolVersions",
1763 [p.strip() 1895 [
1764 for p in self.insecureSslProtocolsEdit.toPlainText().splitlines() 1896 p.strip()
1765 ]), 1897 for p in self.insecureSslProtocolsEdit.toPlainText().splitlines()
1766 Preferences.getSettings().setValue( 1898 ],
1767 "PEP8/WeakKeySizeDsaHigh", 1899 ),
1768 self.dsaHighRiskCombo.currentText()), 1900 Preferences.getSettings().setValue(
1769 Preferences.getSettings().setValue( 1901 "PEP8/WeakKeySizeDsaHigh", self.dsaHighRiskCombo.currentText()
1770 "PEP8/WeakKeySizeDsaMedium", 1902 ),
1771 self.dsaMediumRiskCombo.currentText()), 1903 Preferences.getSettings().setValue(
1772 Preferences.getSettings().setValue( 1904 "PEP8/WeakKeySizeDsaMedium", self.dsaMediumRiskCombo.currentText()
1773 "PEP8/WeakKeySizeRsaHigh", 1905 ),
1774 self.rsaHighRiskCombo.currentText()), 1906 Preferences.getSettings().setValue(
1775 Preferences.getSettings().setValue( 1907 "PEP8/WeakKeySizeRsaHigh", self.rsaHighRiskCombo.currentText()
1776 "PEP8/WeakKeySizeRsaMedium", 1908 ),
1777 self.rsaMediumRiskCombo.currentText()), 1909 Preferences.getSettings().setValue(
1778 Preferences.getSettings().setValue( 1910 "PEP8/WeakKeySizeRsaMedium", self.rsaMediumRiskCombo.currentText()
1779 "PEP8/WeakKeySizeEcHigh", 1911 ),
1780 self.ecHighRiskCombo.currentText()), 1912 Preferences.getSettings().setValue(
1781 Preferences.getSettings().setValue( 1913 "PEP8/WeakKeySizeEcHigh", self.ecHighRiskCombo.currentText()
1782 "PEP8/WeakKeySizeEcMedium", 1914 ),
1783 self.ecMediumRiskCombo.currentText()), 1915 Preferences.getSettings().setValue(
1784 Preferences.getSettings().setValue( 1916 "PEP8/WeakKeySizeEcMedium", self.ecMediumRiskCombo.currentText()
1785 "PEP8/CheckTypedException", 1917 ),
1786 self.typedExceptionsCheckBox.isChecked()), 1918 Preferences.getSettings().setValue(
1787 1919 "PEP8/CheckTypedException", self.typedExceptionsCheckBox.isChecked()
1920 ),
1921
1788 # Imports Checker 1922 # Imports Checker
1789 Preferences.getSettings().setValue( 1923 Preferences.getSettings().setValue(
1790 "PEP8/ApplicationPackageNames", 1924 "PEP8/ApplicationPackageNames",
1791 sorted(self.appPackagesEdit.toPlainText().split())) 1925 sorted(self.appPackagesEdit.toPlainText().split()),
1792 Preferences.getSettings().setValue( 1926 )
1793 "PEP8/BannedModules", 1927 Preferences.getSettings().setValue(
1794 sorted(self.bannedModulesEdit.toPlainText().split())) 1928 "PEP8/BannedModules", sorted(self.bannedModulesEdit.toPlainText().split())
1795 Preferences.getSettings().setValue( 1929 )
1796 "PEP8/BanRelativeImports", 1930 Preferences.getSettings().setValue(
1797 self.__getBanRelativeImportsValue()) 1931 "PEP8/BanRelativeImports", self.__getBanRelativeImportsValue()
1798 1932 )
1933
1799 @pyqtSlot() 1934 @pyqtSlot()
1800 def on_resetDefaultButton_clicked(self): 1935 def on_resetDefaultButton_clicked(self):
1801 """ 1936 """
1802 Private slot to reset the configuration values to their default values. 1937 Private slot to reset the configuration values to their default values.
1803 """ 1938 """
1804 Preferences.getSettings().setValue( 1939 Preferences.getSettings().setValue(
1805 "PEP8/EnabledCheckerCategories", 1940 "PEP8/EnabledCheckerCategories",
1806 ",".join(CodeStyleCheckerDialog.checkCategories.keys())) 1941 ",".join(CodeStyleCheckerDialog.checkCategories.keys()),
1942 )
1807 Preferences.getSettings().setValue("PEP8/ExcludeFilePatterns", "") 1943 Preferences.getSettings().setValue("PEP8/ExcludeFilePatterns", "")
1808 Preferences.getSettings().setValue( 1944 Preferences.getSettings().setValue(
1809 "PEP8/ExcludeMessages", pycodestyle.DEFAULT_IGNORE) 1945 "PEP8/ExcludeMessages", pycodestyle.DEFAULT_IGNORE
1946 )
1810 Preferences.getSettings().setValue("PEP8/IncludeMessages", "") 1947 Preferences.getSettings().setValue("PEP8/IncludeMessages", "")
1811 Preferences.getSettings().setValue("PEP8/RepeatMessages", False) 1948 Preferences.getSettings().setValue("PEP8/RepeatMessages", False)
1812 Preferences.getSettings().setValue("PEP8/FixCodes", "") 1949 Preferences.getSettings().setValue("PEP8/FixCodes", "")
1813 Preferences.getSettings().setValue("PEP8/NoFixCodes", "E501") 1950 Preferences.getSettings().setValue("PEP8/NoFixCodes", "E501")
1814 Preferences.getSettings().setValue("PEP8/FixIssues", False) 1951 Preferences.getSettings().setValue("PEP8/FixIssues", False)
1821 Preferences.getSettings().setValue("PEP8/DocstringType", "pep257") 1958 Preferences.getSettings().setValue("PEP8/DocstringType", "pep257")
1822 Preferences.getSettings().setValue("PEP8/MaxCodeComplexity", 10) 1959 Preferences.getSettings().setValue("PEP8/MaxCodeComplexity", 10)
1823 Preferences.getSettings().setValue("PEP8/LineComplexity", 15) 1960 Preferences.getSettings().setValue("PEP8/LineComplexity", 15)
1824 Preferences.getSettings().setValue("PEP8/LineComplexityScore", 10) 1961 Preferences.getSettings().setValue("PEP8/LineComplexityScore", 10)
1825 Preferences.getSettings().setValue( 1962 Preferences.getSettings().setValue(
1826 "PEP8/ValidEncodings", 1963 "PEP8/ValidEncodings", MiscellaneousCheckerDefaultArgs["CodingChecker"]
1827 MiscellaneousCheckerDefaultArgs["CodingChecker"]
1828 ) 1964 )
1829 Preferences.getSettings().setValue( 1965 Preferences.getSettings().setValue(
1830 "PEP8/CopyrightMinFileSize", 1966 "PEP8/CopyrightMinFileSize",
1831 MiscellaneousCheckerDefaultArgs["CopyrightChecker"]["MinFilesize"] 1967 MiscellaneousCheckerDefaultArgs["CopyrightChecker"]["MinFilesize"],
1832 ) 1968 )
1833 Preferences.getSettings().setValue( 1969 Preferences.getSettings().setValue(
1834 "PEP8/CopyrightAuthor", 1970 "PEP8/CopyrightAuthor",
1835 MiscellaneousCheckerDefaultArgs["CopyrightChecker"]["Author"] 1971 MiscellaneousCheckerDefaultArgs["CopyrightChecker"]["Author"],
1836 ) 1972 )
1837 Preferences.getSettings().setValue("PEP8/FutureChecker", "") 1973 Preferences.getSettings().setValue("PEP8/FutureChecker", "")
1838 Preferences.getSettings().setValue( 1974 Preferences.getSettings().setValue(
1839 "PEP8/BuiltinsChecker", 1975 "PEP8/BuiltinsChecker", MiscellaneousCheckerDefaultArgs["BuiltinsChecker"]
1840 MiscellaneousCheckerDefaultArgs["BuiltinsChecker"]
1841 ) 1976 )
1842 Preferences.getSettings().setValue( 1977 Preferences.getSettings().setValue(
1843 "PEP8/AggressiveSearch", 1978 "PEP8/AggressiveSearch",
1844 MiscellaneousCheckerDefaultArgs[ 1979 MiscellaneousCheckerDefaultArgs["CommentedCodeChecker"]["Aggressive"],
1845 "CommentedCodeChecker"]["Aggressive"]
1846 ) 1980 )
1847 Preferences.getSettings().setValue( 1981 Preferences.getSettings().setValue(
1848 "PEP8/CommentedCodeWhitelist", 1982 "PEP8/CommentedCodeWhitelist",
1849 MiscellaneousCheckerDefaultArgs[ 1983 MiscellaneousCheckerDefaultArgs["CommentedCodeChecker"]["WhiteList"],
1850 "CommentedCodeChecker"]["WhiteList"] 1984 )
1851 ) 1985
1852
1853 # Type Annotations Checker 1986 # Type Annotations Checker
1854 Preferences.getSettings().setValue( 1987 Preferences.getSettings().setValue(
1855 "PEP8/MinimumAnnotationsCoverage", 1988 "PEP8/MinimumAnnotationsCoverage",
1856 AnnotationsCheckerDefaultArgs["MinimumCoverage"]) 1989 AnnotationsCheckerDefaultArgs["MinimumCoverage"],
1990 )
1857 Preferences.getSettings().setValue( 1991 Preferences.getSettings().setValue(
1858 "PEP8/MaximumAnnotationComplexity", 1992 "PEP8/MaximumAnnotationComplexity",
1859 AnnotationsCheckerDefaultArgs["MaximumComplexity"]) 1993 AnnotationsCheckerDefaultArgs["MaximumComplexity"],
1994 )
1860 Preferences.getSettings().setValue( 1995 Preferences.getSettings().setValue(
1861 "PEP8/MaximumAnnotationLength", 1996 "PEP8/MaximumAnnotationLength",
1862 AnnotationsCheckerDefaultArgs["MaximumLength"]) 1997 AnnotationsCheckerDefaultArgs["MaximumLength"],
1998 )
1863 Preferences.getSettings().setValue( 1999 Preferences.getSettings().setValue(
1864 "PEP8/SuppressNoneReturning", 2000 "PEP8/SuppressNoneReturning",
1865 AnnotationsCheckerDefaultArgs["SuppressNoneReturning"]) 2001 AnnotationsCheckerDefaultArgs["SuppressNoneReturning"],
1866 Preferences.getSettings().setValue( 2002 )
1867 "PEP8/SuppressDummyArgs", 2003 Preferences.getSettings().setValue(
1868 AnnotationsCheckerDefaultArgs["SuppressDummyArgs"]) 2004 "PEP8/SuppressDummyArgs", AnnotationsCheckerDefaultArgs["SuppressDummyArgs"]
1869 Preferences.getSettings().setValue( 2005 )
1870 "PEP8/AllowUntypedDefs", 2006 Preferences.getSettings().setValue(
1871 AnnotationsCheckerDefaultArgs["AllowUntypedDefs"]) 2007 "PEP8/AllowUntypedDefs", AnnotationsCheckerDefaultArgs["AllowUntypedDefs"]
2008 )
1872 Preferences.getSettings().setValue( 2009 Preferences.getSettings().setValue(
1873 "PEP8/AllowUntypedNested", 2010 "PEP8/AllowUntypedNested",
1874 AnnotationsCheckerDefaultArgs["AllowUntypedNested"]) 2011 AnnotationsCheckerDefaultArgs["AllowUntypedNested"],
1875 Preferences.getSettings().setValue( 2012 )
1876 "PEP8/MypyInitReturn", 2013 Preferences.getSettings().setValue(
1877 AnnotationsCheckerDefaultArgs["MypyInitReturn"]) 2014 "PEP8/MypyInitReturn", AnnotationsCheckerDefaultArgs["MypyInitReturn"]
2015 )
1878 Preferences.getSettings().setValue( 2016 Preferences.getSettings().setValue(
1879 "PEP8/DispatchDecorators", 2017 "PEP8/DispatchDecorators",
1880 AnnotationsCheckerDefaultArgs["DispatchDecorators"]) 2018 AnnotationsCheckerDefaultArgs["DispatchDecorators"],
2019 )
1881 Preferences.getSettings().setValue( 2020 Preferences.getSettings().setValue(
1882 "PEP8/OverloadDecorators", 2021 "PEP8/OverloadDecorators",
1883 AnnotationsCheckerDefaultArgs["OverloadDecorators"]) 2022 AnnotationsCheckerDefaultArgs["OverloadDecorators"],
1884 2023 )
2024
1885 # Security Checker 2025 # Security Checker
1886 from .Security.SecurityDefaults import SecurityDefaults 2026 from .Security.SecurityDefaults import SecurityDefaults
2027
1887 Preferences.getSettings().setValue( 2028 Preferences.getSettings().setValue(
1888 "PEP8/HardcodedTmpDirectories", 2029 "PEP8/HardcodedTmpDirectories",
1889 SecurityDefaults["hardcoded_tmp_directories"]) 2030 SecurityDefaults["hardcoded_tmp_directories"],
1890 Preferences.getSettings().setValue( 2031 )
1891 "PEP8/InsecureHashes", 2032 Preferences.getSettings().setValue(
1892 SecurityDefaults["insecure_hashes"]) 2033 "PEP8/InsecureHashes", SecurityDefaults["insecure_hashes"]
2034 )
1893 Preferences.getSettings().setValue( 2035 Preferences.getSettings().setValue(
1894 "PEP8/InsecureSslProtocolVersions", 2036 "PEP8/InsecureSslProtocolVersions",
1895 SecurityDefaults["insecure_ssl_protocol_versions"]) 2037 SecurityDefaults["insecure_ssl_protocol_versions"],
1896 Preferences.getSettings().setValue( 2038 )
1897 "PEP8/WeakKeySizeDsaHigh", 2039 Preferences.getSettings().setValue(
1898 str(SecurityDefaults["weak_key_size_dsa_high"])) 2040 "PEP8/WeakKeySizeDsaHigh", str(SecurityDefaults["weak_key_size_dsa_high"])
2041 )
1899 Preferences.getSettings().setValue( 2042 Preferences.getSettings().setValue(
1900 "PEP8/WeakKeySizeDsaMedium", 2043 "PEP8/WeakKeySizeDsaMedium",
1901 str(SecurityDefaults["weak_key_size_dsa_medium"])) 2044 str(SecurityDefaults["weak_key_size_dsa_medium"]),
1902 Preferences.getSettings().setValue( 2045 )
1903 "PEP8/WeakKeySizeRsaHigh", 2046 Preferences.getSettings().setValue(
1904 str(SecurityDefaults["weak_key_size_rsa_high"])) 2047 "PEP8/WeakKeySizeRsaHigh", str(SecurityDefaults["weak_key_size_rsa_high"])
2048 )
1905 Preferences.getSettings().setValue( 2049 Preferences.getSettings().setValue(
1906 "PEP8/WeakKeySizeRsaMedium", 2050 "PEP8/WeakKeySizeRsaMedium",
1907 str(SecurityDefaults["weak_key_size_rsa_medium"])) 2051 str(SecurityDefaults["weak_key_size_rsa_medium"]),
1908 Preferences.getSettings().setValue( 2052 )
1909 "PEP8/WeakKeySizeEcHigh", 2053 Preferences.getSettings().setValue(
1910 str(SecurityDefaults["weak_key_size_ec_high"])) 2054 "PEP8/WeakKeySizeEcHigh", str(SecurityDefaults["weak_key_size_ec_high"])
1911 Preferences.getSettings().setValue( 2055 )
1912 "PEP8/WeakKeySizeEcMedium", 2056 Preferences.getSettings().setValue(
1913 str(SecurityDefaults["weak_key_size_ec_medium"])) 2057 "PEP8/WeakKeySizeEcMedium", str(SecurityDefaults["weak_key_size_ec_medium"])
1914 Preferences.getSettings().setValue( 2058 )
1915 "PEP8/CheckTypedException", 2059 Preferences.getSettings().setValue(
1916 SecurityDefaults["check_typed_exception"]) 2060 "PEP8/CheckTypedException", SecurityDefaults["check_typed_exception"]
1917 2061 )
2062
1918 # Imports Checker 2063 # Imports Checker
1919 Preferences.getSettings().setValue( 2064 Preferences.getSettings().setValue("PEP8/ApplicationPackageNames", [])
1920 "PEP8/ApplicationPackageNames", []) 2065 Preferences.getSettings().setValue("PEP8/BannedModules", [])
1921 Preferences.getSettings().setValue( 2066 Preferences.getSettings().setValue("PEP8/BanRelativeImports", "")
1922 "PEP8/BannedModules", []) 2067
1923 Preferences.getSettings().setValue(
1924 "PEP8/BanRelativeImports", "")
1925
1926 # Update UI with default values 2068 # Update UI with default values
1927 self.on_loadDefaultButton_clicked() 2069 self.on_loadDefaultButton_clicked()
1928 2070
1929 @pyqtSlot() 2071 @pyqtSlot()
1930 def on_cancelButton_clicked(self): 2072 def on_cancelButton_clicked(self):
1931 """ 2073 """
1932 Private slot to handle the "Cancel" button press. 2074 Private slot to handle the "Cancel" button press.
1933 """ 2075 """
1934 if self.__batch: 2076 if self.__batch:
1935 self.styleCheckService.cancelStyleBatchCheck() 2077 self.styleCheckService.cancelStyleBatchCheck()
1936 QTimer.singleShot(1000, self.__finish) 2078 QTimer.singleShot(1000, self.__finish)
1937 else: 2079 else:
1938 self.__finish() 2080 self.__finish()
1939 2081
1940 @pyqtSlot(QAbstractButton) 2082 @pyqtSlot(QAbstractButton)
1941 def on_buttonBox_clicked(self, button): 2083 def on_buttonBox_clicked(self, button):
1942 """ 2084 """
1943 Private slot called by a button of the button box clicked. 2085 Private slot called by a button of the button box clicked.
1944 2086
1945 @param button button that was clicked 2087 @param button button that was clicked
1946 @type QAbstractButton 2088 @type QAbstractButton
1947 """ 2089 """
1948 if button == self.buttonBox.button( 2090 if button == self.buttonBox.button(QDialogButtonBox.StandardButton.Close):
1949 QDialogButtonBox.StandardButton.Close
1950 ):
1951 self.close() 2091 self.close()
1952 2092
1953 def __clearErrors(self, files): 2093 def __clearErrors(self, files):
1954 """ 2094 """
1955 Private method to clear all warning markers of open editors to be 2095 Private method to clear all warning markers of open editors to be
1956 checked. 2096 checked.
1957 2097
1958 @param files list of files to be checked 2098 @param files list of files to be checked
1959 @type list of str 2099 @type list of str
1960 """ 2100 """
1961 vm = ericApp().getObject("ViewManager") 2101 vm = ericApp().getObject("ViewManager")
1962 openFiles = vm.getOpenFilenames() 2102 openFiles = vm.getOpenFilenames()
1963 for file in [f for f in openFiles if f in files]: 2103 for file in [f for f in openFiles if f in files]:
1964 editor = vm.getOpenEditor(file) 2104 editor = vm.getOpenEditor(file)
1965 editor.clearStyleWarnings() 2105 editor.clearStyleWarnings()
1966 2106
1967 @pyqtSlot() 2107 @pyqtSlot()
1968 def on_fixButton_clicked(self): 2108 def on_fixButton_clicked(self):
1969 """ 2109 """
1970 Private slot to fix selected issues. 2110 Private slot to fix selected issues.
1971 2111
1972 Build a dictionary of issues to fix. Update the initialized __options. 2112 Build a dictionary of issues to fix. Update the initialized __options.
1973 Then call check with the dict as keyparam to fix selected issues. 2113 Then call check with the dict as keyparam to fix selected issues.
1974 """ 2114 """
1975 fixableItems = self.__getSelectedFixableItems() 2115 fixableItems = self.__getSelectedFixableItems()
1976 # dictionary of lists of tuples containing the issue and the item 2116 # dictionary of lists of tuples containing the issue and the item
1977 fixesDict = {} 2117 fixesDict = {}
1978 for itm in fixableItems: 2118 for itm in fixableItems:
1979 filename = itm.data(0, self.filenameRole) 2119 filename = itm.data(0, self.filenameRole)
1980 if filename not in fixesDict: 2120 if filename not in fixesDict:
1981 fixesDict[filename] = [] 2121 fixesDict[filename] = []
1982 fixesDict[filename].append(( 2122 fixesDict[filename].append(
1983 { 2123 (
1984 "file": filename, 2124 {
1985 "line": itm.data(0, self.lineRole), 2125 "file": filename,
1986 "offset": itm.data(0, self.positionRole), 2126 "line": itm.data(0, self.lineRole),
1987 "code": itm.data(0, self.codeRole), 2127 "offset": itm.data(0, self.positionRole),
1988 "display": itm.data(0, self.messageRole), 2128 "code": itm.data(0, self.codeRole),
1989 "args": itm.data(0, self.argsRole), 2129 "display": itm.data(0, self.messageRole),
1990 }, 2130 "args": itm.data(0, self.argsRole),
1991 itm 2131 },
1992 )) 2132 itm,
1993 2133 )
2134 )
2135
1994 # update the configuration values (3: fixCodes, 4: noFixCodes, 2136 # update the configuration values (3: fixCodes, 4: noFixCodes,
1995 # 5: fixIssues, 6: maxLineLength) 2137 # 5: fixIssues, 6: maxLineLength)
1996 self.__options[3] = self.fixIssuesEdit.text() 2138 self.__options[3] = self.fixIssuesEdit.text()
1997 self.__options[4] = self.noFixIssuesEdit.text() 2139 self.__options[4] = self.noFixIssuesEdit.text()
1998 self.__options[5] = True 2140 self.__options[5] = True
1999 self.__options[6] = self.lineLengthSpinBox.value() 2141 self.__options[6] = self.lineLengthSpinBox.value()
2000 2142
2001 self.files = list(fixesDict.keys()) 2143 self.files = list(fixesDict.keys())
2002 # now go through all the files 2144 # now go through all the files
2003 self.progress = 0 2145 self.progress = 0
2004 self.files.sort() 2146 self.files.sort()
2005 self.cancelled = False 2147 self.cancelled = False
2006 self.__onlyFixes = fixesDict 2148 self.__onlyFixes = fixesDict
2007 self.check() 2149 self.check()
2008 2150
2009 def __getSelectedFixableItems(self): 2151 def __getSelectedFixableItems(self):
2010 """ 2152 """
2011 Private method to extract all selected items for fixable issues. 2153 Private method to extract all selected items for fixable issues.
2012 2154
2013 @return selected items for fixable issues 2155 @return selected items for fixable issues
2014 @rtype list of QTreeWidgetItem 2156 @rtype list of QTreeWidgetItem
2015 """ 2157 """
2016 fixableItems = [] 2158 fixableItems = []
2017 for itm in self.resultList.selectedItems(): 2159 for itm in self.resultList.selectedItems():
2020 citm = itm.child(index) 2162 citm = itm.child(index)
2021 if self.__itemFixable(citm) and citm not in fixableItems: 2163 if self.__itemFixable(citm) and citm not in fixableItems:
2022 fixableItems.append(citm) 2164 fixableItems.append(citm)
2023 elif self.__itemFixable(itm) and itm not in fixableItems: 2165 elif self.__itemFixable(itm) and itm not in fixableItems:
2024 fixableItems.append(itm) 2166 fixableItems.append(itm)
2025 2167
2026 return fixableItems 2168 return fixableItems
2027 2169
2028 def __itemFixable(self, itm): 2170 def __itemFixable(self, itm):
2029 """ 2171 """
2030 Private method to check, if an item has a fixable issue. 2172 Private method to check, if an item has a fixable issue.
2031 2173
2032 @param itm item to be checked 2174 @param itm item to be checked
2033 @type QTreeWidgetItem 2175 @type QTreeWidgetItem
2034 @return flag indicating a fixable issue 2176 @return flag indicating a fixable issue
2035 @rtype bool 2177 @rtype bool
2036 """ 2178 """
2037 return (itm.data(0, self.fixableRole) and 2179 return itm.data(0, self.fixableRole) and not itm.data(0, self.ignoredRole)
2038 not itm.data(0, self.ignoredRole)) 2180
2039
2040 def __initFuturesList(self, selectedFutures): 2181 def __initFuturesList(self, selectedFutures):
2041 """ 2182 """
2042 Private method to set the selected status of the future imports. 2183 Private method to set the selected status of the future imports.
2043 2184
2044 @param selectedFutures comma separated list of expected future imports 2185 @param selectedFutures comma separated list of expected future imports
2045 @type str 2186 @type str
2046 """ 2187 """
2047 expectedImports = ( 2188 expectedImports = (
2048 [i.strip() for i in selectedFutures.split(",") if bool(i.strip())] 2189 [i.strip() for i in selectedFutures.split(",") if bool(i.strip())]
2049 if selectedFutures else 2190 if selectedFutures
2050 [] 2191 else []
2051 ) 2192 )
2052 for row in range(self.futuresList.count()): 2193 for row in range(self.futuresList.count()):
2053 itm = self.futuresList.item(row) 2194 itm = self.futuresList.item(row)
2054 if itm.text() in expectedImports: 2195 if itm.text() in expectedImports:
2055 itm.setCheckState(Qt.CheckState.Checked) 2196 itm.setCheckState(Qt.CheckState.Checked)
2056 else: 2197 else:
2057 itm.setCheckState(Qt.CheckState.Unchecked) 2198 itm.setCheckState(Qt.CheckState.Unchecked)
2058 2199
2059 def __getSelectedFutureImports(self): 2200 def __getSelectedFutureImports(self):
2060 """ 2201 """
2061 Private method to get the expected future imports. 2202 Private method to get the expected future imports.
2062 2203
2063 @return expected future imports as a comma separated string 2204 @return expected future imports as a comma separated string
2064 @rtype str 2205 @rtype str
2065 """ 2206 """
2066 selectedFutures = [] 2207 selectedFutures = []
2067 for row in range(self.futuresList.count()): 2208 for row in range(self.futuresList.count()):
2068 itm = self.futuresList.item(row) 2209 itm = self.futuresList.item(row)
2069 if itm.checkState() == Qt.CheckState.Checked: 2210 if itm.checkState() == Qt.CheckState.Checked:
2070 selectedFutures.append(itm.text()) 2211 selectedFutures.append(itm.text())
2071 return ", ".join(selectedFutures) 2212 return ", ".join(selectedFutures)
2072 2213
2073 def __initBuiltinsIgnoreList(self, builtinsIgnoreDict): 2214 def __initBuiltinsIgnoreList(self, builtinsIgnoreDict):
2074 """ 2215 """
2075 Private method to populate the list of shadowed builtins to be ignored. 2216 Private method to populate the list of shadowed builtins to be ignored.
2076 2217
2077 @param builtinsIgnoreDict dictionary containing the builtins 2218 @param builtinsIgnoreDict dictionary containing the builtins
2078 assignments to be ignored 2219 assignments to be ignored
2079 @type dict of list of str 2220 @type dict of list of str
2080 """ 2221 """
2081 self.builtinsAssignmentList.clear() 2222 self.builtinsAssignmentList.clear()
2082 for left, rightList in builtinsIgnoreDict.items(): 2223 for left, rightList in builtinsIgnoreDict.items():
2083 for right in rightList: 2224 for right in rightList:
2084 QTreeWidgetItem(self.builtinsAssignmentList, [left, right]) 2225 QTreeWidgetItem(self.builtinsAssignmentList, [left, right])
2085 2226
2086 self.on_builtinsAssignmentList_itemSelectionChanged() 2227 self.on_builtinsAssignmentList_itemSelectionChanged()
2087 2228
2088 def __getBuiltinsIgnoreList(self): 2229 def __getBuiltinsIgnoreList(self):
2089 """ 2230 """
2090 Private method to get a dictionary containing the builtins assignments 2231 Private method to get a dictionary containing the builtins assignments
2091 to be ignored. 2232 to be ignored.
2092 2233
2093 @return dictionary containing the builtins assignments to be ignored 2234 @return dictionary containing the builtins assignments to be ignored
2094 @rtype dict of list of str 2235 @rtype dict of list of str
2095 """ 2236 """
2096 builtinsIgnoreDict = {} 2237 builtinsIgnoreDict = {}
2097 for row in range(self.builtinsAssignmentList.topLevelItemCount()): 2238 for row in range(self.builtinsAssignmentList.topLevelItemCount()):
2098 itm = self.builtinsAssignmentList.topLevelItem(row) 2239 itm = self.builtinsAssignmentList.topLevelItem(row)
2099 left, right = itm.text(0), itm.text(1) 2240 left, right = itm.text(0), itm.text(1)
2100 if left not in builtinsIgnoreDict: 2241 if left not in builtinsIgnoreDict:
2101 builtinsIgnoreDict[left] = [] 2242 builtinsIgnoreDict[left] = []
2102 builtinsIgnoreDict[left].append(right) 2243 builtinsIgnoreDict[left].append(right)
2103 2244
2104 return builtinsIgnoreDict 2245 return builtinsIgnoreDict
2105 2246
2106 @pyqtSlot() 2247 @pyqtSlot()
2107 def on_builtinsAssignmentList_itemSelectionChanged(self): 2248 def on_builtinsAssignmentList_itemSelectionChanged(self):
2108 """ 2249 """
2109 Private slot to react upon changes of the selected builtin assignments. 2250 Private slot to react upon changes of the selected builtin assignments.
2110 """ 2251 """
2111 self.deleteBuiltinButton.setEnabled( 2252 self.deleteBuiltinButton.setEnabled(
2112 len(self.builtinsAssignmentList.selectedItems()) > 0) 2253 len(self.builtinsAssignmentList.selectedItems()) > 0
2113 2254 )
2255
2114 @pyqtSlot() 2256 @pyqtSlot()
2115 def on_addBuiltinButton_clicked(self): 2257 def on_addBuiltinButton_clicked(self):
2116 """ 2258 """
2117 Private slot to add a built-in assignment to be ignored. 2259 Private slot to add a built-in assignment to be ignored.
2118 """ 2260 """
2119 from .CodeStyleAddBuiltinIgnoreDialog import ( 2261 from .CodeStyleAddBuiltinIgnoreDialog import CodeStyleAddBuiltinIgnoreDialog
2120 CodeStyleAddBuiltinIgnoreDialog 2262
2121 )
2122 dlg = CodeStyleAddBuiltinIgnoreDialog(self) 2263 dlg = CodeStyleAddBuiltinIgnoreDialog(self)
2123 if dlg.exec() == QDialog.DialogCode.Accepted: 2264 if dlg.exec() == QDialog.DialogCode.Accepted:
2124 left, right = dlg.getData() 2265 left, right = dlg.getData()
2125 QTreeWidgetItem(self.builtinsAssignmentList, [left, right]) 2266 QTreeWidgetItem(self.builtinsAssignmentList, [left, right])
2126 2267
2127 @pyqtSlot() 2268 @pyqtSlot()
2128 def on_deleteBuiltinButton_clicked(self): 2269 def on_deleteBuiltinButton_clicked(self):
2129 """ 2270 """
2130 Private slot to delete the selected items from the list. 2271 Private slot to delete the selected items from the list.
2131 """ 2272 """
2132 for itm in self.builtinsAssignmentList.selectedItems(): 2273 for itm in self.builtinsAssignmentList.selectedItems():
2133 index = self.builtinsAssignmentList.indexOfTopLevelItem(itm) 2274 index = self.builtinsAssignmentList.indexOfTopLevelItem(itm)
2134 self.builtinsAssignmentList.takeTopLevelItem(index) 2275 self.builtinsAssignmentList.takeTopLevelItem(index)
2135 del itm 2276 del itm
2136 2277
2137 def __initCategoriesList(self, enabledCategories): 2278 def __initCategoriesList(self, enabledCategories):
2138 """ 2279 """
2139 Private method to set the enabled status of the checker categories. 2280 Private method to set the enabled status of the checker categories.
2140 2281
2141 @param enabledCategories comma separated list of enabled checker 2282 @param enabledCategories comma separated list of enabled checker
2142 categories 2283 categories
2143 @type str 2284 @type str
2144 """ 2285 """
2145 enabledCategoriesList = ( 2286 enabledCategoriesList = (
2146 [c.strip() for c in enabledCategories.split(",") 2287 [c.strip() for c in enabledCategories.split(",") if bool(c.strip())]
2147 if bool(c.strip())] 2288 if enabledCategories
2148 if enabledCategories else 2289 else list(CodeStyleCheckerDialog.checkCategories.keys())
2149 list(CodeStyleCheckerDialog.checkCategories.keys())
2150 ) 2290 )
2151 for row in range(self.categoriesList.count()): 2291 for row in range(self.categoriesList.count()):
2152 itm = self.categoriesList.item(row) 2292 itm = self.categoriesList.item(row)
2153 if itm.data(Qt.ItemDataRole.UserRole) in enabledCategoriesList: 2293 if itm.data(Qt.ItemDataRole.UserRole) in enabledCategoriesList:
2154 itm.setCheckState(Qt.CheckState.Checked) 2294 itm.setCheckState(Qt.CheckState.Checked)
2155 else: 2295 else:
2156 itm.setCheckState(Qt.CheckState.Unchecked) 2296 itm.setCheckState(Qt.CheckState.Unchecked)
2157 2297
2158 def __getCategories(self, enabled, asList=False): 2298 def __getCategories(self, enabled, asList=False):
2159 """ 2299 """
2160 Private method to get the enabled or disabled checker categories. 2300 Private method to get the enabled or disabled checker categories.
2161 2301
2162 @param enabled flag indicating to return enabled categories 2302 @param enabled flag indicating to return enabled categories
2163 @type bool 2303 @type bool
2164 @param asList flag indicating to return the checker categories as a 2304 @param asList flag indicating to return the checker categories as a
2165 Python list 2305 Python list
2166 @type bool 2306 @type bool
2167 @return checker categories as a list or comma separated string 2307 @return checker categories as a list or comma separated string
2168 @rtype str or list of str 2308 @rtype str or list of str
2169 """ 2309 """
2170 state = Qt.CheckState.Checked if enabled else Qt.CheckState.Unchecked 2310 state = Qt.CheckState.Checked if enabled else Qt.CheckState.Unchecked
2171 2311
2172 checkerList = [] 2312 checkerList = []
2173 for row in range(self.categoriesList.count()): 2313 for row in range(self.categoriesList.count()):
2174 itm = self.categoriesList.item(row) 2314 itm = self.categoriesList.item(row)
2175 if itm.checkState() == state: 2315 if itm.checkState() == state:
2176 checkerList.append(itm.data(Qt.ItemDataRole.UserRole)) 2316 checkerList.append(itm.data(Qt.ItemDataRole.UserRole))
2177 if asList: 2317 if asList:
2178 return checkerList 2318 return checkerList
2179 else: 2319 else:
2180 return ", ".join(checkerList) 2320 return ", ".join(checkerList)
2181 2321
2182 def __assembleExcludeMessages(self): 2322 def __assembleExcludeMessages(self):
2183 """ 2323 """
2184 Private method to assemble the list of excluded checks. 2324 Private method to assemble the list of excluded checks.
2185 2325
2186 @return list of excluded checks as a comma separated string. 2326 @return list of excluded checks as a comma separated string.
2187 @rtype str 2327 @rtype str
2188 """ 2328 """
2189 excludeMessages = self.excludeMessagesEdit.text() 2329 excludeMessages = self.excludeMessagesEdit.text()
2190 disabledCategories = self.__getCategories(False) 2330 disabledCategories = self.__getCategories(False)
2191 2331
2192 if excludeMessages and disabledCategories: 2332 if excludeMessages and disabledCategories:
2193 return disabledCategories + "," + excludeMessages 2333 return disabledCategories + "," + excludeMessages
2194 elif disabledCategories: 2334 elif disabledCategories:
2195 return disabledCategories 2335 return disabledCategories
2196 elif excludeMessages: 2336 elif excludeMessages:
2197 return excludeMessages 2337 return excludeMessages
2198 else: 2338 else:
2199 return "" 2339 return ""
2200 2340
2201 def __cleanupData(self): 2341 def __cleanupData(self):
2202 """ 2342 """
2203 Private method to clean the loaded/entered data of redundant entries. 2343 Private method to clean the loaded/entered data of redundant entries.
2204 """ 2344 """
2205 # Migrate single letter exclude messages to disabled checker categories 2345 # Migrate single letter exclude messages to disabled checker categories
2206 # and delete them from exlude messages 2346 # and delete them from exlude messages
2207 excludedMessages = [ 2347 excludedMessages = [
2208 m.strip() 2348 m.strip() for m in self.excludeMessagesEdit.text().split(",") if bool(m)
2209 for m in self.excludeMessagesEdit.text().split(",")
2210 if bool(m)
2211 ] 2349 ]
2212 excludedMessageCategories = [ 2350 excludedMessageCategories = [c for c in excludedMessages if len(c) == 1]
2213 c for c in excludedMessages if len(c) == 1
2214 ]
2215 enabledCheckers = self.__getCategories(True, asList=True) 2351 enabledCheckers = self.__getCategories(True, asList=True)
2216 for category in excludedMessageCategories: 2352 for category in excludedMessageCategories:
2217 if category in enabledCheckers: 2353 if category in enabledCheckers:
2218 enabledCheckers.remove(category) 2354 enabledCheckers.remove(category)
2219 excludedMessages.remove(category) 2355 excludedMessages.remove(category)
2220 2356
2221 # Remove excluded messages of an already excluded category 2357 # Remove excluded messages of an already excluded category
2222 disabledCheckers = self.__getCategories(False, asList=True) 2358 disabledCheckers = self.__getCategories(False, asList=True)
2223 for message in excludedMessages[:]: 2359 for message in excludedMessages[:]:
2224 if message[0] in disabledCheckers: 2360 if message[0] in disabledCheckers:
2225 excludedMessages.remove(message) 2361 excludedMessages.remove(message)
2226 2362
2227 self.excludeMessagesEdit.setText(",".join(excludedMessages)) 2363 self.excludeMessagesEdit.setText(",".join(excludedMessages))
2228 self.__initCategoriesList(",".join(enabledCheckers)) 2364 self.__initCategoriesList(",".join(enabledCheckers))
2229 2365
2230 def __initCommentedCodeCheckerWhiteList(self, whitelist): 2366 def __initCommentedCodeCheckerWhiteList(self, whitelist):
2231 """ 2367 """
2232 Private method to populate the list of commented code whitelist 2368 Private method to populate the list of commented code whitelist
2233 patterns. 2369 patterns.
2234 2370
2235 @param whitelist list of commented code whitelist patterns 2371 @param whitelist list of commented code whitelist patterns
2236 @type list of str 2372 @type list of str
2237 """ 2373 """
2238 self.whitelistWidget.clear() 2374 self.whitelistWidget.clear()
2239 2375
2240 for pattern in whitelist: 2376 for pattern in whitelist:
2241 QListWidgetItem(pattern, self.whitelistWidget) 2377 QListWidgetItem(pattern, self.whitelistWidget)
2242 2378
2243 self.on_whitelistWidget_itemSelectionChanged() 2379 self.on_whitelistWidget_itemSelectionChanged()
2244 2380
2245 def __getCommentedCodeCheckerWhiteList(self): 2381 def __getCommentedCodeCheckerWhiteList(self):
2246 """ 2382 """
2247 Private method to get the list of commented code whitelist patterns. 2383 Private method to get the list of commented code whitelist patterns.
2248 2384
2249 @return list of commented code whitelist patterns 2385 @return list of commented code whitelist patterns
2250 @rtype list of str 2386 @rtype list of str
2251 """ 2387 """
2252 whitelist = [] 2388 whitelist = []
2253 2389
2254 for row in range(self.whitelistWidget.count()): 2390 for row in range(self.whitelistWidget.count()):
2255 whitelist.append(self.whitelistWidget.item(row).text()) 2391 whitelist.append(self.whitelistWidget.item(row).text())
2256 2392
2257 return whitelist 2393 return whitelist
2258 2394
2259 @pyqtSlot() 2395 @pyqtSlot()
2260 def on_whitelistWidget_itemSelectionChanged(self): 2396 def on_whitelistWidget_itemSelectionChanged(self):
2261 """ 2397 """
2262 Private slot to react upon changes of the selected whitelist patterns. 2398 Private slot to react upon changes of the selected whitelist patterns.
2263 """ 2399 """
2264 self.deleteWhitelistButton.setEnabled( 2400 self.deleteWhitelistButton.setEnabled(
2265 len(self.whitelistWidget.selectedItems()) > 0) 2401 len(self.whitelistWidget.selectedItems()) > 0
2266 2402 )
2403
2267 @pyqtSlot() 2404 @pyqtSlot()
2268 def on_addWhitelistButton_clicked(self): 2405 def on_addWhitelistButton_clicked(self):
2269 """ 2406 """
2270 Private slot to add a commented code whitelist pattern. 2407 Private slot to add a commented code whitelist pattern.
2271 """ 2408 """
2272 pattern, ok = QInputDialog.getText( 2409 pattern, ok = QInputDialog.getText(
2273 self, 2410 self,
2274 self.tr("Commented Code Whitelist Pattern"), 2411 self.tr("Commented Code Whitelist Pattern"),
2275 self.tr("Enter a Commented Code Whitelist Pattern"), 2412 self.tr("Enter a Commented Code Whitelist Pattern"),
2276 QLineEdit.EchoMode.Normal) 2413 QLineEdit.EchoMode.Normal,
2414 )
2277 if ok and pattern: 2415 if ok and pattern:
2278 QListWidgetItem(pattern, self.whitelistWidget) 2416 QListWidgetItem(pattern, self.whitelistWidget)
2279 2417
2280 @pyqtSlot() 2418 @pyqtSlot()
2281 def on_deleteWhitelistButton_clicked(self): 2419 def on_deleteWhitelistButton_clicked(self):
2282 """ 2420 """
2283 Private slot to delete the selected items from the list. 2421 Private slot to delete the selected items from the list.
2284 """ 2422 """
2285 for itm in self.whitelistWidget.selectedItems(): 2423 for itm in self.whitelistWidget.selectedItems():
2286 row = self.whitelistWidget.row(itm) 2424 row = self.whitelistWidget.row(itm)
2287 self.whitelistWidget.takeItem(row) 2425 self.whitelistWidget.takeItem(row)
2288 del itm 2426 del itm
2289 2427
2290 @pyqtSlot() 2428 @pyqtSlot()
2291 def on_filterButton_clicked(self): 2429 def on_filterButton_clicked(self):
2292 """ 2430 """
2293 Private slot to filter the list of messages based on selected message 2431 Private slot to filter the list of messages based on selected message
2294 code. 2432 code.
2295 """ 2433 """
2296 selectedMessageCode = self.filterComboBox.currentText() 2434 selectedMessageCode = self.filterComboBox.currentText()
2297 2435
2298 for topRow in range(self.resultList.topLevelItemCount()): 2436 for topRow in range(self.resultList.topLevelItemCount()):
2299 topItem = self.resultList.topLevelItem(topRow) 2437 topItem = self.resultList.topLevelItem(topRow)
2300 topItem.setExpanded(True) 2438 topItem.setExpanded(True)
2301 visibleChildren = topItem.childCount() 2439 visibleChildren = topItem.childCount()
2302 for childIndex in range(topItem.childCount()): 2440 for childIndex in range(topItem.childCount()):
2303 childItem = topItem.child(childIndex) 2441 childItem = topItem.child(childIndex)
2304 hideChild = ( 2442 hideChild = (
2305 childItem.data(0, self.codeRole) != selectedMessageCode 2443 childItem.data(0, self.codeRole) != selectedMessageCode
2306 if selectedMessageCode else 2444 if selectedMessageCode
2307 False 2445 else False
2308 ) 2446 )
2309 childItem.setHidden(hideChild) 2447 childItem.setHidden(hideChild)
2310 if hideChild: 2448 if hideChild:
2311 visibleChildren -= 1 2449 visibleChildren -= 1
2312 topItem.setHidden(visibleChildren == 0) 2450 topItem.setHidden(visibleChildren == 0)

eric ide

mercurial