Repository: randombit/botan
Pull request #3093 (2022-12-02 21:15:49)

Fix more Pylint warnings


Patch:
diff --git a/configure.py b/configure.py
index a540e3ea4..d04ad5e1f 100755
--- a/configure.py
+++ b/configure.py
@@ -277,14 +277,13 @@ class BuildPaths: # pylint: disable=too-many-instance-attributes
     def src_info(self, typ):
         if typ == 'lib':
             return (self.lib_sources, self.libobj_dir)
-        elif typ == 'cli':
+        if typ == 'cli':
             return (self.cli_sources, self.cliobj_dir)
-        elif typ == 'test':
+        if typ == 'test':
             return (self.test_sources, self.testobj_dir)
-        elif typ == 'fuzzer':
+        if typ == 'fuzzer':
             return (self.fuzzer_sources, self.fuzzobj_dir)
-        else:
-            raise InternalError("Unknown src info type '%s'" % (typ))
+        raise InternalError("Unknown src info type '%s'" % (typ))
 
 ACCEPTABLE_BUILD_TARGETS = ["static", "shared", "cli", "tests", "bogo_shim"]
 
@@ -705,7 +704,7 @@ class LexResult:
 
 class LexerError(InternalError):
     def __init__(self, msg, lexfile, line):
-        super(LexerError, self).__init__(msg)
+        super().__init__(msg)
         self.msg = msg
         self.lexfile = lexfile
         self.line = line
@@ -819,7 +818,7 @@ class ModuleInfo(InfoObject):
 
     def __init__(self, infofile):
         # pylint: disable=too-many-statements
-        super(ModuleInfo, self).__init__(infofile)
+        super().__init__(infofile)
         lex = lex_me_harder(
             infofile,
             ['header:internal', 'header:public', 'header:external', 'requires',
@@ -911,14 +910,15 @@ class ModuleInfo(InfoObject):
             logging.error("Module '%s' is virtual but contains %d source code files", self.basename, source_file_count)
 
     def _parse_module_info(self, lex):
-        try:
-            info = lex.module_info
-            self.name = info["name"]
-            self.brief = info["brief"] if "brief" in info else None
-            self.type = info["type"] if "type" in info else "Public"
-        except:
+        info = lex.module_info
+
+        if "name" not in info:
             raise InternalError("Module '%s' does not contain a <module_info> section with at least a documentation-friendly 'name' definition" % self.basename)
 
+        self.name = info["name"]
+        self.brief = info.get("brief") # possibly None
+        self.type = info.get("type") or "Public"
+
         if self.type not in ["Public", "Internal", "Virtual"]:
             raise InternalError("Module '%s' has an unknown type: %s" % (self.basename, self.type))
 
@@ -1128,7 +1128,7 @@ class ModuleInfo(InfoObject):
 
 class ModulePolicyInfo(InfoObject):
     def __init__(self, infofile):
-        super(ModulePolicyInfo, self).__init__(infofile)
+        super().__init__(infofile)
         lex = lex_me_harder(
             infofile,
             ['required', 'if_available', 'prohibited'],
@@ -1153,7 +1153,7 @@ class ModulePolicyInfo(InfoObject):
 
 class ArchInfo(InfoObject):
     def __init__(self, infofile):
-        super(ArchInfo, self).__init__(infofile)
+        super().__init__(infofile)
         lex = lex_me_harder(
             infofile,
             ['aliases', 'isa_extensions'],
@@ -1191,7 +1191,7 @@ class ArchInfo(InfoObject):
 
 class CompilerInfo(InfoObject): # pylint: disable=too-many-instance-attributes
     def __init__(self, infofile):
-        super(CompilerInfo, self).__init__(infofile)
+        super().__init__(infofile)
         lex = lex_me_harder(
             infofile,
             [],
@@ -1527,7 +1527,7 @@ class CompilerInfo(InfoObject): # pylint: disable=too-many-instance-attributes
 
 class OsInfo(InfoObject): # pylint: disable=too-many-instance-attributes
     def __init__(self, infofile):
-        super(OsInfo, self).__init__(infofile)
+        super().__init__(infofile)
         lex = lex_me_harder(
             infofile,
             ['aliases', 'target_features', 'feature_macros'],
@@ -1974,10 +1974,9 @@ def create_template_vars(source_paths, build_paths, options, modules, cc, arch,
             inno_arch = {'x86_32': '',
                          'x86_64': 'x64',
                          'ia64': 'ia64'}
-            if arch in inno_arch:
-                return inno_arch[arch]
-            else:
+            if arch not in inno_arch:
                 logging.warning('Unknown arch %s in innosetup_arch', arch)
+            return inno_arch.get(arch)
         return None
 
     def configure_command_line():
@@ -2632,26 +2631,17 @@ class AmalgamationHelper:
     @staticmethod
     def is_botan_include(cpp_source_line):
         match = AmalgamationHelper._botan_include.search(cpp_source_line)
-        if match:
-            return match.group(1)
-        else:
-            return None
+        return match.group(1) if match else None
 
     @staticmethod
     def is_unconditional_any_include(cpp_source_line):
         match = AmalgamationHelper._unconditional_any_include.search(cpp_source_line)
-        if match:
-            return match.group(1)
-        else:
-            return None
+        return match.group(1) if match else None
 
     @staticmethod
     def is_unconditional_std_include(cpp_source_line):
         match = AmalgamationHelper._unconditional_std_include.search(cpp_source_line)
-        if match:
-            return match.group(1)
-        else:
-            return None
+        return match.group(1) if match else None
 
     @staticmethod
     def write_banner(fd):
@@ -2846,7 +2836,7 @@ def have_program(program):
 class BotanConfigureLogHandler(logging.StreamHandler):
     def emit(self, record):
         # Do the default stuff first
-        super(BotanConfigureLogHandler, self).emit(record)
+        super().emit(record)
         # Exit script if and ERROR or worse occurred
         if record.levelno >= logging.ERROR:
             sys.exit(1)
@@ -2928,8 +2918,7 @@ def python_platform_identifier():
     system_from_python = platform.system().lower()
     if re.match('^cygwin_.*', system_from_python):
         return 'cygwin'
-    else:
-        return system_from_python
+    return system_from_python
 
 # This is for otions that have --with-XYZ and --without-XYZ. If user does not
 # set any of those, we choose a default here.
@@ -3312,7 +3301,7 @@ def do_io_for_build(cc, arch, osinfo, using_mods, info_modules, build_paths, sou
                 portable_symlink(header_file, directory, link_method)
             except OSError as ex:
                 if ex.errno != errno.EEXIST:
-                    raise UserError('Error linking %s into %s: %s' % (header_file, directory, ex))
+                    raise UserError('Error linking %s into %s: %s' % (header_file, directory, ex)) from ex
 
     link_headers(build_paths.public_headers, 'public',
                  build_paths.botan_include_dir)
@@ -3498,7 +3487,7 @@ def main(argv):
 
         if options.cpu.endswith('eb') or options.cpu.endswith('be'):
             return 'big'
-        elif options.cpu.endswith('el') or options.cpu.endswith('le'):
+        if options.cpu.endswith('el') or options.cpu.endswith('le'):
             return 'little'
 
         if arch_info.endian:
diff --git a/src/configs/pylint.rc b/src/configs/pylint.rc
index c4437c451..0c70ec407 100644
--- a/src/configs/pylint.rc
+++ b/src/configs/pylint.rc
@@ -31,8 +31,13 @@ confidence=
 # no Warning level messages displayed, use"--disable=all --enable=classes
 # --disable=W"
 
-disable=missing-docstring,no-else-return,locally-disabled,import-outside-toplevel,super-with-arguments,raise-missing-from,duplicate-code,consider-using-f-string,fixme,consider-using-with
-
+# * consider-using-f-string and consider-using-with could be fixed now
+#   that we support only Python3, but neither seems that important
+# * missing-docstring isn't considered important because these are scripts
+#   not libraries
+# * fixme is marking TODOs in the future
+# * no-else-return is often awkward
+disable=missing-docstring,fixme,duplicate-code,no-else-return,consider-using-f-string,consider-using-with
 
 [REPORTS]
 
diff --git a/src/editors/sublime/build.py b/src/editors/sublime/build.py
index 8b20eecdf..e0f3569af 100755
--- a/src/editors/sublime/build.py
+++ b/src/editors/sublime/build.py
@@ -32,8 +32,8 @@ def run_cmd(cmd):
 
     try:
         subprocess.run(cmd, shell=shell, check=True)
-    except subprocess.CalledProcessError:
-        raise BuildError('Command failed, aborting...')
+    except subprocess.CalledProcessError as ex:
+        raise BuildError('Command failed, aborting...') from ex
 
 
 def _find_regex_in_makefile(regex):
@@ -114,9 +114,9 @@ def apply_astyle_format(format_file):
                  '--suffix=none',  # do not create a backup copy of the unformatted file
                  '--project=src/configs/astyle.rc',
                  format_file])
-    except FileNotFoundError:
+    except FileNotFoundError as ex:
         raise BuildError(
-            "astyle utility not installed, cannot apply formatting")
+            "astyle utility not installed, cannot apply formatting") from ex
 
 
 def main():
diff --git a/src/editors/vscode/scripts/common.py b/src/editors/vscode/scripts/common.py
index 1fe13663a..55fbf4494 100644
--- a/src/editors/vscode/scripts/common.py
+++ b/src/editors/vscode/scripts/common.py
@@ -2,7 +2,7 @@ import os
 import sys
 import subprocess
 import re
-
+import multiprocessing
 
 class BuildError(Exception):
     pass
@@ -16,7 +16,6 @@ def get_concurrency():
     max_concurrency = 16
 
     try:
-        import multiprocessing
         return min(max_concurrency, multiprocessing.cpu_count())
     except ImportError:
         return def_concurrency
@@ -33,8 +32,8 @@ def run_cmd(cmd, workingdir=None):
 
     try:
         subprocess.run(cmd, shell=shell, check=True, cwd=workingdir)
-    except subprocess.CalledProcessError:
-        raise BuildError('External command failed, aborting...')
+    except subprocess.CalledProcessError as ex:
+        raise BuildError('External command failed, aborting...') from ex
 
 
 def _find_regex_in_makefile(regex):
diff --git a/src/python/botan2.py b/src/python/botan2.py
index f0c23cdbd..ad8ed7531 100755
--- a/src/python/botan2.py
+++ b/src/python/botan2.py
@@ -38,7 +38,7 @@ class BotanException(Exception):
         self.__rc = rc
 
         if rc == 0:
-            super(BotanException, self).__init__(message)
+            super().__init__(message)
         else:
             exn_msg = _DLL.botan_error_last_exception_message().decode('ascii')
             err_descr = _DLL.botan_error_description(rc).decode('ascii')
@@ -47,7 +47,7 @@ class BotanException(Exception):
             if exn_msg != "":
                 formatted_msg += ': ' + exn_msg
 
-            super(BotanException, self).__init__(formatted_msg)
+            super().__init__(formatted_msg)
 
     def error_code(self):
         return self.__rc
diff --git a/src/scripts/bench.py b/src/scripts/bench.py
index 4194fb2db..572c12bf1 100755
--- a/src/scripts/bench.py
+++ b/src/scripts/bench.py
@@ -30,7 +30,7 @@ def setup_logging(options):
 
     class LogOnErrorHandler(logging.StreamHandler):
         def emit(self, record):
-            super(LogOnErrorHandler, self).emit(record)
+            super().emit(record)
             if record.levelno >= logging.ERROR:
                 sys.exit(1)
 
diff --git a/src/scripts/build_docs.py b/src/scripts/build_docs.py
index 904bd2534..554247674 100755
--- a/src/scripts/build_docs.py
+++ b/src/scripts/build_docs.py
@@ -17,6 +17,7 @@ import json
 import tempfile
 import os
 import stat
+import multiprocessing
 
 def get_concurrency():
     """
@@ -25,7 +26,6 @@ def get_concurrency():
     def_concurrency = 2
 
     try:
-        import multiprocessing
         return max(def_concurrency, multiprocessing.cpu_count())
     except ImportError:
         return def_concurrency
@@ -129,8 +129,8 @@ def read_config(config):
         f = open(config, encoding='utf8')
         cfg = json.load(f)
         f.close()
-    except OSError:
-        raise Exception('Failed to load build config %s - is build dir correct?' % (config))
+    except OSError as ex:
+        raise Exception('Failed to load build config %s - is build dir correct?' % (config)) from ex
 
     return cfg
 
diff --git a/src/scripts/check.py b/src/scripts/check.py
index 6a39d50c3..cc75f3a23 100755
--- a/src/scripts/check.py
+++ b/src/scripts/check.py
@@ -62,8 +62,8 @@ def read_config(config):
     try:
         with open(config, encoding='utf8') as f:
             return json.load(f)
-    except OSError:
-        raise Exception('Failed to load build config %s - is build dir correct?' % (config))
+    except OSError as ex:
+        raise Exception('Failed to load build config %s - is build dir correct?' % (config)) from ex
 
 
 def main(args=None):
diff --git a/src/scripts/ci_build.py b/src/scripts/ci_build.py
index e9bd08031..9411a308b 100755
--- a/src/scripts/ci_build.py
+++ b/src/scripts/ci_build.py
@@ -16,13 +16,13 @@ import sys
 import time
 import tempfile
 import optparse # pylint: disable=deprecated-module
+import multiprocessing
 
 def get_concurrency():
     def_concurrency = 2
     max_concurrency = 16
 
     try:
-        import multiprocessing
         return min(max_concurrency, multiprocessing.cpu_count())
     except ImportError:
         return def_concurrency
diff --git a/src/scripts/dist.py b/src/scripts/dist.py
index e499424f2..8e3522365 100755
--- a/src/scripts/dist.py
+++ b/src/scripts/dist.py
@@ -301,7 +301,7 @@ def write_archive(version, output_basename, archive_type, rel_epoch, all_files,
 def configure_logging(options):
     class ExitOnErrorLogHandler(logging.StreamHandler):
         def emit(self, record):
-            super(ExitOnErrorLogHandler, self).emit(record)
+            super().emit(record)
             # Exit script if and ERROR or worse occurred
             if record.levelno >= logging.ERROR:
                 if sys.exc_info()[2] is not None:


Test patch:
diff --git a/src/scripts/test_cli.py b/src/scripts/test_cli.py
index af0ba8eba..bf12d45e2 100755
--- a/src/scripts/test_cli.py
+++ b/src/scripts/test_cli.py
@@ -6,21 +6,27 @@
 Botan is released under the Simplified BSD License (see license.txt)
 """
 
-import subprocess
-import sys
-import os
+import base64
+import binascii
+import json
 import logging
+import multiprocessing
 import optparse # pylint: disable=deprecated-module
-import time
+import os
+import platform
+import random
+import re
 import shutil
+import socket
+import ssl
+import subprocess
+import sys
 import tempfile
-import re
-import random
-import json
-import binascii
-import platform
-import multiprocessing
+import threading
+import time
 from multiprocessing.pool import ThreadPool
+from http.client import HTTPSConnection
+from http.server import HTTPServer, BaseHTTPRequestHandler
 
 # pylint: disable=global-statement,unused-argument
 
@@ -36,7 +42,7 @@ def run_socket_tests():
 class TestLogHandler(logging.StreamHandler):
     def emit(self, record):
         # Do the default stuff first
-        super(TestLogHandler, self).emit(record)
+        super().emit(record)
         if record.levelno >= logging.ERROR:
             global TESTS_FAILED
             TESTS_FAILED += 1
@@ -560,10 +566,6 @@ ed25519 cj8GsiNlRkqiDElAeNMSBBMwrAl15hYPgX50+GWX/lA= Tsy82BBU2xxVqNe1ip11OyEGoKW
 def cli_roughtime_tests(tmp_dir):
     # pylint: disable=line-too-long
     # pylint: disable=too-many-locals
-    import socket
-    import base64
-    import threading
-
     if not check_for_command("roughtime"):
         return
 
@@ -916,15 +918,6 @@ def cli_tls_http_server_tests(tmp_dir):
     if not run_socket_tests() or not check_for_command("tls_http_server"):
         return
 
-    try:
-        from http.client import HTTPSConnection
-    except ImportError:
-        try:
-            from httplib import HTTPSConnection
-        except ImportError:
-            return
-    import ssl
-
     server_port = random_port_number()
 
     priv_key = os.path.join(tmp_dir, 'priv.pem')
@@ -979,25 +972,6 @@ def cli_tls_proxy_tests(tmp_dir):
     if not run_socket_tests() or not check_for_command("tls_proxy"):
         return
 
-    try:
-        from http.client import HTTPSConnection
-    except ImportError:
-        try:
-            from httplib import HTTPSConnection
-        except ImportError:
-            return
-
-    try:
-        from http.server import HTTPServer, BaseHTTPRequestHandler
-    except ImportError:
-        try:
-            from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
-        except ImportError:
-            return
-
-    import ssl
-    import threading
-
     server_port = random_port_number()
     proxy_port = random_port_number()