src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Imports/ImportsChecker.py

branch
eric7
changeset 9458
3b41bb7d1623
parent 9453
e5065dde905d
child 9459
f9c6a8f86195
--- 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
     ##

eric ide

mercurial