diff -r e9e7eca7efee -r bf71ee032bb4 src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/PathLib/PathlibChecker.py --- a/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/PathLib/PathlibChecker.py Wed Jul 13 11:16:20 2022 +0200 +++ b/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/PathLib/PathlibChecker.py Wed Jul 13 14:55:47 2022 +0200 @@ -18,22 +18,43 @@ Class implementing a checker for functions that can be replaced by use of the pathlib module. """ + Codes = [ ## Replacements for the os module functions - "P101", "P102", "P103", "P104", "P105", "P106", "P107", - "P108", "P109", "P110", "P111", "P112", "P113", "P114", - + "P101", + "P102", + "P103", + "P104", + "P105", + "P106", + "P107", + "P108", + "P109", + "P110", + "P111", + "P112", + "P113", + "P114", ## Replacements for the os.path module functions - "P201", "P202", "P203", "P204", "P205", "P206", "P207", - "P208", "P209", "P210", "P211", "P212", "P213", - + "P201", + "P202", + "P203", + "P204", + "P205", + "P206", + "P207", + "P208", + "P209", + "P210", + "P211", + "P212", + "P213", ## Replacements for some Python standrd library functions "P301", - ## Replacements for py.path.local "P401", ] - + # map functions to be replaced to error codes Function2Code = { "os.chmod": "P101", @@ -50,7 +71,6 @@ "os.listdir": "P112", "os.link": "P113", "os.symlink": "P114", - "os.path.abspath": "P201", "os.path.exists": "P202", "os.path.expanduser": "P203", @@ -64,17 +84,14 @@ "os.path.samefile": "P211", "os.path.splitext": "P212", "os.path.relpath": "P213", - "open": "P301", - "py.path.local": "P401", } - - def __init__(self, source, filename, tree, selected, ignored, expected, - repeat): + + def __init__(self, source, filename, tree, selected, ignored, expected, repeat): """ Constructor - + @param source source code to be checked @type list of str @param filename name of the source file @@ -91,22 +108,21 @@ @type bool """ self.__select = tuple(selected) - self.__ignore = ('',) if selected else tuple(ignored) + self.__ignore = ("",) if selected else tuple(ignored) self.__expected = expected[:] self.__repeat = repeat self.__filename = filename self.__source = source[:] self.__tree = copy.deepcopy(tree) - + # statistics counters self.counters = {} - + # collection of detected errors self.errors = [] - - self.__checkCodes = (code for code in self.Codes - if not self.__ignoreCode(code)) - + + self.__checkCodes = (code for code in self.Codes if not self.__ignoreCode(code)) + def __ignoreCode(self, code): """ Private method to check if the message code should be ignored. @@ -116,13 +132,12 @@ @return flag indicating to ignore the given code @rtype bool """ - return (code.startswith(self.__ignore) and - not code.startswith(self.__select)) - + return code.startswith(self.__ignore) and not code.startswith(self.__select) + def __error(self, lineNumber, offset, code, *args): """ Private method to record an issue. - + @param lineNumber line number of the issue @type int @param offset position within line of the issue @@ -134,16 +149,16 @@ """ if self.__ignoreCode(code): return - + if code in self.counters: self.counters[code] += 1 else: self.counters[code] = 1 - + # Don't care about expected codes if code in self.__expected: return - + if code and (self.counters[code] == 1 or self.__repeat): # record the issue with one based line number self.errors.append( @@ -155,7 +170,7 @@ "args": args, } ) - + def run(self): """ Public method to check the given source against functions @@ -164,19 +179,19 @@ if not self.__filename: # don't do anything, if essential data is missing return - + if not self.__checkCodes: # don't do anything, if no codes were selected return - + visitor = PathlibVisitor(self.__checkForReplacement) visitor.visit(self.__tree) - + def __checkForReplacement(self, node, name): """ Private method to check the given node for the need for a replacement. - + @param node reference to the AST node to check @type ast.AST @param name resolved name of the node @@ -191,23 +206,24 @@ """ Class to traverse the AST node tree and check for potential issues. """ + def __init__(self, checkCallback): """ Constructor - + @param checkCallback callback function taking a reference to the AST node and the resolved name @type func """ super().__init__() - + self.__checkCallback = checkCallback self.__importAlias = {} - + def visit_ImportFrom(self, node): """ Public method handle the ImportFrom AST node. - + @param node reference to the ImportFrom AST node @type ast.ImportFrom """ @@ -220,7 +236,7 @@ def visit_Import(self, node): """ Public method to handle the Import AST node. - + @param node reference to the Import AST node @type ast.Import """ @@ -231,13 +247,13 @@ def visit_Call(self, node): """ Public method to handle the Call AST node. - + @param node reference to the Call AST node @type ast.Call """ nameResolver = NameResolver(self.__importAlias) nameResolver.visit(node.func) - + self.__checkCallback(node, nameResolver.name()) @@ -245,20 +261,21 @@ """ Class to resolve a Name or Attribute node. """ + def __init__(self, importAlias): """ Constructor - + @param importAlias reference to the import aliases dictionary @type dict """ self.__importAlias = importAlias self.__names = [] - + def name(self): """ Public method to resolve the name. - + @return resolved name @rtype str """ @@ -266,22 +283,22 @@ attr = self.__importAlias[self.__names[-1]] self.__names[-1] = attr # do nothing if there is no such name or the names list is empty - + return ".".join(reversed(self.__names)) - + def visit_Name(self, node): """ Public method to handle the Name AST node. - + @param node reference to the Name AST node @type ast.Name """ self.__names.append(node.id) - + def visit_Attribute(self, node): """ Public method to handle the Attribute AST node. - + @param node reference to the Attribute AST node @type ast.Attribute """