src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/MiscellaneousChecker.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9274
86fab0c74430
--- a/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/MiscellaneousChecker.py	Wed Jul 13 11:16:20 2022 +0200
+++ b/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/MiscellaneousChecker.py	Wed Jul 13 14:55:47 2022 +0200
@@ -27,7 +27,7 @@
 def composeCallPath(node):
     """
     Generator function to assemble the call path of a given node.
-    
+
     @param node node to assemble call path for
     @type ast.Node
     @yield call path components
@@ -44,88 +44,133 @@
     """
     Class implementing a checker for miscellaneous checks.
     """
+
     Codes = [
         ## Coding line
-        "M101", "M102",
-        
+        "M101",
+        "M102",
         ## Copyright
-        "M111", "M112",
-        
+        "M111",
+        "M112",
         ## Shadowed Builtins
-        "M131", "M132",
-        
+        "M131",
+        "M132",
         ## Comprehensions
-        "M181", "M182", "M183", "M184", "M185", "M186", "M187", "M188",
+        "M181",
+        "M182",
+        "M183",
+        "M184",
+        "M185",
+        "M186",
+        "M187",
+        "M188",
         "M189",
-        "M191", "M192", "M193", "M195", "M196", "M197", "M198",
-        
+        "M191",
+        "M192",
+        "M193",
+        "M195",
+        "M196",
+        "M197",
+        "M198",
         ## Dictionaries with sorted keys
         "M201",
-        
         ## Naive datetime usage
-        "M301", "M302", "M303", "M304", "M305", "M306", "M307", "M308",
-        "M311", "M312", "M313", "M314", "M315",
+        "M301",
+        "M302",
+        "M303",
+        "M304",
+        "M305",
+        "M306",
+        "M307",
+        "M308",
+        "M311",
+        "M312",
+        "M313",
+        "M314",
+        "M315",
         "M321",
-        
         ## sys.version and sys.version_info usage
-        "M401", "M402", "M403",
-        "M411", "M412", "M413", "M414",
-        "M421", "M422", "M423",
-        
+        "M401",
+        "M402",
+        "M403",
+        "M411",
+        "M412",
+        "M413",
+        "M414",
+        "M421",
+        "M422",
+        "M423",
         ## Bugbear
-        "M501", "M502", "M503", "M504", "M505", "M506", "M507", "M508",
+        "M501",
+        "M502",
+        "M503",
+        "M504",
+        "M505",
+        "M506",
+        "M507",
+        "M508",
         "M509",
-        "M511", "M512", "M513",
-        "M521", "M522", "M523", "M524",
-        
+        "M511",
+        "M512",
+        "M513",
+        "M521",
+        "M522",
+        "M523",
+        "M524",
         ## Format Strings
         "M601",
-        "M611", "M612", "M613",
-        "M621", "M622", "M623", "M624", "M625",
-        "M631", "M632",
-        
+        "M611",
+        "M612",
+        "M613",
+        "M621",
+        "M622",
+        "M623",
+        "M624",
+        "M625",
+        "M631",
+        "M632",
         ## Logging
-        "M651", "M652", "M653", "M654", "M655",
-        
+        "M651",
+        "M652",
+        "M653",
+        "M654",
+        "M655",
         ## Future statements
-        "M701", "M702",
-        
+        "M701",
+        "M702",
         ## Gettext
         "M711",
-        
         ## print
         "M801",
-        
         ## one element tuple
         "M811",
-        
         ## Mutable Defaults
-        "M821", "M822",
-        
+        "M821",
+        "M822",
         ## return statements
-        "M831", "M832", "M833", "M834",
-        
+        "M831",
+        "M832",
+        "M833",
+        "M834",
         ## line continuation
         "M841",
-        
         ## commented code
         "M891",
     ]
-    
+
     Formatter = Formatter()
-    FormatFieldRegex = re.compile(r'^((?:\s|.)*?)(\..*|\[.*\])?$')
-    
+    FormatFieldRegex = re.compile(r"^((?:\s|.)*?)(\..*|\[.*\])?$")
+
     BuiltinsWhiteList = [
         "__name__",
         "__doc__",
         "credits",
     ]
 
-    def __init__(self, source, filename, tree, select, ignore, expected,
-                 repeat, args):
+    def __init__(self, source, filename, tree, select, ignore, expected, repeat, args):
         """
         Constructor
-        
+
         @param source source code to be checked
         @type list of str
         @param filename name of the source file
@@ -144,53 +189,127 @@
         @type dict
         """
         self.__select = tuple(select)
-        self.__ignore = ('',) if select else tuple(ignore)
+        self.__ignore = ("",) if select else tuple(ignore)
         self.__expected = expected[:]
         self.__repeat = repeat
         self.__filename = filename
         self.__source = source[:]
         self.__tree = copy.deepcopy(tree)
         self.__args = args
-        
+
         self.__pep3101FormatRegex = re.compile(
-            r'^(?:[^\'"]*[\'"][^\'"]*[\'"])*\s*%|^\s*%')
-        
+            r'^(?:[^\'"]*[\'"][^\'"]*[\'"])*\s*%|^\s*%'
+        )
+
         import builtins
-        self.__builtins = [b for b in dir(builtins)
-                           if b not in self.BuiltinsWhiteList]
-        
+
+        self.__builtins = [b for b in dir(builtins) if b not in self.BuiltinsWhiteList]
+
         self.__eradicator = Eradicator()
-        
+
         # statistics counters
         self.counters = {}
-        
+
         # collection of detected errors
         self.errors = []
-        
+
         checkersWithCodes = [
             (self.__checkCoding, ("M101", "M102")),
             (self.__checkCopyright, ("M111", "M112")),
             (self.__checkBuiltins, ("M131", "M132")),
-            (self.__checkComprehensions, ("M181", "M182", "M183", "M184",
-                                          "M185", "M186", "M187", "M188",
-                                          "M189",
-                                          "M191", "M192", "M193",
-                                          "M195", "M196", "M197", "M198")),
+            (
+                self.__checkComprehensions,
+                (
+                    "M181",
+                    "M182",
+                    "M183",
+                    "M184",
+                    "M185",
+                    "M186",
+                    "M187",
+                    "M188",
+                    "M189",
+                    "M191",
+                    "M192",
+                    "M193",
+                    "M195",
+                    "M196",
+                    "M197",
+                    "M198",
+                ),
+            ),
             (self.__checkDictWithSortedKeys, ("M201",)),
-            (self.__checkDateTime, ("M301", "M302", "M303", "M304", "M305",
-                                    "M306", "M307", "M308", "M311", "M312",
-                                    "M313", "M314", "M315", "M321")),
-            (self.__checkSysVersion, ("M401", "M402", "M403",
-                                      "M411", "M412", "M413", "M414",
-                                      "M421", "M422", "M423")),
-            (self.__checkBugBear, ("M501", "M502", "M503", "M504", "M505",
-                                   "M506", "M507", "M508", "M509",
-                                   "M511", "M512", "M513",
-                                   "M521", "M522", "M523", "M524")),
+            (
+                self.__checkDateTime,
+                (
+                    "M301",
+                    "M302",
+                    "M303",
+                    "M304",
+                    "M305",
+                    "M306",
+                    "M307",
+                    "M308",
+                    "M311",
+                    "M312",
+                    "M313",
+                    "M314",
+                    "M315",
+                    "M321",
+                ),
+            ),
+            (
+                self.__checkSysVersion,
+                (
+                    "M401",
+                    "M402",
+                    "M403",
+                    "M411",
+                    "M412",
+                    "M413",
+                    "M414",
+                    "M421",
+                    "M422",
+                    "M423",
+                ),
+            ),
+            (
+                self.__checkBugBear,
+                (
+                    "M501",
+                    "M502",
+                    "M503",
+                    "M504",
+                    "M505",
+                    "M506",
+                    "M507",
+                    "M508",
+                    "M509",
+                    "M511",
+                    "M512",
+                    "M513",
+                    "M521",
+                    "M522",
+                    "M523",
+                    "M524",
+                ),
+            ),
             (self.__checkPep3101, ("M601",)),
-            (self.__checkFormatString, ("M611", "M612", "M613",
-                                        "M621", "M622", "M623", "M624", "M625",
-                                        "M631", "M632")),
+            (
+                self.__checkFormatString,
+                (
+                    "M611",
+                    "M612",
+                    "M613",
+                    "M621",
+                    "M622",
+                    "M623",
+                    "M624",
+                    "M625",
+                    "M631",
+                    "M632",
+                ),
+            ),
             (self.__checkLogging, ("M651", "M652", "M653", "M654", "M655")),
             (self.__checkFuture, ("M701", "M702")),
             (self.__checkGettext, ("M711",)),
@@ -201,24 +320,25 @@
             (self.__checkLineContinuation, ("M841",)),
             (self.__checkCommentedCode, ("M891",)),
         ]
-        
+
         # the eradicate whitelist
         commentedCodeCheckerArgs = self.__args.get(
             "CommentedCodeChecker",
-            MiscellaneousCheckerDefaultArgs["CommentedCodeChecker"])
+            MiscellaneousCheckerDefaultArgs["CommentedCodeChecker"],
+        )
         commentedCodeCheckerWhitelist = commentedCodeCheckerArgs.get(
             "WhiteList",
-            MiscellaneousCheckerDefaultArgs[
-                "CommentedCodeChecker"]["WhiteList"])
-        self.__eradicator.update_whitelist(commentedCodeCheckerWhitelist,
-                                           extend_default=False)
-        
+            MiscellaneousCheckerDefaultArgs["CommentedCodeChecker"]["WhiteList"],
+        )
+        self.__eradicator.update_whitelist(
+            commentedCodeCheckerWhitelist, extend_default=False
+        )
+
         self.__checkers = []
         for checker, codes in checkersWithCodes:
-            if any(not (code and self.__ignoreCode(code))
-                    for code in codes):
+            if any(not (code and self.__ignoreCode(code)) for code in codes):
                 self.__checkers.append(checker)
-    
+
     def __ignoreCode(self, code):
         """
         Private method to check if the message code should be ignored.
@@ -228,13 +348,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
@@ -246,16 +365,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(
@@ -267,7 +386,7 @@
                     "args": args,
                 }
             )
-    
+
     def run(self):
         """
         Public method to check the given source against miscellaneous
@@ -276,29 +395,28 @@
         if not self.__filename:
             # don't do anything, if essential data is missing
             return
-        
+
         if not self.__checkers:
             # don't do anything, if no codes were selected
             return
-        
+
         for check in self.__checkers:
             check()
-    
+
     def __getCoding(self):
         """
         Private method to get the defined coding of the source.
-        
+
         @return tuple containing the line number and the coding
         @rtype tuple of int and str
         """
         for lineno, line in enumerate(self.__source[:5]):
-            matched = re.search(r'coding[:=]\s*([-\w_.]+)',
-                                line, re.IGNORECASE)
+            matched = re.search(r"coding[:=]\s*([-\w_.]+)", line, re.IGNORECASE)
             if matched:
                 return lineno, matched.group(1)
         else:
             return 0, ""
-    
+
     def __checkCoding(self):
         """
         Private method to check the presence of a coding line and valid
@@ -306,55 +424,56 @@
         """
         if len(self.__source) == 0:
             return
-        
-        encodings = [e.lower().strip()
-                     for e in self.__args.get(
-                     "CodingChecker",
-                     MiscellaneousCheckerDefaultArgs["CodingChecker"])
-                     .split(",")]
+
+        encodings = [
+            e.lower().strip()
+            for e in self.__args.get(
+                "CodingChecker", MiscellaneousCheckerDefaultArgs["CodingChecker"]
+            ).split(",")
+        ]
         lineno, coding = self.__getCoding()
         if coding:
             if coding.lower() not in encodings:
                 self.__error(lineno, 0, "M102", coding)
         else:
             self.__error(0, 0, "M101")
-    
+
     def __checkCopyright(self):
         """
         Private method to check the presence of a copyright statement.
         """
         source = "".join(self.__source)
         copyrightArgs = self.__args.get(
-            "CopyrightChecker",
-            MiscellaneousCheckerDefaultArgs["CopyrightChecker"])
+            "CopyrightChecker", MiscellaneousCheckerDefaultArgs["CopyrightChecker"]
+        )
         copyrightMinFileSize = copyrightArgs.get(
             "MinFilesize",
-            MiscellaneousCheckerDefaultArgs["CopyrightChecker"]["MinFilesize"])
+            MiscellaneousCheckerDefaultArgs["CopyrightChecker"]["MinFilesize"],
+        )
         copyrightAuthor = copyrightArgs.get(
-            "Author",
-            MiscellaneousCheckerDefaultArgs["CopyrightChecker"]["Author"])
+            "Author", MiscellaneousCheckerDefaultArgs["CopyrightChecker"]["Author"]
+        )
         copyrightRegexStr = (
             r"Copyright\s+(\(C\)\s+)?(\d{{4}}\s+-\s+)?\d{{4}}\s+{author}"
         )
-        
+
         tocheck = max(1024, copyrightMinFileSize)
         topOfSource = source[:tocheck]
         if len(topOfSource) < copyrightMinFileSize:
             return
 
-        copyrightRe = re.compile(copyrightRegexStr.format(author=r".*"),
-                                 re.IGNORECASE)
+        copyrightRe = re.compile(copyrightRegexStr.format(author=r".*"), re.IGNORECASE)
         if not copyrightRe.search(topOfSource):
             self.__error(0, 0, "M111")
             return
-        
+
         if copyrightAuthor:
             copyrightAuthorRe = re.compile(
-                copyrightRegexStr.format(author=copyrightAuthor),
-                re.IGNORECASE)
+                copyrightRegexStr.format(author=copyrightAuthor), re.IGNORECASE
+            )
             if not copyrightAuthorRe.search(topOfSource):
                 self.__error(0, 0, "M112")
-    
+
     def __checkCommentedCode(self):
         """
         Private method to check for commented code.
@@ -362,15 +481,17 @@
         source = "".join(self.__source)
         commentedCodeCheckerArgs = self.__args.get(
             "CommentedCodeChecker",
-            MiscellaneousCheckerDefaultArgs["CommentedCodeChecker"])
+            MiscellaneousCheckerDefaultArgs["CommentedCodeChecker"],
+        )
         aggressive = commentedCodeCheckerArgs.get(
             "Aggressive",
-            MiscellaneousCheckerDefaultArgs[
-                "CommentedCodeChecker"]["Aggressive"])
+            MiscellaneousCheckerDefaultArgs["CommentedCodeChecker"]["Aggressive"],
+        )
         for markedLine in self.__eradicator.commented_out_code_line_numbers(
-                source, aggressive=aggressive):
+            source, aggressive=aggressive
+        ):
             self.__error(markedLine - 1, 0, "M891")
-    
+
     def __checkLineContinuation(self):
         """
         Private method to check line continuation using backslash.
@@ -387,37 +508,33 @@
             content = stripped[lineno - 1]
             withoutComment = content[:start] + content[stop:]
             stripped[lineno - 1] = withoutComment.rstrip()
-        
+
         # perform check with 'cleaned' source
         for lineIndex, line in enumerate(stripped):
             strippedLine = line.strip()
-            if (strippedLine.endswith('\\') and
-                    not strippedLine.startswith(('assert', 'with'))):
+            if strippedLine.endswith("\\") and not strippedLine.startswith(
+                ("assert", "with")
+            ):
                 self.__error(lineIndex, len(line), "M841")
-    
+
     def __checkPrintStatements(self):
         """
         Private method to check for print statements.
         """
         for node in ast.walk(self.__tree):
             if (
-                (isinstance(node, ast.Call) and
-                 getattr(node.func, 'id', None) == 'print') or
-                (hasattr(ast, 'Print') and isinstance(node, ast.Print))
-            ):
+                isinstance(node, ast.Call) and getattr(node.func, "id", None) == "print"
+            ) or (hasattr(ast, "Print") and isinstance(node, ast.Print)):
                 self.__error(node.lineno - 1, node.col_offset, "M801")
-    
+
     def __checkTuple(self):
         """
         Private method to check for one element tuples.
         """
         for node in ast.walk(self.__tree):
-            if (
-                isinstance(node, ast.Tuple) and
-                len(node.elts) == 1
-            ):
+            if isinstance(node, ast.Tuple) and len(node.elts) == 1:
                 self.__error(node.lineno - 1, node.col_offset, "M811")
-    
+
     def __checkFuture(self):
         """
         Private method to check the __future__ imports.
@@ -425,27 +542,24 @@
         expectedImports = {
             i.strip()
             for i in self.__args.get("FutureChecker", "").split(",")
-            if bool(i.strip())}
+            if bool(i.strip())
+        }
         if len(expectedImports) == 0:
             # nothing to check for; disabling the check
             return
-        
+
         imports = set()
         node = None
         hasCode = False
-        
+
         for node in ast.walk(self.__tree):
-            if (isinstance(node, ast.ImportFrom) and
-                    node.module == '__future__'):
+            if isinstance(node, ast.ImportFrom) and node.module == "__future__":
                 imports |= {name.name for name in node.names}
             elif isinstance(node, ast.Expr):
                 if not AstUtilities.isString(node.value):
                     hasCode = True
                     break
-            elif not (
-                AstUtilities.isString(node) or
-                isinstance(node, ast.Module)
-            ):
+            elif not (AstUtilities.isString(node) or isinstance(node, ast.Module)):
                 hasCode = True
                 break
 
@@ -454,12 +568,18 @@
 
         if imports < expectedImports:
             if imports:
-                self.__error(node.lineno - 1, node.col_offset, "M701",
-                             ", ".join(expectedImports), ", ".join(imports))
+                self.__error(
+                    node.lineno - 1,
+                    node.col_offset,
+                    "M701",
+                    ", ".join(expectedImports),
+                    ", ".join(imports),
+                )
             else:
-                self.__error(node.lineno - 1, node.col_offset, "M702",
-                             ", ".join(expectedImports))
-    
+                self.__error(
+                    node.lineno - 1, node.col_offset, "M702", ", ".join(expectedImports)
+                )
+
     def __checkPep3101(self):
         """
         Private method to check for old style string formatting.
@@ -468,9 +588,9 @@
             match = self.__pep3101FormatRegex.search(line)
             if match:
                 lineLen = len(line)
-                pos = line.find('%')
+                pos = line.find("%")
                 formatPos = pos
-                formatter = '%'
+                formatter = "%"
                 if line[pos + 1] == "(":
                     pos = line.find(")", pos)
                 c = line[pos]
@@ -482,7 +602,7 @@
                 if c in "diouxXeEfFgGcrs":
                     formatter += c
                 self.__error(lineno, formatPos, "M601", formatter)
-    
+
     def __checkFormatString(self):
         """
         Private method to check string format strings.
@@ -491,7 +611,7 @@
         if not coding:
             # default to utf-8
             coding = "utf-8"
-        
+
         visitor = TextVisitor()
         visitor.visit(self.__tree)
         for node in visitor.nodes:
@@ -510,10 +630,10 @@
                         self.__error(node.lineno - 1, node.col_offset, "M612")
                     else:
                         self.__error(node.lineno - 1, node.col_offset, "M613")
-            
+
             if node in visitor.calls:
                 call, strArgs = visitor.calls[node]
-                
+
                 numbers = set()
                 names = set()
                 # Determine which fields require a keyword and which an arg
@@ -528,20 +648,21 @@
                         numbers.add(number)
                     else:
                         names.add(fieldMatch.group(1))
-                
+
                 keywords = {keyword.arg for keyword in call.keywords}
                 numArgs = len(call.args)
                 if strArgs:
                     numArgs -= 1
                 hasKwArgs = any(kw.arg is None for kw in call.keywords)
-                hasStarArgs = sum(1 for arg in call.args
-                                  if isinstance(arg, ast.Starred))
-                
+                hasStarArgs = sum(
+                    1 for arg in call.args if isinstance(arg, ast.Starred)
+                )
+
                 if hasKwArgs:
                     keywords.discard(None)
                 if hasStarArgs:
                     numArgs -= 1
-                
+
                 # if starargs or kwargs is not None, it can't count the
                 # parameters but at least check if the args are used
                 if hasKwArgs and not names:
@@ -550,36 +671,34 @@
                 if hasStarArgs and not numbers:
                     # No numbers but args
                     self.__error(call.lineno - 1, call.col_offset, "M624")
-                
+
                 if not hasKwArgs and not hasStarArgs:
                     # can actually verify numbers and names
                     for number in sorted(numbers):
                         if number >= numArgs:
-                            self.__error(call.lineno - 1, call.col_offset,
-                                         "M621", number)
-                    
+                            self.__error(
+                                call.lineno - 1, call.col_offset, "M621", number
+                            )
+
                     for name in sorted(names):
                         if name not in keywords:
-                            self.__error(call.lineno - 1, call.col_offset,
-                                         "M622", name)
-                
+                            self.__error(call.lineno - 1, call.col_offset, "M622", name)
+
                 for arg in range(numArgs):
                     if arg not in numbers:
-                        self.__error(call.lineno - 1, call.col_offset, "M631",
-                                     arg)
-                
+                        self.__error(call.lineno - 1, call.col_offset, "M631", arg)
+
                 for keyword in keywords:
                     if keyword not in names:
-                        self.__error(call.lineno - 1, call.col_offset, "M632",
-                                     keyword)
-                
+                        self.__error(call.lineno - 1, call.col_offset, "M632", keyword)
+
                 if implicit and explicit:
                     self.__error(call.lineno - 1, call.col_offset, "M625")
-    
+
     def __getFields(self, string):
         """
         Private method to extract the format field information.
-        
+
         @param string format string to be parsed
         @type str
         @return format field information as a tuple with fields, implicit
@@ -592,21 +711,23 @@
         explicit = False
         try:
             for _literal, field, spec, conv in self.Formatter.parse(string):
-                if field is not None and (conv is None or conv in 'rsa'):
+                if field is not None and (conv is None or conv in "rsa"):
                     if not field:
                         field = str(next(cnt))
                         implicit = True
                     else:
                         explicit = True
                     fields.add(field)
-                    fields.update(parsedSpec[1]
-                                  for parsedSpec in self.Formatter.parse(spec)
-                                  if parsedSpec[1] is not None)
+                    fields.update(
+                        parsedSpec[1]
+                        for parsedSpec in self.Formatter.parse(spec)
+                        if parsedSpec[1] is not None
+                    )
         except ValueError:
             return set(), False, False
         else:
             return fields, implicit, explicit
-    
+
     def __checkBuiltins(self):
         """
         Private method to check, if built-ins are shadowed.
@@ -614,67 +735,64 @@
         functionDefs = [ast.FunctionDef]
         with contextlib.suppress(AttributeError):
             functionDefs.append(ast.AsyncFunctionDef)
-        
+
         ignoreBuiltinAssignments = self.__args.get(
-            "BuiltinsChecker",
-            MiscellaneousCheckerDefaultArgs["BuiltinsChecker"])
-        
+            "BuiltinsChecker", MiscellaneousCheckerDefaultArgs["BuiltinsChecker"]
+        )
+
         for node in ast.walk(self.__tree):
             if isinstance(node, ast.Assign):
                 # assign statement
                 for element in node.targets:
-                    if (
-                        isinstance(element, ast.Name) and
-                        element.id in self.__builtins
-                    ):
+                    if isinstance(element, ast.Name) and element.id in self.__builtins:
                         value = node.value
                         if (
-                            isinstance(value, ast.Name) and
-                            element.id in ignoreBuiltinAssignments and
-                            value.id in ignoreBuiltinAssignments[element.id]
+                            isinstance(value, ast.Name)
+                            and element.id in ignoreBuiltinAssignments
+                            and value.id in ignoreBuiltinAssignments[element.id]
                         ):
                             # ignore compatibility assignments
                             continue
-                        self.__error(element.lineno - 1, element.col_offset,
-                                     "M131", element.id)
+                        self.__error(
+                            element.lineno - 1, element.col_offset, "M131", element.id
+                        )
                     elif isinstance(element, (ast.Tuple, ast.List)):
                         for tupleElement in element.elts:
                             if (
-                                isinstance(tupleElement, ast.Name) and
-                                tupleElement.id in self.__builtins
+                                isinstance(tupleElement, ast.Name)
+                                and tupleElement.id in self.__builtins
                             ):
-                                self.__error(tupleElement.lineno - 1,
-                                             tupleElement.col_offset,
-                                             "M131", tupleElement.id)
+                                self.__error(
+                                    tupleElement.lineno - 1,
+                                    tupleElement.col_offset,
+                                    "M131",
+                                    tupleElement.id,
+                                )
             elif isinstance(node, ast.For):
                 # for loop
                 target = node.target
-                if (
-                    isinstance(target, ast.Name) and
-                    target.id in self.__builtins
-                ):
-                    self.__error(target.lineno - 1, target.col_offset,
-                                 "M131", target.id)
+                if isinstance(target, ast.Name) and target.id in self.__builtins:
+                    self.__error(
+                        target.lineno - 1, target.col_offset, "M131", target.id
+                    )
                 elif isinstance(target, (ast.Tuple, ast.List)):
                     for element in target.elts:
                         if (
-                            isinstance(element, ast.Name) and
-                            element.id in self.__builtins
+                            isinstance(element, ast.Name)
+                            and element.id in self.__builtins
                         ):
-                            self.__error(element.lineno - 1,
-                                         element.col_offset,
-                                         "M131", element.id)
-            elif any(isinstance(node, functionDef)
-                     for functionDef in functionDefs):
+                            self.__error(
+                                element.lineno - 1,
+                                element.col_offset,
+                                "M131",
+                                element.id,
+                            )
+            elif any(isinstance(node, functionDef) for functionDef in functionDefs):
                 # (asynchronous) function definition
                 for arg in node.args.args:
-                    if (
-                        isinstance(arg, ast.arg) and
-                        arg.arg in self.__builtins
-                    ):
-                        self.__error(arg.lineno - 1, arg.col_offset,
-                                     "M132", arg.arg)
-    
+                    if isinstance(arg, ast.arg) and arg.arg in self.__builtins:
+                        self.__error(arg.lineno - 1, arg.col_offset, "M132", arg.arg)
+
     def __checkComprehensions(self):
         """
         Private method to check some comprehension related things.
@@ -683,11 +801,11 @@
             if isinstance(node, ast.Call) and isinstance(node.func, ast.Name):
                 nArgs = len(node.args)
                 nKwArgs = len(node.keywords)
-                
+
                 if (
-                    nArgs == 1 and
-                    isinstance(node.args[0], ast.GeneratorExp) and
-                    node.func.id in ('list', 'set')
+                    nArgs == 1
+                    and isinstance(node.args[0], ast.GeneratorExp)
+                    and node.func.id in ("list", "set")
                 ):
                     errorCode = {
                         "list": "M181",
@@ -696,48 +814,51 @@
                     self.__error(node.lineno - 1, node.col_offset, errorCode)
 
                 elif (
-                    nArgs == 1 and
-                    isinstance(node.args[0],
-                               (ast.GeneratorExp, ast.ListComp)) and
-                    isinstance(node.args[0].elt, ast.Tuple) and
-                    len(node.args[0].elt.elts) == 2 and
-                    node.func.id == "dict"
+                    nArgs == 1
+                    and isinstance(node.args[0], (ast.GeneratorExp, ast.ListComp))
+                    and isinstance(node.args[0].elt, ast.Tuple)
+                    and len(node.args[0].elt.elts) == 2
+                    and node.func.id == "dict"
                 ):
                     if isinstance(node.args[0], ast.GeneratorExp):
                         errorCode = "M183"
                     else:
                         errorCode = "M185"
                     self.__error(node.lineno - 1, node.col_offset, errorCode)
-                
+
                 elif (
-                    nArgs == 1 and
-                    isinstance(node.args[0], ast.ListComp) and
-                    node.func.id in ('list', 'set')
+                    nArgs == 1
+                    and isinstance(node.args[0], ast.ListComp)
+                    and node.func.id in ("list", "set")
                 ):
                     errorCode = {
-                        'list': 'M195',
-                        'set': 'M184',
+                        "list": "M195",
+                        "set": "M184",
                     }[node.func.id]
                     self.__error(node.lineno - 1, node.col_offset, errorCode)
-                
+
                 elif nArgs == 1 and (
-                    isinstance(node.args[0], ast.Tuple) and
-                    node.func.id == "tuple" or
-                    isinstance(node.args[0], ast.List) and
-                    node.func.id == "list"
+                    isinstance(node.args[0], ast.Tuple)
+                    and node.func.id == "tuple"
+                    or isinstance(node.args[0], ast.List)
+                    and node.func.id == "list"
                 ):
                     errorCode = {
-                        'tuple': 'M197',
-                        'list': 'M198',
+                        "tuple": "M197",
+                        "list": "M198",
                     }[node.func.id]
-                    self.__error(node.lineno - 1, node.col_offset, errorCode,
-                                 type(node.args[0]).__name__.lower(),
-                                 node.func.id)
-                
+                    self.__error(
+                        node.lineno - 1,
+                        node.col_offset,
+                        errorCode,
+                        type(node.args[0]).__name__.lower(),
+                        node.func.id,
+                    )
+
                 elif (
-                    nArgs == 1 and
-                    isinstance(node.args[0], (ast.Tuple, ast.List)) and
-                    node.func.id in ("tuple", "list", "set", "dict")
+                    nArgs == 1
+                    and isinstance(node.args[0], (ast.Tuple, ast.List))
+                    and node.func.id in ("tuple", "list", "set", "dict")
                 ):
                     errorCode = {
                         "tuple": "M192",
@@ -745,29 +866,30 @@
                         "set": "M191",
                         "dict": "M191",
                     }[node.func.id]
-                    self.__error(node.lineno - 1, node.col_offset, errorCode,
-                                 type(node.args[0]).__name__.lower(),
-                                 node.func.id)
-                
+                    self.__error(
+                        node.lineno - 1,
+                        node.col_offset,
+                        errorCode,
+                        type(node.args[0]).__name__.lower(),
+                        node.func.id,
+                    )
+
                 elif (
-                    nArgs == 0 and
-                    not any(isinstance(a, ast.Starred) for a in node.args) and
-                    not any(k.arg is None for k in node.keywords) and
-                    node.func.id == "dict"
+                    nArgs == 0
+                    and not any(isinstance(a, ast.Starred) for a in node.args)
+                    and not any(k.arg is None for k in node.keywords)
+                    and node.func.id == "dict"
                 ) or (
-                    nArgs == 0 and
-                    nKwArgs == 0 and
-                    node.func.id in ("tuple", "list")
+                    nArgs == 0 and nKwArgs == 0 and node.func.id in ("tuple", "list")
                 ):
-                    self.__error(node.lineno - 1, node.col_offset, "M186",
-                                 node.func.id)
-                
+                    self.__error(node.lineno - 1, node.col_offset, "M186", node.func.id)
+
                 elif (
-                    node.func.id in {"list", "reversed"} and
-                    nArgs > 0 and
-                    isinstance(node.args[0], ast.Call) and
-                    isinstance(node.args[0].func, ast.Name) and
-                    node.args[0].func.id == "sorted"
+                    node.func.id in {"list", "reversed"}
+                    and nArgs > 0
+                    and isinstance(node.args[0], ast.Call)
+                    and isinstance(node.args[0].func, ast.Name)
+                    and node.args[0].func.id == "sorted"
                 ):
                     if node.func.id == "reversed":
                         reverseFlagValue = False
@@ -783,64 +905,78 @@
                                 reverseFlagValue = None
 
                         if reverseFlagValue is None:
-                            self.__error(node.lineno - 1, node.col_offset,
-                                         "M187a", node.func.id,
-                                         node.args[0].func.id)
+                            self.__error(
+                                node.lineno - 1,
+                                node.col_offset,
+                                "M187a",
+                                node.func.id,
+                                node.args[0].func.id,
+                            )
                         else:
-                            self.__error(node.lineno - 1, node.col_offset,
-                                         "M187b", node.func.id,
-                                         node.args[0].func.id,
-                                         not reverseFlagValue)
+                            self.__error(
+                                node.lineno - 1,
+                                node.col_offset,
+                                "M187b",
+                                node.func.id,
+                                node.args[0].func.id,
+                                not reverseFlagValue,
+                            )
                     else:
-                        self.__error(node.lineno - 1, node.col_offset,
-                                     "M187c", node.func.id,
-                                     node.args[0].func.id)
-                
+                        self.__error(
+                            node.lineno - 1,
+                            node.col_offset,
+                            "M187c",
+                            node.func.id,
+                            node.args[0].func.id,
+                        )
+
                 elif (
-                    nArgs > 0 and
-                    isinstance(node.args[0], ast.Call) and
-                    isinstance(node.args[0].func, ast.Name) and
-                    (
+                    nArgs > 0
+                    and isinstance(node.args[0], ast.Call)
+                    and isinstance(node.args[0].func, ast.Name)
+                    and (
                         (
-                            node.func.id in {"set", "sorted"} and
-                            node.args[0].func.id in {
-                                "list", "reversed", "sorted", "tuple"}
-                        ) or (
-                            node.func.id in {"list", "tuple"} and
-                            node.args[0].func.id in {"list", "tuple"}
-                        ) or (
-                            node.func.id == "set" and
-                            node.args[0].func.id == "set"
+                            node.func.id in {"set", "sorted"}
+                            and node.args[0].func.id
+                            in {"list", "reversed", "sorted", "tuple"}
                         )
+                        or (
+                            node.func.id in {"list", "tuple"}
+                            and node.args[0].func.id in {"list", "tuple"}
+                        )
+                        or (node.func.id == "set" and node.args[0].func.id == "set")
                     )
                 ):
-                    self.__error(node.lineno - 1, node.col_offset, "M188",
-                                 node.args[0].func.id, node.func.id)
-                
+                    self.__error(
+                        node.lineno - 1,
+                        node.col_offset,
+                        "M188",
+                        node.args[0].func.id,
+                        node.func.id,
+                    )
+
                 elif (
-                    node.func.id in {"reversed", "set", "sorted"} and
-                    nArgs > 0 and
-                    isinstance(node.args[0], ast.Subscript) and
-                    isinstance(node.args[0].slice, ast.Slice) and
-                    node.args[0].slice.lower is None and
-                    node.args[0].slice.upper is None and
-                    isinstance(node.args[0].slice.step, ast.UnaryOp) and
-                    isinstance(node.args[0].slice.step.op, ast.USub) and
-                    isinstance(node.args[0].slice.step.operand, ast.Num) and
-                    node.args[0].slice.step.operand.n == 1
+                    node.func.id in {"reversed", "set", "sorted"}
+                    and nArgs > 0
+                    and isinstance(node.args[0], ast.Subscript)
+                    and isinstance(node.args[0].slice, ast.Slice)
+                    and node.args[0].slice.lower is None
+                    and node.args[0].slice.upper is None
+                    and isinstance(node.args[0].slice.step, ast.UnaryOp)
+                    and isinstance(node.args[0].slice.step.op, ast.USub)
+                    and isinstance(node.args[0].slice.step.operand, ast.Num)
+                    and node.args[0].slice.step.operand.n == 1
                 ):
-                    self.__error(node.lineno - 1, node.col_offset,
-                                 "M189", node.func.id)
-                
-                elif (
-                    isinstance(node, (ast.ListComp, ast.SetComp)) and (
-                        len(node.generators) == 1 and
-                        not node.generators[0].ifs and
-                        not node.generators[0].is_async and (
-                            isinstance(node.elt, ast.Name) and
-                            isinstance(node.generators[0].target, ast.Name) and
-                            node.elt.id == node.generators[0].target.id
-                        )
+                    self.__error(node.lineno - 1, node.col_offset, "M189", node.func.id)
+
+                elif isinstance(node, (ast.ListComp, ast.SetComp)) and (
+                    len(node.generators) == 1
+                    and not node.generators[0].ifs
+                    and not node.generators[0].is_async
+                    and (
+                        isinstance(node.elt, ast.Name)
+                        and isinstance(node.generators[0].target, ast.Name)
+                        and node.elt.id == node.generators[0].target.id
                     )
                 ):
                     compType = {
@@ -848,10 +984,9 @@
                         ast.ListComp: "list",
                         ast.SetComp: "set",
                     }[node.__class__]
-                    
-                    self.__error(node.lineno - 1, node.col_offset,
-                                 "M196", compType)
-    
+
+                    self.__error(node.lineno - 1, node.col_offset, "M196", compType)
+
     def __checkMutableDefault(self):
         """
         Private method to check for use of mutable types as default arguments.
@@ -882,52 +1017,58 @@
         functionDefs = [ast.FunctionDef]
         with contextlib.suppress(AttributeError):
             functionDefs.append(ast.AsyncFunctionDef)
-        
+
         for node in ast.walk(self.__tree):
-            if any(isinstance(node, functionDef)
-                   for functionDef in functionDefs):
+            if any(isinstance(node, functionDef) for functionDef in functionDefs):
                 defaults = node.args.defaults[:]
                 with contextlib.suppress(AttributeError):
                     defaults += node.args.kw_defaults[:]
                 for default in defaults:
-                    if any(isinstance(default, mutableType)
-                           for mutableType in mutableTypes):
+                    if any(
+                        isinstance(default, mutableType) for mutableType in mutableTypes
+                    ):
                         typeName = type(default).__name__
                         if isinstance(default, ast.Call):
-                            callPath = '.'.join(composeCallPath(default.func))
+                            callPath = ".".join(composeCallPath(default.func))
                             if callPath in mutableCalls:
-                                self.__error(default.lineno - 1,
-                                             default.col_offset,
-                                             "M823", callPath + "()")
+                                self.__error(
+                                    default.lineno - 1,
+                                    default.col_offset,
+                                    "M823",
+                                    callPath + "()",
+                                )
                             elif callPath not in immutableCalls:
-                                self.__error(default.lineno - 1,
-                                             default.col_offset,
-                                             "M822", typeName)
+                                self.__error(
+                                    default.lineno - 1,
+                                    default.col_offset,
+                                    "M822",
+                                    typeName,
+                                )
                         else:
-                            self.__error(default.lineno - 1,
-                                         default.col_offset,
-                                         "M821", typeName)
-    
+                            self.__error(
+                                default.lineno - 1, default.col_offset, "M821", typeName
+                            )
+
     def __dictShouldBeChecked(self, node):
         """
         Private function to test, if the node should be checked.
-        
+
         @param node reference to the AST node
         @return flag indicating to check the node
         @rtype bool
         """
         if not all(AstUtilities.isString(key) for key in node.keys):
             return False
-        
+
         if (
-            "__IGNORE_WARNING__" in self.__source[node.lineno - 1] or
-            "__IGNORE_WARNING_M201__" in self.__source[node.lineno - 1]
+            "__IGNORE_WARNING__" in self.__source[node.lineno - 1]
+            or "__IGNORE_WARNING_M201__" in self.__source[node.lineno - 1]
         ):
             return False
-        
+
         lineNumbers = [key.lineno for key in node.keys]
         return len(lineNumbers) == len(set(lineNumbers))
-    
+
     def __checkDictWithSortedKeys(self):
         """
         Private method to check, if dictionary keys appear in sorted order.
@@ -936,9 +1077,10 @@
             if isinstance(node, ast.Dict) and self.__dictShouldBeChecked(node):
                 for key1, key2 in zip(node.keys, node.keys[1:]):
                     if key2.s < key1.s:
-                        self.__error(key2.lineno - 1, key2.col_offset,
-                                     "M201", key2.s, key1.s)
-    
+                        self.__error(
+                            key2.lineno - 1, key2.col_offset, "M201", key2.s, key1.s
+                        )
+
     def __checkLogging(self):
         """
         Private method to check logging statements.
@@ -947,19 +1089,19 @@
         visitor.visit(self.__tree)
         for node, reason in visitor.violations:
             self.__error(node.lineno - 1, node.col_offset, reason)
-    
+
     def __checkGettext(self):
         """
         Private method to check the 'gettext' import statement.
         """
         for node in ast.walk(self.__tree):
-            if (
-                isinstance(node, ast.ImportFrom) and
-                any(name.asname == '_' for name in node.names)
+            if isinstance(node, ast.ImportFrom) and any(
+                name.asname == "_" for name in node.names
             ):
-                self.__error(node.lineno - 1, node.col_offset, "M711",
-                             node.names[0].name)
-    
+                self.__error(
+                    node.lineno - 1, node.col_offset, "M711", node.names[0].name
+                )
+
     def __checkBugBear(self):
         """
         Private method for bugbear checks.
@@ -971,7 +1113,7 @@
             reason = violation[1]
             params = violation[2:]
             self.__error(node.lineno - 1, node.col_offset, reason, *params)
-    
+
     def __checkReturn(self):
         """
         Private method to check return statements.
@@ -982,7 +1124,7 @@
             node = violation[0]
             reason = violation[1]
             self.__error(node.lineno - 1, node.col_offset, reason)
-    
+
     def __checkDateTime(self):
         """
         Private method to check use of naive datetime functions.
@@ -993,7 +1135,7 @@
         for node in ast.walk(tree):
             for childNode in ast.iter_child_nodes(node):
                 childNode._dtCheckerParent = node
-        
+
         # step 2: perform checks and report issues
         visitor = DateTimeVisitor()
         visitor.visit(tree)
@@ -1001,7 +1143,7 @@
             node = violation[0]
             reason = violation[1]
             self.__error(node.lineno - 1, node.col_offset, reason)
-    
+
     def __checkSysVersion(self):
         """
         Private method to check the use of sys.version and sys.version_info.
@@ -1021,8 +1163,9 @@
     It tries to detect docstrings as string of the first expression of each
     module, class or function.
     """
+
     # modelled after the string format flake8 extension
-    
+
     def __init__(self):
         """
         Constructor
@@ -1034,18 +1177,18 @@
     def __addNode(self, node):
         """
         Private method to add a node to our list of nodes.
-        
+
         @param node reference to the node to add
         @type ast.AST
         """
-        if not hasattr(node, 'is_docstring'):
+        if not hasattr(node, "is_docstring"):
             node.is_docstring = False
         self.nodes.append(node)
 
     def visit_Str(self, node):
         """
         Public method to record a string node.
-        
+
         @param node reference to the string node
         @type ast.Str
         """
@@ -1054,16 +1197,16 @@
     def visit_Bytes(self, node):
         """
         Public method to record a bytes node.
-        
+
         @param node reference to the bytes node
         @type ast.Bytes
         """
         self.__addNode(node)
-    
+
     def visit_Constant(self, node):
         """
         Public method to handle constant nodes.
-        
+
         @param node reference to the bytes node
         @type ast.Constant
         """
@@ -1078,7 +1221,7 @@
     def __visitDefinition(self, node):
         """
         Private method handling class and function definitions.
-        
+
         @param node reference to the node to handle
         @type ast.FunctionDef, ast.AsyncFunctionDef or ast.ClassDef
         """
@@ -1096,14 +1239,14 @@
 
         If the first node is an expression which contains a string or bytes it
         marks that as a docstring.
-        
+
         @param node reference to the node to traverse
         @type ast.AST
         """
         if (
-            node.body and
-            isinstance(node.body[0], ast.Expr) and
-            AstUtilities.isBaseString(node.body[0].value)
+            node.body
+            and isinstance(node.body[0], ast.Expr)
+            and AstUtilities.isBaseString(node.body[0].value)
         ):
             node.body[0].value.is_docstring = True
 
@@ -1113,7 +1256,7 @@
     def visit_Module(self, node):
         """
         Public method to handle a module.
-        
+
         @param node reference to the node to handle
         @type ast.Module
         """
@@ -1122,7 +1265,7 @@
     def visit_ClassDef(self, node):
         """
         Public method to handle a class definition.
-        
+
         @param node reference to the node to handle
         @type ast.ClassDef
         """
@@ -1132,7 +1275,7 @@
     def visit_FunctionDef(self, node):
         """
         Public method to handle a function definition.
-        
+
         @param node reference to the node to handle
         @type ast.FunctionDef
         """
@@ -1142,7 +1285,7 @@
     def visit_AsyncFunctionDef(self, node):
         """
         Public method to handle an asynchronous function definition.
-        
+
         @param node reference to the node to handle
         @type ast.AsyncFunctionDef
         """
@@ -1152,21 +1295,18 @@
     def visit_Call(self, node):
         """
         Public method to handle a function call.
-        
+
         @param node reference to the node to handle
         @type ast.Call
         """
-        if (
-            isinstance(node.func, ast.Attribute) and
-            node.func.attr == 'format'
-        ):
+        if isinstance(node.func, ast.Attribute) and node.func.attr == "format":
             if AstUtilities.isBaseString(node.func.value):
                 self.calls[node.func.value] = (node, False)
             elif (
-                isinstance(node.func.value, ast.Name) and
-                node.func.value.id == 'str' and
-                node.args and
-                AstUtilities.isBaseString(node.args[0])
+                isinstance(node.func.value, ast.Name)
+                and node.func.value.id == "str"
+                and node.args
+                and AstUtilities.isBaseString(node.args[0])
             ):
                 self.calls[node.args[0]] = (node, True)
         super().generic_visit(node)
@@ -1176,6 +1316,7 @@
     """
     Class implementing a node visitor to check logging statements.
     """
+
     LoggingLevels = {
         "debug",
         "critical",
@@ -1184,13 +1325,13 @@
         "warn",
         "warning",
     }
-    
+
     def __init__(self):
         """
         Constructor
         """
         super().__init__()
-        
+
         self.__currentLoggingCall = None
         self.__currentLoggingArgument = None
         self.__currentLoggingLevel = None
@@ -1200,7 +1341,7 @@
     def __withinLoggingStatement(self):
         """
         Private method to check, if we are inside a logging statement.
-        
+
         @return flag indicating we are inside a logging statement
         @rtype bool
         """
@@ -1209,7 +1350,7 @@
     def __withinLoggingArgument(self):
         """
         Private method to check, if we are inside a logging argument.
-        
+
         @return flag indicating we are inside a logging argument
         @rtype bool
         """
@@ -1218,21 +1359,21 @@
     def __withinExtraKeyword(self, node):
         """
         Private method to check, if we are inside the extra keyword.
-        
+
         @param node reference to the node to be checked
         @type ast.keyword
         @return flag indicating we are inside the extra keyword
         @rtype bool
         """
         return (
-            self.__currentExtraKeyword is not None and
-            self.__currentExtraKeyword != node
+            self.__currentExtraKeyword is not None
+            and self.__currentExtraKeyword != node
         )
-    
+
     def __detectLoggingLevel(self, node):
         """
         Private method to decide whether an AST Call is a logging call.
-        
+
         @param node reference to the node to be processed
         @type ast.Call
         @return logging level
@@ -1241,10 +1382,10 @@
         with contextlib.suppress(AttributeError):
             if node.func.value.id == "warnings":
                 return None
-            
+
             if node.func.attr in LoggingVisitor.LoggingLevels:
                 return node.func.attr
-        
+
         return None
 
     def __isFormatCall(self, node):
@@ -1260,66 +1401,62 @@
             return node.func.attr == "format"
         except AttributeError:
             return False
-    
+
     def visit_Call(self, node):
         """
         Public method to handle a function call.
 
         Every logging statement and string format is expected to be a function
         call.
-        
+
         @param node reference to the node to be processed
         @type ast.Call
         """
         # we are in a logging statement
         if (
-            self.__withinLoggingStatement() and
-            self.__withinLoggingArgument() and
-            self.__isFormatCall(node)
+            self.__withinLoggingStatement()
+            and self.__withinLoggingArgument()
+            and self.__isFormatCall(node)
         ):
             self.violations.append((node, "M651"))
             super().generic_visit(node)
             return
-        
+
         loggingLevel = self.__detectLoggingLevel(node)
-        
+
         if loggingLevel and self.__currentLoggingLevel is None:
             self.__currentLoggingLevel = loggingLevel
-        
+
         # we are in some other statement
         if loggingLevel is None:
             super().generic_visit(node)
             return
-        
+
         # we are entering a new logging statement
         self.__currentLoggingCall = node
-        
+
         if loggingLevel == "warn":
             self.violations.append((node, "M655"))
-        
+
         for index, child in enumerate(ast.iter_child_nodes(node)):
             if index == 1:
                 self.__currentLoggingArgument = child
-            if (
-                index > 1 and
-                isinstance(child, ast.keyword) and
-                child.arg == "extra"
-            ):
+            if index > 1 and isinstance(child, ast.keyword) and child.arg == "extra":
                 self.__currentExtraKeyword = child
-            
+
             super().visit(child)
-            
+
             self.__currentLoggingArgument = None
             self.__currentExtraKeyword = None
-        
+
         self.__currentLoggingCall = None
         self.__currentLoggingLevel = None
-    
+
     def visit_BinOp(self, node):
         """
         Public method to handle binary operations while processing the first
         logging argument.
-        
+
         @param node reference to the node to be processed
         @type ast.BinOp
         """
@@ -1327,27 +1464,27 @@
             # handle percent format
             if isinstance(node.op, ast.Mod):
                 self.violations.append((node, "M652"))
-            
+
             # handle string concat
             if isinstance(node.op, ast.Add):
                 self.violations.append((node, "M653"))
-        
+
         super().generic_visit(node)
-    
+
     def visit_JoinedStr(self, node):
         """
         Public method to handle f-string arguments.
-        
+
         @param node reference to the node to be processed
         @type ast.JoinedStr
         """
         if (
-            self.__withinLoggingStatement() and
-            any(isinstance(i, ast.FormattedValue) for i in node.values) and
-            self.__withinLoggingArgument()
+            self.__withinLoggingStatement()
+            and any(isinstance(i, ast.FormattedValue) for i in node.values)
+            and self.__withinLoggingArgument()
         ):
             self.violations.append((node, "M654"))
-            
+
             super().generic_visit(node)
 
 
@@ -1355,42 +1492,43 @@
     """
     Class implementing a node visitor to check for various topics.
     """
+
     #
     # This class was implemented along the BugBear flake8 extension (v 19.3.0).
     # Original: Copyright (c) 2016 Łukasz Langa
     #
-    
+
     NodeWindowSize = 4
-    
+
     def __init__(self):
         """
         Constructor
         """
         super().__init__()
-        
+
         self.__nodeStack = []
         self.__nodeWindow = []
         self.violations = []
-    
+
     def visit(self, node):
         """
         Public method to traverse a given AST node.
-        
+
         @param node AST node to be traversed
         @type ast.Node
         """
         self.__nodeStack.append(node)
         self.__nodeWindow.append(node)
-        self.__nodeWindow = self.__nodeWindow[-BugBearVisitor.NodeWindowSize:]
-        
+        self.__nodeWindow = self.__nodeWindow[-BugBearVisitor.NodeWindowSize :]
+
         super().visit(node)
-        
+
         self.__nodeStack.pop()
-    
+
     def visit_UAdd(self, node):
         """
         Public method to handle unary additions.
-        
+
         @param node reference to the node to be processed
         @type ast.UAdd
         """
@@ -1398,13 +1536,13 @@
         if trailingNodes == [ast.UnaryOp, ast.UAdd, ast.UnaryOp, ast.UAdd]:
             originator = self.__nodeWindow[-4]
             self.violations.append((originator, "M501"))
-        
+
         self.generic_visit(node)
-    
+
     def visit_Call(self, node):
         """
         Public method to handle a function call.
-        
+
         @param node reference to the node to be processed
         @type ast.Call
         """
@@ -1414,7 +1552,7 @@
             "M522": ("viewkeys", "viewvalues", "viewitems", "viewlists"),
             "M523": ("next",),
         }
-        
+
         if isinstance(node.func, ast.Attribute):
             for code, methods in methodsDict.items():
                 if node.func.attr in methods:
@@ -1430,165 +1568,161 @@
                 if isinstance(node.func, ast.Name) and node.func.id == "super":
                     args = node.args
                     if (
-                        len(args) == 2 and
-                        isinstance(args[0], ast.Attribute) and
-                        isinstance(args[0].value, ast.Name) and
-                        args[0].value.id == 'self' and
-                        args[0].attr == '__class__'
+                        len(args) == 2
+                        and isinstance(args[0], ast.Attribute)
+                        and isinstance(args[0].value, ast.Name)
+                        and args[0].value.id == "self"
+                        and args[0].attr == "__class__"
                     ):
                         self.violations.append((node, "M509"))
-                
+
                 # bad getattr and setattr
                 if (
-                    node.func.id in ("getattr", "hasattr") and
-                    node.args[1].s == "__call__"
+                    node.func.id in ("getattr", "hasattr")
+                    and node.args[1].s == "__call__"
                 ):
                     self.violations.append((node, "M511"))
                 if (
-                    node.func.id == "getattr" and
-                    len(node.args) == 2 and
-                    AstUtilities.isString(node.args[1])
+                    node.func.id == "getattr"
+                    and len(node.args) == 2
+                    and AstUtilities.isString(node.args[1])
                 ):
                     self.violations.append((node, "M512"))
                 elif (
-                    node.func.id == "setattr" and
-                    len(node.args) == 3 and
-                    AstUtilities.isString(node.args[1])
+                    node.func.id == "setattr"
+                    and len(node.args) == 3
+                    and AstUtilities.isString(node.args[1])
                 ):
                     self.violations.append((node, "M513"))
 
             self.generic_visit(node)
-    
+
     def visit_Attribute(self, node):
         """
         Public method to handle attributes.
-        
+
         @param node reference to the node to be processed
         @type ast.Attribute
         """
         callPath = list(composeCallPath(node))
-        
-        if '.'.join(callPath) == 'sys.maxint':
+
+        if ".".join(callPath) == "sys.maxint":
             self.violations.append((node, "M504"))
-        
-        elif (
-            len(callPath) == 2 and
-            callPath[1] == 'message'
-        ):
+
+        elif len(callPath) == 2 and callPath[1] == "message":
             name = callPath[0]
             for elem in reversed(self.__nodeStack[:-1]):
                 if isinstance(elem, ast.ExceptHandler) and elem.name == name:
                     self.violations.append((node, "M505"))
                     break
-    
+
     def visit_Assign(self, node):
         """
         Public method to handle assignments.
-        
+
         @param node reference to the node to be processed
         @type ast.Assign
         """
         if isinstance(self.__nodeStack[-2], ast.ClassDef):
             # By using 'hasattr' below we're ignoring starred arguments, slices
             # and tuples for simplicity.
-            assignTargets = {t.id for t in node.targets if hasattr(t, 'id')}
-            if '__metaclass__' in assignTargets:
+            assignTargets = {t.id for t in node.targets if hasattr(t, "id")}
+            if "__metaclass__" in assignTargets:
                 self.violations.append((node, "M524"))
-        
+
         elif len(node.targets) == 1:
             target = node.targets[0]
             if (
-                isinstance(target, ast.Attribute) and
-                isinstance(target.value, ast.Name) and
-                (target.value.id, target.attr) == ('os', 'environ')
+                isinstance(target, ast.Attribute)
+                and isinstance(target.value, ast.Name)
+                and (target.value.id, target.attr) == ("os", "environ")
             ):
                 self.violations.append((node, "M506"))
-        
+
         self.generic_visit(node)
-    
+
     def visit_For(self, node):
         """
         Public method to handle 'for' statements.
-        
+
         @param node reference to the node to be processed
         @type ast.For
         """
         self.__checkForM507(node)
-        
+
         self.generic_visit(node)
-    
+
     def visit_AsyncFor(self, node):
         """
         Public method to handle 'for' statements.
-        
+
         @param node reference to the node to be processed
         @type ast.AsyncFor
         """
         self.__checkForM507(node)
-        
+
         self.generic_visit(node)
-    
+
     def visit_Assert(self, node):
         """
         Public method to handle 'assert' statements.
-        
+
         @param node reference to the node to be processed
         @type ast.Assert
         """
         if (
-            AstUtilities.isNameConstant(node.test) and
-            AstUtilities.getValue(node.test) is False
+            AstUtilities.isNameConstant(node.test)
+            and AstUtilities.getValue(node.test) is False
         ):
             self.violations.append((node, "M503"))
-        
+
         self.generic_visit(node)
-    
+
     def visit_JoinedStr(self, node):
         """
         Public method to handle f-string arguments.
-        
+
         @param node reference to the node to be processed
         @type ast.JoinedStr
         """
         for value in node.values:
             if isinstance(value, ast.FormattedValue):
                 return
-        
+
         self.violations.append((node, "M508"))
-    
+
     def __checkForM502(self, node):
         """
         Private method to check the use of *strip().
-        
+
         @param node reference to the node to be processed
         @type ast.Call
         """
         if node.func.attr not in ("lstrip", "rstrip", "strip"):
-            return          # method name doesn't match
-        
+            return  # method name doesn't match
+
         if len(node.args) != 1 or not AstUtilities.isString(node.args[0]):
-            return          # used arguments don't match the builtin strip
-        
+            return  # used arguments don't match the builtin strip
+
         s = AstUtilities.getValue(node.args[0])
         if len(s) == 1:
-            return          # stripping just one character
-        
+            return  # stripping just one character
+
         if len(s) == len(set(s)):
-            return          # no characters appear more than once
+            return  # no characters appear more than once
 
         self.violations.append((node, "M502"))
-    
+
     def __checkForM507(self, node):
         """
         Private method to check for unused loop variables.
-        
+
         @param node reference to the node to be processed
         @type ast.For
         """
         targets = NameFinder()
         targets.visit(node.target)
-        ctrlNames = set(filter(lambda s: not s.startswith('_'),
-                               targets.getNames()))
+        ctrlNames = set(filter(lambda s: not s.startswith("_"), targets.getNames()))
         body = NameFinder()
         for expr in node.body:
             body.visit(expr)
@@ -1602,18 +1736,19 @@
     """
     Class to extract a name out of a tree of nodes.
     """
+
     def __init__(self):
         """
         Constructor
         """
         super().__init__()
-        
+
         self.__names = {}
 
     def visit_Name(self, node):
         """
         Public method to handle 'Name' nodes.
-        
+
         @param node reference to the node to be processed
         @type ast.Name
         """
@@ -1622,7 +1757,7 @@
     def visit(self, node):
         """
         Public method to traverse a given AST node.
-        
+
         @param node AST node to be traversed
         @type ast.Node
         """
@@ -1631,11 +1766,11 @@
                 super().visit(elem)
         else:
             super().visit(node)
-    
+
     def getNames(self):
         """
         Public method to return the extracted names and Name nodes.
-        
+
         @return dictionary containing the names as keys and the list of nodes
         @rtype dict
         """
@@ -1646,140 +1781,143 @@
     """
     Class implementing a node visitor to check return statements.
     """
-    Assigns = 'assigns'
-    Refs = 'refs'
-    Returns = 'returns'
-    
+
+    Assigns = "assigns"
+    Refs = "refs"
+    Returns = "returns"
+
     def __init__(self):
         """
         Constructor
         """
         super().__init__()
-        
+
         self.__stack = []
         self.violations = []
         self.__loopCount = 0
-    
+
     @property
     def assigns(self):
         """
         Public method to get the Assign nodes.
-        
+
         @return dictionary containing the node name as key and line number
             as value
         @rtype dict
         """
         return self.__stack[-1][ReturnVisitor.Assigns]
-    
+
     @property
     def refs(self):
         """
         Public method to get the References nodes.
-        
+
         @return dictionary containing the node name as key and line number
             as value
         @rtype dict
         """
         return self.__stack[-1][ReturnVisitor.Refs]
-    
+
     @property
     def returns(self):
         """
         Public method to get the Return nodes.
-        
+
         @return dictionary containing the node name as key and line number
             as value
         @rtype dict
         """
         return self.__stack[-1][ReturnVisitor.Returns]
-    
+
     def visit_For(self, node):
         """
         Public method to handle a for loop.
-        
+
         @param node reference to the for node to handle
         @type ast.For
         """
         self.__visitLoop(node)
-    
+
     def visit_AsyncFor(self, node):
         """
         Public method to handle an async for loop.
-        
+
         @param node reference to the async for node to handle
         @type ast.AsyncFor
         """
         self.__visitLoop(node)
-    
+
     def visit_While(self, node):
         """
         Public method to handle a while loop.
-        
+
         @param node reference to the while node to handle
         @type ast.While
         """
         self.__visitLoop(node)
-    
+
     def __visitLoop(self, node):
         """
         Private method to handle loop nodes.
-        
+
         @param node reference to the loop node to handle
         @type ast.For, ast.AsyncFor or ast.While
         """
         self.__loopCount += 1
         self.generic_visit(node)
         self.__loopCount -= 1
-    
+
     def __visitWithStack(self, node):
         """
         Private method to traverse a given function node using a stack.
-        
+
         @param node AST node to be traversed
         @type ast.FunctionDef or ast.AsyncFunctionDef
         """
-        self.__stack.append({
-            ReturnVisitor.Assigns: defaultdict(list),
-            ReturnVisitor.Refs: defaultdict(list),
-            ReturnVisitor.Returns: []
-        })
-        
+        self.__stack.append(
+            {
+                ReturnVisitor.Assigns: defaultdict(list),
+                ReturnVisitor.Refs: defaultdict(list),
+                ReturnVisitor.Returns: [],
+            }
+        )
+
         self.generic_visit(node)
         self.__checkFunction(node)
         self.__stack.pop()
-    
+
     def visit_FunctionDef(self, node):
         """
         Public method to handle a function definition.
-        
+
         @param node reference to the node to handle
         @type ast.FunctionDef
         """
         self.__visitWithStack(node)
-    
+
     def visit_AsyncFunctionDef(self, node):
         """
         Public method to handle a function definition.
-        
+
         @param node reference to the node to handle
         @type ast.AsyncFunctionDef
         """
         self.__visitWithStack(node)
-    
+
     def visit_Return(self, node):
         """
         Public method to handle a return node.
-        
+
         @param node reference to the node to handle
         @type ast.Return
         """
         self.returns.append(node)
         self.generic_visit(node)
-    
+
     def visit_Assign(self, node):
         """
         Public method to handle an assign node.
-        
+
         @param node reference to the node to handle
         @type ast.Assign
         """
@@ -1787,31 +1925,28 @@
             return
 
         self.generic_visit(node.value)
-        
+
         target = node.targets[0]
-        if (
-            isinstance(target, ast.Tuple) and
-            not isinstance(node.value, ast.Tuple)
-        ):
+        if isinstance(target, ast.Tuple) and not isinstance(node.value, ast.Tuple):
             # skip unpacking assign
             return
-        
+
         self.__visitAssignTarget(target)
-    
+
     def visit_Name(self, node):
         """
         Public method to handle a name node.
-        
+
         @param node reference to the node to handle
         @type ast.Name
         """
         if self.__stack:
             self.refs[node.id].append(node.lineno)
-    
+
     def __visitAssignTarget(self, node):
         """
         Private method to handle an assign target node.
-        
+
         @param node reference to the node to handle
         @type ast.AST
         """
@@ -1819,70 +1954,66 @@
             for elt in node.elts:
                 self.__visitAssignTarget(elt)
             return
-        
+
         if not self.__loopCount and isinstance(node, ast.Name):
             self.assigns[node.id].append(node.lineno)
             return
-        
+
         self.generic_visit(node)
-    
+
     def __checkFunction(self, node):
         """
         Private method to check a function definition node.
-        
+
         @param node reference to the node to check
         @type ast.AsyncFunctionDef or ast.FunctionDef
         """
         if not self.returns or not node.body:
             return
-        
+
         if len(node.body) == 1 and isinstance(node.body[-1], ast.Return):
             # skip functions that consist of `return None` only
             return
-        
+
         if not self.__resultExists():
             self.__checkUnnecessaryReturnNone()
             return
-        
+
         self.__checkImplicitReturnValue()
         self.__checkImplicitReturn(node.body[-1])
-        
+
         for n in self.returns:
             if n.value:
                 self.__checkUnnecessaryAssign(n.value)
-    
+
     def __isNone(self, node):
         """
         Private method to check, if a node value is None.
-        
+
         @param node reference to the node to check
         @type ast.AST
         @return flag indicating the node contains a None value
         @rtype bool
         """
-        return (
-            AstUtilities.isNameConstant(node) and
-            AstUtilities.getValue(node) is None
-        )
-    
+        return AstUtilities.isNameConstant(node) and AstUtilities.getValue(node) is None
+
     def __isFalse(self, node):
         """
         Private method to check, if a node value is False.
-        
+
         @param node reference to the node to check
         @type ast.AST
         @return flag indicating the node contains a False value
         @rtype bool
         """
         return (
-            AstUtilities.isNameConstant(node) and
-            AstUtilities.getValue(node) is False
+            AstUtilities.isNameConstant(node) and AstUtilities.getValue(node) is False
         )
-    
+
     def __resultExists(self):
         """
         Private method to check the existance of a return result.
-        
+
         @return flag indicating the existence of a return result
         @rtype bool
         """
@@ -1890,9 +2021,9 @@
             value = node.value
             if value and not self.__isNone(value):
                 return True
-        
+
         return False
-    
+
     def __checkImplicitReturnValue(self):
         """
         Private method to check for implicit return values.
@@ -1900,7 +2031,7 @@
         for node in self.returns:
             if not node.value:
                 self.violations.append((node, "M832"))
-    
+
     def __checkUnnecessaryReturnNone(self):
         """
         Private method to check for an unnecessary 'return None' statement.
@@ -1908,11 +2039,11 @@
         for node in self.returns:
             if self.__isNone(node.value):
                 self.violations.append((node, "M831"))
-    
+
     def __checkImplicitReturn(self, node):
         """
         Private method to check for an implicit return statement.
-        
+
         @param node reference to the node to check
         @type ast.AST
         """
@@ -1920,59 +2051,59 @@
             if not node.body or not node.orelse:
                 self.violations.append((node, "M833"))
                 return
-            
+
             self.__checkImplicitReturn(node.body[-1])
             self.__checkImplicitReturn(node.orelse[-1])
             return
-        
+
         if isinstance(node, (ast.For, ast.AsyncFor)) and node.orelse:
             self.__checkImplicitReturn(node.orelse[-1])
             return
-        
+
         if isinstance(node, (ast.With, ast.AsyncWith)):
             self.__checkImplicitReturn(node.body[-1])
             return
-        
+
         if isinstance(node, ast.Assert) and self.__isFalse(node.test):
             return
-        
+
         try:
             okNodes = (ast.Return, ast.Raise, ast.While, ast.Try)
         except AttributeError:
             okNodes = (ast.Return, ast.Raise, ast.While)
         if not isinstance(node, okNodes):
             self.violations.append((node, "M833"))
-    
+
     def __checkUnnecessaryAssign(self, node):
         """
         Private method to check for an unnecessary assign statement.
-        
+
         @param node reference to the node to check
         @type ast.AST
         """
         if not isinstance(node, ast.Name):
             return
-        
+
         varname = node.id
         returnLineno = node.lineno
-        
+
         if varname not in self.assigns:
             return
-        
+
         if varname not in self.refs:
             self.violations.append((node, "M834"))
             return
-        
+
         if self.__hasRefsBeforeNextAssign(varname, returnLineno):
             return
-        
+
         self.violations.append((node, "M834"))
 
     def __hasRefsBeforeNextAssign(self, varname, returnLineno):
         """
         Private method to check for references before a following assign
         statement.
-        
+
         @param varname variable name to check for
         @type str
         @param returnLineno line number of the return statement
@@ -1982,47 +2113,48 @@
         """
         beforeAssign = 0
         afterAssign = None
-        
+
         for lineno in sorted(self.assigns[varname]):
             if lineno > returnLineno:
                 afterAssign = lineno
                 break
-            
+
             if lineno <= returnLineno:
                 beforeAssign = lineno
-        
+
         for lineno in self.refs[varname]:
             if lineno == returnLineno:
                 continue
-            
+
             if afterAssign:
                 if beforeAssign < lineno <= afterAssign:
                     return True
-            
+
             elif beforeAssign < lineno:
                 return True
-        
+
         return False
 
 
 class DateTimeVisitor(ast.NodeVisitor):
     """
     Class implementing a node visitor to check datetime function calls.
-    
+
     Note: This class is modelled after flake8_datetimez checker.
     """
+
     def __init__(self):
         """
         Constructor
         """
         super().__init__()
-        
+
         self.violations = []
-    
+
     def __getFromKeywords(self, keywords, name):
         """
         Private method to get a keyword node given its name.
-        
+
         @param keywords list of keyword argument nodes
         @type list of ast.AST
         @param name name of the keyword node
@@ -2033,195 +2165,176 @@
         for keyword in keywords:
             if keyword.arg == name:
                 return keyword
-        
+
         return None
-    
+
     def visit_Call(self, node):
         """
         Public method to handle a function call.
 
         Every datetime related function call is check for use of the naive
         variant (i.e. use without TZ info).
-        
+
         @param node reference to the node to be processed
         @type ast.Call
         """
         # datetime.something()
         isDateTimeClass = (
-            isinstance(node.func, ast.Attribute) and
-            isinstance(node.func.value, ast.Name) and
-            node.func.value.id == 'datetime')
-        
+            isinstance(node.func, ast.Attribute)
+            and isinstance(node.func.value, ast.Name)
+            and node.func.value.id == "datetime"
+        )
+
         # datetime.datetime.something()
         isDateTimeModuleAndClass = (
-            isinstance(node.func, ast.Attribute) and
-            isinstance(node.func.value, ast.Attribute) and
-            node.func.value.attr == 'datetime' and
-            isinstance(node.func.value.value, ast.Name) and
-            node.func.value.value.id == 'datetime')
-        
+            isinstance(node.func, ast.Attribute)
+            and isinstance(node.func.value, ast.Attribute)
+            and node.func.value.attr == "datetime"
+            and isinstance(node.func.value.value, ast.Name)
+            and node.func.value.value.id == "datetime"
+        )
+
         if isDateTimeClass:
-            if node.func.attr == 'datetime':
+            if node.func.attr == "datetime":
                 # datetime.datetime(2000, 1, 1, 0, 0, 0, 0,
                 #                   datetime.timezone.utc)
-                isCase1 = (
-                    len(node.args) >= 8 and
-                    not (
-                        AstUtilities.isNameConstant(node.args[7]) and
-                        AstUtilities.getValue(node.args[7]) is None
-                    )
+                isCase1 = len(node.args) >= 8 and not (
+                    AstUtilities.isNameConstant(node.args[7])
+                    and AstUtilities.getValue(node.args[7]) is None
                 )
-                
+
                 # datetime.datetime(2000, 1, 1, tzinfo=datetime.timezone.utc)
-                tzinfoKeyword = self.__getFromKeywords(node.keywords, 'tzinfo')
-                isCase2 = (
-                    tzinfoKeyword is not None and
-                    not (
-                        AstUtilities.isNameConstant(tzinfoKeyword.value) and
-                        AstUtilities.getValue(tzinfoKeyword.value) is None
-                    )
+                tzinfoKeyword = self.__getFromKeywords(node.keywords, "tzinfo")
+                isCase2 = tzinfoKeyword is not None and not (
+                    AstUtilities.isNameConstant(tzinfoKeyword.value)
+                    and AstUtilities.getValue(tzinfoKeyword.value) is None
                 )
-                
+
                 if not (isCase1 or isCase2):
                     self.violations.append((node, "M301"))
-            
-            elif node.func.attr == 'time':
+
+            elif node.func.attr == "time":
                 # time(12, 10, 45, 0, datetime.timezone.utc)
-                isCase1 = (
-                    len(node.args) >= 5 and
-                    not (
-                        AstUtilities.isNameConstant(node.args[4]) and
-                        AstUtilities.getValue(node.args[4]) is None
-                    )
+                isCase1 = len(node.args) >= 5 and not (
+                    AstUtilities.isNameConstant(node.args[4])
+                    and AstUtilities.getValue(node.args[4]) is None
                 )
-                
+
                 # datetime.time(12, 10, 45, tzinfo=datetime.timezone.utc)
-                tzinfoKeyword = self.__getFromKeywords(node.keywords, 'tzinfo')
-                isCase2 = (
-                    tzinfoKeyword is not None and
-                    not (
-                        AstUtilities.isNameConstant(tzinfoKeyword.value) and
-                        AstUtilities.getValue(tzinfoKeyword.value) is None
-                    )
+                tzinfoKeyword = self.__getFromKeywords(node.keywords, "tzinfo")
+                isCase2 = tzinfoKeyword is not None and not (
+                    AstUtilities.isNameConstant(tzinfoKeyword.value)
+                    and AstUtilities.getValue(tzinfoKeyword.value) is None
                 )
-                
+
                 if not (isCase1 or isCase2):
                     self.violations.append((node, "M321"))
-            
-            elif node.func.attr == 'date':
+
+            elif node.func.attr == "date":
                 self.violations.append((node, "M311"))
-        
+
         if isDateTimeClass or isDateTimeModuleAndClass:
-            if node.func.attr == 'today':
+            if node.func.attr == "today":
                 self.violations.append((node, "M302"))
-            
-            elif node.func.attr == 'utcnow':
+
+            elif node.func.attr == "utcnow":
                 self.violations.append((node, "M303"))
-            
-            elif node.func.attr == 'utcfromtimestamp':
+
+            elif node.func.attr == "utcfromtimestamp":
                 self.violations.append((node, "M304"))
-            
-            elif node.func.attr in 'now':
+
+            elif node.func.attr in "now":
                 # datetime.now(UTC)
                 isCase1 = (
-                    len(node.args) == 1 and
-                    len(node.keywords) == 0 and
-                    not (
-                        AstUtilities.isNameConstant(node.args[0]) and
-                        AstUtilities.getValue(node.args[0]) is None
+                    len(node.args) == 1
+                    and len(node.keywords) == 0
+                    and not (
+                        AstUtilities.isNameConstant(node.args[0])
+                        and AstUtilities.getValue(node.args[0]) is None
                     )
                 )
-                
+
                 # datetime.now(tz=UTC)
-                tzKeyword = self.__getFromKeywords(node.keywords, 'tz')
-                isCase2 = (
-                    tzKeyword is not None and
-                    not (
-                        AstUtilities.isNameConstant(tzKeyword.value) and
-                        AstUtilities.getValue(tzKeyword.value) is None
-                    )
+                tzKeyword = self.__getFromKeywords(node.keywords, "tz")
+                isCase2 = tzKeyword is not None and not (
+                    AstUtilities.isNameConstant(tzKeyword.value)
+                    and AstUtilities.getValue(tzKeyword.value) is None
                 )
-                
+
                 if not (isCase1 or isCase2):
                     self.violations.append((node, "M305"))
-            
-            elif node.func.attr == 'fromtimestamp':
+
+            elif node.func.attr == "fromtimestamp":
                 # datetime.fromtimestamp(1234, UTC)
                 isCase1 = (
-                    len(node.args) == 2 and
-                    len(node.keywords) == 0 and
-                    not (
-                        AstUtilities.isNameConstant(node.args[1]) and
-                        AstUtilities.getValue(node.args[1]) is None
+                    len(node.args) == 2
+                    and len(node.keywords) == 0
+                    and not (
+                        AstUtilities.isNameConstant(node.args[1])
+                        and AstUtilities.getValue(node.args[1]) is None
                     )
                 )
-                
+
                 # datetime.fromtimestamp(1234, tz=UTC)
-                tzKeyword = self.__getFromKeywords(node.keywords, 'tz')
-                isCase2 = (
-                    tzKeyword is not None and
-                    not (
-                        AstUtilities.isNameConstant(tzKeyword.value) and
-                        AstUtilities.getValue(tzKeyword.value) is None
-                    )
+                tzKeyword = self.__getFromKeywords(node.keywords, "tz")
+                isCase2 = tzKeyword is not None and not (
+                    AstUtilities.isNameConstant(tzKeyword.value)
+                    and AstUtilities.getValue(tzKeyword.value) is None
                 )
-                
+
                 if not (isCase1 or isCase2):
                     self.violations.append((node, "M306"))
-            
-            elif node.func.attr == 'strptime':
+
+            elif node.func.attr == "strptime":
                 # datetime.strptime(...).replace(tzinfo=UTC)
-                parent = getattr(node, '_dtCheckerParent', None)
-                pparent = getattr(parent, '_dtCheckerParent', None)
-                if (
-                    not (isinstance(parent, ast.Attribute) and
-                         parent.attr == 'replace') or
-                    not isinstance(pparent, ast.Call)
-                ):
+                parent = getattr(node, "_dtCheckerParent", None)
+                pparent = getattr(parent, "_dtCheckerParent", None)
+                if not (
+                    isinstance(parent, ast.Attribute) and parent.attr == "replace"
+                ) or not isinstance(pparent, ast.Call):
                     isCase1 = False
                 else:
-                    tzinfoKeyword = self.__getFromKeywords(pparent.keywords,
-                                                           'tzinfo')
-                    isCase1 = (
-                        tzinfoKeyword is not None and
-                        not (
-                            AstUtilities.isNameConstant(
-                                tzinfoKeyword.value) and
-                            AstUtilities.getValue(tzinfoKeyword.value) is None
-                        )
+                    tzinfoKeyword = self.__getFromKeywords(pparent.keywords, "tzinfo")
+                    isCase1 = tzinfoKeyword is not None and not (
+                        AstUtilities.isNameConstant(tzinfoKeyword.value)
+                        and AstUtilities.getValue(tzinfoKeyword.value) is None
                     )
-                
+
                 if not isCase1:
                     self.violations.append((node, "M307"))
-            
-            elif node.func.attr == 'fromordinal':
+
+            elif node.func.attr == "fromordinal":
                 self.violations.append((node, "M308"))
-        
+
         # date.something()
-        isDateClass = (isinstance(node.func, ast.Attribute) and
-                       isinstance(node.func.value, ast.Name) and
-                       node.func.value.id == 'date')
-        
+        isDateClass = (
+            isinstance(node.func, ast.Attribute)
+            and isinstance(node.func.value, ast.Name)
+            and node.func.value.id == "date"
+        )
+
         # datetime.date.something()
-        isDateModuleAndClass = (isinstance(node.func, ast.Attribute) and
-                                isinstance(node.func.value, ast.Attribute) and
-                                node.func.value.attr == 'date' and
-                                isinstance(node.func.value.value, ast.Name) and
-                                node.func.value.value.id == 'datetime')
-        
+        isDateModuleAndClass = (
+            isinstance(node.func, ast.Attribute)
+            and isinstance(node.func.value, ast.Attribute)
+            and node.func.value.attr == "date"
+            and isinstance(node.func.value.value, ast.Name)
+            and node.func.value.value.id == "datetime"
+        )
+
         if isDateClass or isDateModuleAndClass:
-            if node.func.attr == 'today':
+            if node.func.attr == "today":
                 self.violations.append((node, "M312"))
-            
-            elif node.func.attr == 'fromtimestamp':
+
+            elif node.func.attr == "fromtimestamp":
                 self.violations.append((node, "M313"))
-            
-            elif node.func.attr == 'fromordinal':
+
+            elif node.func.attr == "fromordinal":
                 self.violations.append((node, "M314"))
-            
-            elif node.func.attr == 'fromisoformat':
+
+            elif node.func.attr == "fromisoformat":
                 self.violations.append((node, "M315"))
-        
+
         self.generic_visit(node)
 
 
@@ -2229,35 +2342,36 @@
     """
     Class implementing a node visitor to check the use of sys.version and
     sys.version_info.
-    
+
     Note: This class is modelled after flake8-2020 checker.
     """
+
     def __init__(self):
         """
         Constructor
         """
         super().__init__()
-        
+
         self.violations = []
         self.__fromImports = {}
-    
+
     def visit_ImportFrom(self, node):
         """
         Public method to handle a from ... import ... statement.
-        
+
         @param node reference to the node to be processed
         @type ast.ImportFrom
         """
         for alias in node.names:
             if node.module is not None and not alias.asname:
                 self.__fromImports[alias.name] = node.module
-        
+
         self.generic_visit(node)
-    
+
     def __isSys(self, attr, node):
         """
         Private method to check for a reference to sys attribute.
-        
+
         @param attr attribute name
         @type str
         @param node reference to the node to be checked
@@ -2267,22 +2381,23 @@
         """
         match = False
         if (
-            (isinstance(node, ast.Attribute) and
-             isinstance(node.value, ast.Name) and
-             node.value.id == "sys" and
-             node.attr == attr) or
-            (isinstance(node, ast.Name) and
-             node.id == attr and
-             self.__fromImports.get(node.id) == "sys")
+            isinstance(node, ast.Attribute)
+            and isinstance(node.value, ast.Name)
+            and node.value.id == "sys"
+            and node.attr == attr
+        ) or (
+            isinstance(node, ast.Name)
+            and node.id == attr
+            and self.__fromImports.get(node.id) == "sys"
         ):
             match = True
-        
+
         return match
-    
+
     def __isSysVersionUpperSlice(self, node, n):
         """
         Private method to check the upper slice of sys.version.
-        
+
         @param node reference to the node to be checked
         @type ast.Node
         @param n slice value to check against
@@ -2291,18 +2406,18 @@
         @rtype bool
         """
         return (
-            self.__isSys("version", node.value) and
-            isinstance(node.slice, ast.Slice) and
-            node.slice.lower is None and
-            AstUtilities.isNumber(node.slice.upper) and
-            AstUtilities.getValue(node.slice.upper) == n and
-            node.slice.step is None
+            self.__isSys("version", node.value)
+            and isinstance(node.slice, ast.Slice)
+            and node.slice.lower is None
+            and AstUtilities.isNumber(node.slice.upper)
+            and AstUtilities.getValue(node.slice.upper) == n
+            and node.slice.step is None
         )
-    
+
     def visit_Subscript(self, node):
         """
         Public method to handle a subscript.
-        
+
         @param node reference to the node to be processed
         @type ast.Subscript
         """
@@ -2311,46 +2426,46 @@
         elif self.__isSysVersionUpperSlice(node, 3):
             self.violations.append((node.value, "M401"))
         elif (
-            self.__isSys('version', node.value) and
-            isinstance(node.slice, ast.Index) and
-            AstUtilities.isNumber(node.slice.value) and
-            AstUtilities.getValue(node.slice.value) == 2
+            self.__isSys("version", node.value)
+            and isinstance(node.slice, ast.Index)
+            and AstUtilities.isNumber(node.slice.value)
+            and AstUtilities.getValue(node.slice.value) == 2
         ):
             self.violations.append((node.value, "M402"))
         elif (
-            self.__isSys('version', node.value) and
-            isinstance(node.slice, ast.Index) and
-            AstUtilities.isNumber(node.slice.value) and
-            AstUtilities.getValue(node.slice.value) == 0
+            self.__isSys("version", node.value)
+            and isinstance(node.slice, ast.Index)
+            and AstUtilities.isNumber(node.slice.value)
+            and AstUtilities.getValue(node.slice.value) == 0
         ):
             self.violations.append((node.value, "M421"))
 
         self.generic_visit(node)
-    
+
     def visit_Compare(self, node):
         """
         Public method to handle a comparison.
-        
+
         @param node reference to the node to be processed
         @type ast.Compare
         """
         if (
-            isinstance(node.left, ast.Subscript) and
-            self.__isSys('version_info', node.left.value) and
-            isinstance(node.left.slice, ast.Index) and
-            AstUtilities.isNumber(node.left.slice.value) and
-            AstUtilities.getValue(node.left.slice.value) == 0 and
-            len(node.ops) == 1 and
-            isinstance(node.ops[0], ast.Eq) and
-            AstUtilities.isNumber(node.comparators[0]) and
-            AstUtilities.getValue(node.comparators[0]) == 3
+            isinstance(node.left, ast.Subscript)
+            and self.__isSys("version_info", node.left.value)
+            and isinstance(node.left.slice, ast.Index)
+            and AstUtilities.isNumber(node.left.slice.value)
+            and AstUtilities.getValue(node.left.slice.value) == 0
+            and len(node.ops) == 1
+            and isinstance(node.ops[0], ast.Eq)
+            and AstUtilities.isNumber(node.comparators[0])
+            and AstUtilities.getValue(node.comparators[0]) == 3
         ):
             self.violations.append((node.left, "M411"))
         elif (
-            self.__isSys('version', node.left) and
-            len(node.ops) == 1 and
-            isinstance(node.ops[0], (ast.Lt, ast.LtE, ast.Gt, ast.GtE)) and
-            AstUtilities.isString(node.comparators[0])
+            self.__isSys("version", node.left)
+            and len(node.ops) == 1
+            and isinstance(node.ops[0], (ast.Lt, ast.LtE, ast.Gt, ast.GtE))
+            and AstUtilities.isString(node.comparators[0])
         ):
             if len(AstUtilities.getValue(node.comparators[0])) == 1:
                 errorCode = "M422"
@@ -2358,55 +2473,56 @@
                 errorCode = "M403"
             self.violations.append((node.left, errorCode))
         elif (
-            isinstance(node.left, ast.Subscript) and
-            self.__isSys('version_info', node.left.value) and
-            isinstance(node.left.slice, ast.Index) and
-            AstUtilities.isNumber(node.left.slice.value) and
-            AstUtilities.getValue(node.left.slice.value) == 1 and
-            len(node.ops) == 1 and
-            isinstance(node.ops[0], (ast.Lt, ast.LtE, ast.Gt, ast.GtE)) and
-            AstUtilities.isNumber(node.comparators[0])
+            isinstance(node.left, ast.Subscript)
+            and self.__isSys("version_info", node.left.value)
+            and isinstance(node.left.slice, ast.Index)
+            and AstUtilities.isNumber(node.left.slice.value)
+            and AstUtilities.getValue(node.left.slice.value) == 1
+            and len(node.ops) == 1
+            and isinstance(node.ops[0], (ast.Lt, ast.LtE, ast.Gt, ast.GtE))
+            and AstUtilities.isNumber(node.comparators[0])
         ):
             self.violations.append((node, "M413"))
         elif (
-            isinstance(node.left, ast.Attribute) and
-            self.__isSys('version_info', node.left.value) and
-            node.left.attr == 'minor' and
-            len(node.ops) == 1 and
-            isinstance(node.ops[0], (ast.Lt, ast.LtE, ast.Gt, ast.GtE)) and
-            AstUtilities.isNumber(node.comparators[0])
+            isinstance(node.left, ast.Attribute)
+            and self.__isSys("version_info", node.left.value)
+            and node.left.attr == "minor"
+            and len(node.ops) == 1
+            and isinstance(node.ops[0], (ast.Lt, ast.LtE, ast.Gt, ast.GtE))
+            and AstUtilities.isNumber(node.comparators[0])
         ):
             self.violations.append((node, "M414"))
-        
+
         self.generic_visit(node)
-    
+
     def visit_Attribute(self, node):
         """
         Public method to handle an attribute.
-        
+
         @param node reference to the node to be processed
         @type ast.Attribute
         """
         if (
-            isinstance(node.value, ast.Name) and
-            node.value.id == 'six' and
-            node.attr == 'PY3'
+            isinstance(node.value, ast.Name)
+            and node.value.id == "six"
+            and node.attr == "PY3"
         ):
             self.violations.append((node, "M412"))
-        
+
         self.generic_visit(node)
 
     def visit_Name(self, node):
         """
         Public method to handle an name.
-        
+
         @param node reference to the node to be processed
         @type ast.Name
         """
-        if node.id == 'PY3' and self.__fromImports.get(node.id) == 'six':
+        if node.id == "PY3" and self.__fromImports.get(node.id) == "six":
             self.violations.append((node, "M412"))
-        
+
         self.generic_visit(node)
 
+
 #
 # eflag: noqa = M891

eric ide

mercurial