--- a/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Imports/ImportsChecker.py Mon Oct 31 17:54:41 2022 +0100 +++ b/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Imports/ImportsChecker.py Tue Nov 01 16:46:35 2022 +0100 @@ -65,6 +65,14 @@ self.__tree = copy.deepcopy(tree) self.__args = args + # parameters for import sorting + if args["SortOrder"] == "native": + self.__sortingFunction = sorted + else: + # naturally is the default sort order + self.__sortingFunction = self.__naturally + self.__sortCaseSensitive = args["SortCaseSensitive"] + # statistics counters self.counters = {} @@ -393,11 +401,9 @@ ####################################################################### ## Import order ## - ## adapted from: flake8-alphabetize v0.0.17 + ## adapted from: flake8-alphabetize v0.0.18 ####################################################################### - # TODO: upgrade to v0.0.18 - # TODO: introduce sort type iaw. isort def __checkImportOrder(self): """ Private method to check the order of import statements. @@ -499,12 +505,96 @@ # Can't handle anything that isn't a string literal return None - expectedList = sorted(actualList) + expectedList = self.sorted(actualList, key=self.moduleKey) if expectedList != actualList: return (node, "I204", ", ".join(expectedList)) return None + def sorted(self, toSort, key=None, reverse=False): + """ + Public method to sort the given list of names. + + @param toSort list of names to be sorted + @type list of str + @param key function to generate keys (defaults to None) + @type function (optional) + @param reverse flag indicating a reverse sort (defaults to False) + @type bool (optional) + @return sorted list of names + @rtype list of str + """ + return self.__sortingFunction(toSort, key=key, reverse=reverse) + + def __naturally(self, toSort, key=None, reverse=False): + """ + Private method to sort the given list of names naturally. + + Note: Natural sorting maintains the sort order of numbers (i.e. + [Q1, Q10, Q2] is sorted as [Q1, Q2, Q10] while the Python + standard sort would yield [Q1, Q10, Q2]. + + @param toSort list of names to be sorted + @type list of str + @param key function to generate keys (defaults to None) + @type function (optional) + @param reverse flag indicating a reverse sort (defaults to False) + @type bool (optional) + @return sorted list of names + @rtype list of str + """ + if key is None: + keyCallback = self.__naturalKeys + else: + def keyCallback(text): + return self.__naturalKeys(key(text)) + + return sorted(toSort, key=keyCallback, reverse=reverse) + + def __atoi(self, text): + """ + Private method to convert the given text to an integer number. + + @param text text to be converted + @type str + @return integer number + @rtype int + """ + return int(text) if text.isdigit() else text + + def __naturalKeys(self, text): + """ + Private method to generate keys for natural sorting. + + @param text text to generate a key for + @type str + @return key for natural sorting + @rtype list of str or int + """ + return [self.__atoi(c) for c in re.split(r"(\d+)", text)] + + def moduleKey(self, moduleName): + """ + Public method to generate a key for the given module name. + + @param moduleName module name + @type str + @return generated key + @rtype str + """ + prefix = "" + + if moduleName.isupper() and len(moduleName) > 1: + prefix = "A" + elif moduleName[0:1].isupper(): + prefix = "B" + else: + prefix = "C" + if not self.__sortCaseSensitive: + moduleName = moduleName.lower() + + return f"{prefix}{moduleName}" + ####################################################################### ## Tidy imports ##