scripts/install.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9218
71cf3979a6c9
child 9231
d92a18dffa5e
--- a/scripts/install.py	Wed Jul 13 11:16:20 2022 +0200
+++ b/scripts/install.py	Wed Jul 13 14:55:47 2022 +0200
@@ -22,7 +22,7 @@
 import re
 import shlex
 import shutil
-import subprocess               # secok
+import subprocess  # secok
 import time
 import sys
 
@@ -47,11 +47,12 @@
 progLanguages = ["Python", "Ruby", "QSS"]
 sourceDir = "eric"
 eric7SourceDir = ""
-configName = 'eric7config.py'
+configName = "eric7config.py"
 defaultMacAppBundleName = "eric7.app"
 defaultMacAppBundlePath = "/Applications"
 defaultMacPythonExe = "{0}/Resources/Python.app/Contents/MacOS/Python".format(
-    sys.exec_prefix)
+    sys.exec_prefix
+)
 if not os.path.exists(defaultMacPythonExe):
     defaultMacPythonExe = ""
 macAppBundleName = defaultMacAppBundleName
@@ -75,13 +76,11 @@
         "PyQt6": [],
         "QScintilla2": [],
     },
-    
     "linux": {
         "sip": [],
         "PyQt6": [],
         "QScintilla2": [],
     },
-    
     "mac": {
         "sip": [],
         "PyQt6": [],
@@ -93,19 +92,19 @@
 def exit(rcode=0):
     """
     Exit the install script.
-    
+
     @param rcode result code to report back (integer)
     """
     global currDir
-    
+
     print()
-    
+
     if sys.platform.startswith(("win", "cygwin")):
         with contextlib.suppress():
-            input("Press enter to continue...")             # secok
-    
+            input("Press enter to continue...")  # secok
+
     os.chdir(currDir)
-    
+
     sys.exit(rcode)
 
 
@@ -121,20 +120,23 @@
     print()
     print("Usage:")
     if sys.platform == "darwin":
-        print("    {0} [-chvxz] [-a dir] [-b dir] [-d dir] [-f file] [-i dir]"
-              " [-m name] [-n path] [-p python] [--help] [--no-apis]"
-              " [--no-info] [--no-tools] [--verbose] [--yes]"
-              .format(progName))
+        print(
+            "    {0} [-chvxz] [-a dir] [-b dir] [-d dir] [-f file] [-i dir]"
+            " [-m name] [-n path] [-p python] [--help] [--no-apis]"
+            " [--no-info] [--no-tools] [--verbose] [--yes]".format(progName)
+        )
     elif sys.platform.startswith(("win", "cygwin")):
-        print("    {0} [-chvxz] [-a dir] [-b dir] [-d dir] [-f file]"
-              " [--clean-desktop] [--help] [--no-apis] [--no-info]"
-              " [--no-tools] [--verbose] [--yes]"
-              .format(progName))
+        print(
+            "    {0} [-chvxz] [-a dir] [-b dir] [-d dir] [-f file]"
+            " [--clean-desktop] [--help] [--no-apis] [--no-info]"
+            " [--no-tools] [--verbose] [--yes]".format(progName)
+        )
     else:
-        print("    {0} [-chvxz] [-a dir] [-b dir] [-d dir] [-f file] [-i dir]"
-              " [--help] [--no-apis] [--no-info] [--no-tools] [--verbose]"
-              " [--yes]"
-              .format(progName))
+        print(
+            "    {0} [-chvxz] [-a dir] [-b dir] [-d dir] [-f file] [-i dir]"
+            " [--help] [--no-apis] [--no-info] [--no-tools] [--verbose]"
+            " [--yes]".format(progName)
+        )
     print("where:")
     print("    -h, --help display this help message")
     print("    -a dir     where the API files will be installed")
@@ -147,8 +149,7 @@
     print("               (default: {0})".format(platBinDir))
     print("    -d dir     where eric python files will be installed")
     print("               (default: {0})".format(modDir))
-    print("    -f file    configuration file naming the various installation"
-          " paths")
+    print("    -f file    configuration file naming the various installation" " paths")
     if not sys.platform.startswith(("win", "cygwin")):
         print("    -i dir     temporary install prefix")
         print("               (default: {0})".format(distDir))
@@ -166,21 +167,23 @@
     print("    --no-info  don't create the install info file")
     print("    --no-tools don't install qt6-applications")
     print("    -v, --verbose print some more information")
-    print("    -x         don't perform dependency checks (use on your own"
-          " risk)")
+    print("    -x         don't perform dependency checks (use on your own" " risk)")
     print("    -z         don't compile the installed python files")
     print("    --yes      answer 'yes' to all questions")
     print()
-    print("The file given to the -f option must be valid Python code"
-          " defining a")
-    print("dictionary called 'cfg' with the keys 'ericDir', 'ericPixDir',"
-          " 'ericIconDir',")
+    print("The file given to the -f option must be valid Python code" " defining a")
+    print(
+        "dictionary called 'cfg' with the keys 'ericDir', 'ericPixDir',"
+        " 'ericIconDir',"
+    )
     print("'ericDTDDir', 'ericCSSDir', 'ericStylesDir', 'ericThemesDir',")
     print(" 'ericDocDir', ericExamplesDir',")
     print("'ericTranslationsDir', 'ericTemplatesDir', 'ericCodeTemplatesDir',")
     print("'ericOthersDir','bindir', 'mdir' and 'apidir.")
-    print("These define the directories for the installation of the various"
-          " parts of eric.")
+    print(
+        "These define the directories for the installation of the various"
+        " parts of eric."
+    )
 
     exit(rcode)
 
@@ -191,9 +194,9 @@
     simple assignment.
     """
     global platBinDir, modDir, pyModDir, apisDir, platBinDirOld
-    
+
     import sysconfig
-    
+
     if sys.platform.startswith(("win", "cygwin")):
         platBinDir = sys.exec_prefix
         if platBinDir.endswith("\\"):
@@ -210,15 +213,12 @@
         else:
             # install them in the user's bin directory
             platBinDir = os.path.expanduser("~/bin")
-        if (
-            platBinDir != "/usr/local/bin" and
-            os.access("/usr/local/bin", os.W_OK)
-        ):
+        if platBinDir != "/usr/local/bin" and os.access("/usr/local/bin", os.W_OK):
             platBinDirOld = "/usr/local/bin"
 
-    modDir = sysconfig.get_path('platlib')
+    modDir = sysconfig.get_path("platlib")
     pyModDir = modDir
-    
+
     pyqtDataDir = os.path.join(modDir, "PyQt6")
     if os.path.exists(os.path.join(pyqtDataDir, "qsci")):
         # it's the installer
@@ -230,6 +230,7 @@
         # determine dynamically
         try:
             from PyQt6.QtCore import QLibraryInfo
+
             qtDataDir = QLibraryInfo.path(QLibraryInfo.LibraryPath.DataPath)
         except ImportError:
             qtDataDir = None
@@ -250,19 +251,19 @@
 def copyDesktopFile(src, dst):
     """
     Modify a desktop file and write it to its destination.
-    
+
     @param src source file name (string)
     @param dst destination file name (string)
     """
     global cfg, platBinDir
-    
+
     with open(src, "r", encoding="utf-8") as f:
         text = f.read()
-    
+
     text = text.replace("@BINDIR@", platBinDir)
     text = text.replace("@MARKER@", "")
     text = text.replace("@PY_MARKER@", "")
-    
+
     with open(dst, "w", encoding="utf-8") as f:
         f.write(text)
     os.chmod(dst, 0o644)
@@ -271,7 +272,7 @@
 def copyAppStreamFile(src, dst):
     """
     Modify an appstream file and write it to its destination.
-    
+
     @param src source file name (string)
     @param dst destination file name (string)
     """
@@ -283,16 +284,16 @@
         from src.eric7.UI.Info import Version
     else:
         Version = "Unknown"
-    
+
     with open(src, "r", encoding="utf-8") as f:
         text = f.read()
-    
+
     text = (
         text.replace("@MARKER@", "")
         .replace("@VERSION@", Version.split(None, 1)[0])
         .replace("@DATE@", time.strftime("%Y-%m-%d"))
     )
-    
+
     with open(dst, "w", encoding="utf-8") as f:
         f.write(text)
     os.chmod(dst, 0o644)
@@ -301,15 +302,15 @@
 def wrapperNames(dname, wfile):
     """
     Create the platform specific names for the wrapper script.
-    
+
     @param dname name of the directory to place the wrapper into
     @param wfile basename (without extension) of the wrapper script
     @return the names of the wrapper scripts
     """
     wnames = (
         (dname + "\\" + wfile + ".cmd", dname + "\\" + wfile + ".bat")
-        if sys.platform.startswith(("win", "cygwin")) else
-        (dname + "/" + wfile, )
+        if sys.platform.startswith(("win", "cygwin"))
+        else (dname + "/" + wfile,)
     )
 
     return wnames
@@ -332,17 +333,17 @@
         wname = wfile + ".cmd"
         if isGuiScript:
             wrapper = (
-                '''@echo off\n'''
+                """@echo off\n"""
                 '''start "" "{2}\\pythonw.exe"'''
                 ''' "{0}\\{1}.pyw"'''
-                ''' %1 %2 %3 %4 %5 %6 %7 %8 %9\n'''.format(
-                    pydir, wfile, os.path.dirname(sys.executable))
+                """ %1 %2 %3 %4 %5 %6 %7 %8 %9\n""".format(
+                    pydir, wfile, os.path.dirname(sys.executable)
+                )
             )
         else:
             wrapper = (
                 '''@"{0}" "{1}\\{2}.py"'''
-                ''' %1 %2 %3 %4 %5 %6 %7 %8 %9\n'''.format(
-                    sys.executable, pydir, wfile)
+                """ %1 %2 %3 %4 %5 %6 %7 %8 %9\n""".format(sys.executable, pydir, wfile)
             )
 
     # Mac OS X
@@ -352,22 +353,24 @@
         if not os.path.exists(pyexec):
             pyexec = "{0}/bin/python{1}".format(sys.exec_prefix, major)
         wname = wfile
-        wrapper = ('''#!/bin/sh\n'''
-                   '''\n'''
-                   '''exec "{0}" "{1}/{2}.py" "$@"\n'''
-                   .format(pyexec, pydir, wfile))
+        wrapper = (
+            """#!/bin/sh\n"""
+            """\n"""
+            """exec "{0}" "{1}/{2}.py" "$@"\n""".format(pyexec, pydir, wfile)
+        )
 
     # *nix systems
     else:
         wname = wfile
-        wrapper = ('''#!/bin/sh\n'''
-                   '''\n'''
-                   '''exec "{0}" "{1}/{2}.py" "$@"\n'''
-                   .format(sys.executable, pydir, wfile))
-    
+        wrapper = (
+            """#!/bin/sh\n"""
+            """\n"""
+            """exec "{0}" "{1}/{2}.py" "$@"\n""".format(sys.executable, pydir, wfile)
+        )
+
     wname = os.path.join(saveDir, wname)
     copyToFile(wname, wrapper)
-    os.chmod(wname, 0o755)                  # secok
+    os.chmod(wname, 0o755)  # secok
 
     return wname
 
@@ -376,7 +379,7 @@
     """
     Copy Python, translation, documentation, wizards configuration,
     designer template files and DTDs of a directory tree.
-    
+
     @param src name of the source directory
     @param dst name of the destination directory
     @param filters list of filter pattern determining the files to be copied
@@ -393,7 +396,7 @@
     except OSError:
         # ignore missing directories (most probably the i18n directory)
         return
-    
+
     for name in names:
         skipIt = False
         for excludePattern in excludePatterns:
@@ -412,8 +415,7 @@
                     break
             else:
                 if os.path.isdir(srcname) and srcname not in excludeDirs:
-                    copyTree(srcname, dstname, filters,
-                             excludePatterns=excludePatterns)
+                    copyTree(srcname, dstname, filters, excludePatterns=excludePatterns)
 
 
 def createGlobalPluginsDir():
@@ -421,8 +423,8 @@
     Create the global plugins directory, if it doesn't exist.
     """
     global cfg, distDir
-    
-    pdir = os.path.join(cfg['mdir'], "eric7plugins")
+
+    pdir = os.path.join(cfg["mdir"], "eric7plugins")
     fname = os.path.join(pdir, "__init__.py")
     if not os.path.exists(fname):
         if not os.path.exists(pdir):
@@ -443,32 +445,32 @@
     """
     Cleanup the sources directory to get rid of leftover files
     and directories.
-    
+
     @param dirName name of the directory to prune (string)
     """
     # step 1: delete all Ui_*.py files without a corresponding
     #         *.ui file
     dirListing = os.listdir(dirName)
     for formName, sourceName in [
-        (f.replace('Ui_', "").replace(".py", ".ui"), f)
-            for f in dirListing if fnmatch.fnmatch(f, "Ui_*.py")]:
+        (f.replace("Ui_", "").replace(".py", ".ui"), f)
+        for f in dirListing
+        if fnmatch.fnmatch(f, "Ui_*.py")
+    ]:
         if not os.path.exists(os.path.join(dirName, formName)):
             os.remove(os.path.join(dirName, sourceName))
             if os.path.exists(os.path.join(dirName, sourceName + "c")):
                 os.remove(os.path.join(dirName, sourceName + "c"))
-    
+
     # step 2: delete the __pycache__ directory and all remaining *.pyc files
     if os.path.exists(os.path.join(dirName, "__pycache__")):
         shutil.rmtree(os.path.join(dirName, "__pycache__"))
-    for name in [f for f in os.listdir(dirName)
-                 if fnmatch.fnmatch(f, "*.pyc")]:
+    for name in [f for f in os.listdir(dirName) if fnmatch.fnmatch(f, "*.pyc")]:
         os.remove(os.path.join(dirName, name))
-    
+
     # step 3: delete *.orig files
-    for name in [f for f in os.listdir(dirName)
-                 if fnmatch.fnmatch(f, "*.orig")]:
+    for name in [f for f in os.listdir(dirName) if fnmatch.fnmatch(f, "*.orig")]:
         os.remove(os.path.join(dirName, name))
-    
+
     # step 4: descent into subdirectories and delete them if empty
     for name in os.listdir(dirName):
         name = os.path.join(dirName, name)
@@ -483,7 +485,7 @@
     Uninstall the old eric files.
     """
     global platBinDir, platBinDirOld
-    
+
     try:
         from eric7config import getConfig
     except ImportError:
@@ -492,31 +494,47 @@
     except SyntaxError:
         # an incomplete or old config file was found
         return
-    
+
     global pyModDir, progLanguages
-    
+
     # Remove the menu entry for Linux systems
     if sys.platform.startswith("linux"):
         cleanUpLinuxSpecifics()
     # Remove the Desktop and Start Menu entries for Windows systems
     elif sys.platform.startswith(("win", "cygwin")):
         cleanUpWindowsLinks()
-    
+
     # Remove the wrapper scripts
     rem_wnames = [
-        "eric7_api", "eric7_browser", "eric7_compare", "eric7_configure",
-        "eric7_diff", "eric7_doc", "eric7_editor", "eric7_hexeditor",
-        "eric7_iconeditor", "eric7_plugininstall", "eric7_pluginrepository",
-        "eric7_pluginuninstall", "eric7_qregularexpression", "eric7_re",
-        "eric7_shell", "eric7_snap", "eric7_sqlbrowser", "eric7_testing",
-        "eric7_tray", "eric7_trpreviewer", "eric7_uipreviewer",
-        "eric7_virtualenv", "eric7",
+        "eric7_api",
+        "eric7_browser",
+        "eric7_compare",
+        "eric7_configure",
+        "eric7_diff",
+        "eric7_doc",
+        "eric7_editor",
+        "eric7_hexeditor",
+        "eric7_iconeditor",
+        "eric7_plugininstall",
+        "eric7_pluginrepository",
+        "eric7_pluginuninstall",
+        "eric7_qregularexpression",
+        "eric7_re",
+        "eric7_shell",
+        "eric7_snap",
+        "eric7_sqlbrowser",
+        "eric7_testing",
+        "eric7_tray",
+        "eric7_trpreviewer",
+        "eric7_uipreviewer",
+        "eric7_virtualenv",
+        "eric7",
         # obsolete scripts below
         "eric7_unittest",
     ]
-    
+
     try:
-        dirs = [platBinDir, getConfig('bindir')]
+        dirs = [platBinDir, getConfig("bindir")]
         if platBinDirOld:
             dirs.append(platBinDirOld)
         for rem_wname in rem_wnames:
@@ -524,9 +542,9 @@
                 for rwname in wrapperNames(d, rem_wname):
                     if os.path.exists(rwname):
                         os.remove(rwname)
-        
+
         # Cleanup our config file(s)
-        for name in ['eric7config.py', 'eric7config.pyc', 'eric7.pth']:
+        for name in ["eric7config.py", "eric7config.pyc", "eric7.pth"]:
             e6cfile = os.path.join(pyModDir, name)
             if os.path.exists(e6cfile):
                 os.remove(e6cfile)
@@ -534,42 +552,52 @@
             path, ext = os.path.splitext(e6cfile)
             for f in glob.glob("{0}.*{1}".format(path, ext)):
                 os.remove(f)
-            
+
         # Cleanup the install directories
-        for name in ['ericExamplesDir', 'ericDocDir', 'ericDTDDir',
-                     'ericCSSDir', 'ericIconDir', 'ericPixDir',
-                     'ericTemplatesDir', 'ericCodeTemplatesDir',
-                     'ericOthersDir', 'ericStylesDir', 'ericThemesDir',
-                     'ericDir']:
+        for name in [
+            "ericExamplesDir",
+            "ericDocDir",
+            "ericDTDDir",
+            "ericCSSDir",
+            "ericIconDir",
+            "ericPixDir",
+            "ericTemplatesDir",
+            "ericCodeTemplatesDir",
+            "ericOthersDir",
+            "ericStylesDir",
+            "ericThemesDir",
+            "ericDir",
+        ]:
             with contextlib.suppress(AttributeError):
                 if os.path.exists(getConfig(name)):
                     shutil.rmtree(getConfig(name), True)
-        
+
         # Cleanup translations
         for name in glob.glob(
-                os.path.join(getConfig('ericTranslationsDir'), 'eric7_*.qm')):
+            os.path.join(getConfig("ericTranslationsDir"), "eric7_*.qm")
+        ):
             if os.path.exists(name):
                 os.remove(name)
-        
+
         # Cleanup API files
         with contextlib.suppress(AttributeError):
-            apidir = getConfig('apidir')
+            apidir = getConfig("apidir")
             for progLanguage in progLanguages:
-                for name in getConfig('apis'):
+                for name in getConfig("apis"):
                     apiname = os.path.join(apidir, progLanguage.lower(), name)
                     if os.path.exists(apiname):
                         os.remove(apiname)
                 for apiname in glob.glob(
-                        os.path.join(apidir, progLanguage.lower(), "*.bas")):
+                    os.path.join(apidir, progLanguage.lower(), "*.bas")
+                ):
                     if os.path.basename(apiname) != "eric7.bas":
                         os.remove(apiname)
-        
+
         if sys.platform == "darwin":
             # delete the Mac app bundle
             cleanUpMacAppBundle()
     except OSError as msg:
-        sys.stderr.write(
-            'Error: {0}\nTry install with admin rights.\n'.format(msg))
+        sys.stderr.write("Error: {0}\nTry install with admin rights.\n".format(msg))
         exit(7)
 
 
@@ -584,7 +612,6 @@
             "/usr/share/metainfo/eric7.appdata.xml",
             "/usr/share/pixmaps/eric.png",
             "/usr/share/icons/eric.png",
-            
             "/usr/share/applications/eric7_browser.desktop",
             "/usr/share/pixmaps/ericWeb.png",
             "/usr/share/icons/ericWeb.png",
@@ -599,7 +626,6 @@
             "~/.local/share/metainfo/eric7.appdata.xml",
             "~/.local/share/pixmaps/eric.png",
             "~/.local/share/icons/eric.png",
-            
             "~/.local/share/applications/eric7_browser.desktop",
             "~/.local/share/pixmaps/ericWeb.png",
             "~/.local/share/icons/ericWeb.png",
@@ -614,17 +640,17 @@
     Uninstall the macOS application bundle.
     """
     from eric7config import getConfig
+
     try:
         macAppBundlePath = getConfig("macAppBundlePath")
         macAppBundleName = getConfig("macAppBundleName")
     except AttributeError:
         macAppBundlePath = defaultMacAppBundlePath
         macAppBundleName = defaultMacAppBundleName
-    for bundlePath in [os.path.join(defaultMacAppBundlePath,
-                                    macAppBundleName),
-                       os.path.join(macAppBundlePath,
-                                    macAppBundleName),
-                       ]:
+    for bundlePath in [
+        os.path.join(defaultMacAppBundlePath, macAppBundleName),
+        os.path.join(macAppBundlePath, macAppBundleName),
+    ]:
         if os.path.exists(bundlePath):
             shutil.rmtree(bundlePath)
 
@@ -634,18 +660,18 @@
     Clean up the Desktop and Start Menu entries for Windows.
     """
     global doCleanDesktopLinks, forceCleanDesktopLinks
-    
+
     try:
-        from pywintypes import com_error        # __IGNORE_WARNING__
+        from pywintypes import com_error  # __IGNORE_WARNING__
     except ImportError:
         # links were not created by install.py
         return
-    
+
     regPath = (
-        "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer" +
-        "\\User Shell Folders"
+        "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"
+        + "\\User Shell Folders"
     )
-    
+
     if doCleanDesktopLinks or forceCleanDesktopLinks:
         # 1. cleanup desktop links
         regName = "Desktop"
@@ -660,7 +686,7 @@
                     except OSError:
                         # maybe restrictions prohibited link removal
                         print("Could not remove '{0}'.".format(linkPath))
-    
+
     # 2. cleanup start menu entry
     regName = "Programs"
     programsEntry = getWinregEntry(regName, regPath)
@@ -678,7 +704,7 @@
 def shutilCopy(src, dst, perm=0o644):
     """
     Wrapper function around shutil.copy() to ensure the permissions.
-    
+
     @param src source file name (string)
     @param dst destination file name or directory name (string)
     @param perm permissions to be set (integer)
@@ -692,240 +718,277 @@
 def installEric():
     """
     Actually perform the installation steps.
-    
+
     @return result code (integer)
     """
     global distDir, doCleanup, cfg, progLanguages, sourceDir, configName
     global installApis
-    
+
     # Create the platform specific wrappers.
     scriptsDir = "install_scripts"
     if not os.path.isdir(scriptsDir):
         os.mkdir(scriptsDir)
     wnames = []
     for name in ["eric7_api", "eric7_doc"]:
-        wnames.append(createPyWrapper(cfg['ericDir'], name, scriptsDir, False))
-    for name in ["eric7_browser", "eric7_compare", "eric7_configure",
-                 "eric7_diff", "eric7_editor", "eric7_hexeditor",
-                 "eric7_iconeditor", "eric7_plugininstall",
-                 "eric7_pluginrepository", "eric7_pluginuninstall",
-                 "eric7_qregularexpression", "eric7_re", "eric7_shell",
-                 "eric7_snap", "eric7_sqlbrowser", "eric7_tray",
-                 "eric7_trpreviewer", "eric7_uipreviewer", "eric7_testing",
-                 "eric7_virtualenv", "eric7"]:
-        wnames.append(createPyWrapper(cfg['ericDir'], name, scriptsDir))
-    
+        wnames.append(createPyWrapper(cfg["ericDir"], name, scriptsDir, False))
+    for name in [
+        "eric7_browser",
+        "eric7_compare",
+        "eric7_configure",
+        "eric7_diff",
+        "eric7_editor",
+        "eric7_hexeditor",
+        "eric7_iconeditor",
+        "eric7_plugininstall",
+        "eric7_pluginrepository",
+        "eric7_pluginuninstall",
+        "eric7_qregularexpression",
+        "eric7_re",
+        "eric7_shell",
+        "eric7_snap",
+        "eric7_sqlbrowser",
+        "eric7_tray",
+        "eric7_trpreviewer",
+        "eric7_uipreviewer",
+        "eric7_testing",
+        "eric7_virtualenv",
+        "eric7",
+    ]:
+        wnames.append(createPyWrapper(cfg["ericDir"], name, scriptsDir))
+
     # set install prefix, if not None
     if distDir:
         for key in list(cfg.keys()):
-            cfg[key] = os.path.normpath(
-                os.path.join(distDir, cfg[key].lstrip(os.sep)))
-    
+            cfg[key] = os.path.normpath(os.path.join(distDir, cfg[key].lstrip(os.sep)))
+
     try:
         # Install the files
         # make the install directories
         for key in cfg:
             if cfg[key] and not os.path.isdir(cfg[key]):
                 os.makedirs(cfg[key])
-        
+
         # copy the eric config file
         if distDir:
-            shutilCopy(configName, cfg['mdir'])
-            if os.path.exists(configName + 'c'):
-                shutilCopy(configName + 'c', cfg['mdir'])
+            shutilCopy(configName, cfg["mdir"])
+            if os.path.exists(configName + "c"):
+                shutilCopy(configName + "c", cfg["mdir"])
         else:
             shutilCopy(configName, modDir)
-            if os.path.exists(configName + 'c'):
-                shutilCopy(configName + 'c', modDir)
-        
+            if os.path.exists(configName + "c"):
+                shutilCopy(configName + "c", modDir)
+
         # copy the various parts of eric
         copyTree(
             eric7SourceDir,
-            cfg['ericDir'],
-            ['*.py', '*.pyc', '*.pyo', '*.pyw'],
-            excludePatterns=["eric7config.py*"])
+            cfg["ericDir"],
+            ["*.py", "*.pyc", "*.pyo", "*.pyw"],
+            excludePatterns=["eric7config.py*"],
+        )
         copyTree(
             os.path.join(eric7SourceDir, "Plugins"),
-            os.path.join(cfg['ericDir'], "Plugins"),
-            ['*.svgz', '*.svg', '*.png', '*.style', '*.tmpl', '*.txt'])
+            os.path.join(cfg["ericDir"], "Plugins"),
+            ["*.svgz", "*.svg", "*.png", "*.style", "*.tmpl", "*.txt"],
+        )
         copyTree(
             os.path.join(eric7SourceDir, "Documentation"),
-            cfg['ericDocDir'],
-            ['*.html', '*.qch'])
-        copyTree(
-            os.path.join(eric7SourceDir, "CSSs"),
-            cfg['ericCSSDir'],
-            ['*.css'])
+            cfg["ericDocDir"],
+            ["*.html", "*.qch"],
+        )
+        copyTree(os.path.join(eric7SourceDir, "CSSs"), cfg["ericCSSDir"], ["*.css"])
         copyTree(
             os.path.join(eric7SourceDir, "Styles"),
-            cfg['ericStylesDir'],
-            ['*.qss', '*.ehj'])
+            cfg["ericStylesDir"],
+            ["*.qss", "*.ehj"],
+        )
         copyTree(
-            os.path.join(eric7SourceDir, "Themes"),
-            cfg['ericThemesDir'],
-            ['*.ethj'])
+            os.path.join(eric7SourceDir, "Themes"), cfg["ericThemesDir"], ["*.ethj"]
+        )
         copyTree(
-            os.path.join(eric7SourceDir, "i18n"),
-            cfg['ericTranslationsDir'],
-            ['*.qm'])
+            os.path.join(eric7SourceDir, "i18n"), cfg["ericTranslationsDir"], ["*.qm"]
+        )
         copyTree(
             os.path.join(eric7SourceDir, "icons"),
-            cfg['ericIconDir'],
-            ['*.svgz', '*.svg', '*.png', 'LICENSE*.*', 'readme.txt'])
+            cfg["ericIconDir"],
+            ["*.svgz", "*.svg", "*.png", "LICENSE*.*", "readme.txt"],
+        )
         copyTree(
             os.path.join(eric7SourceDir, "pixmaps"),
-            cfg['ericPixDir'],
-            ['*.svgz', '*.svg', '*.png', '*.xpm', '*.ico', '*.gif'])
+            cfg["ericPixDir"],
+            ["*.svgz", "*.svg", "*.png", "*.xpm", "*.ico", "*.gif"],
+        )
         copyTree(
             os.path.join(eric7SourceDir, "DesignerTemplates"),
-            cfg['ericTemplatesDir'],
-            ['*.tmpl'])
+            cfg["ericTemplatesDir"],
+            ["*.tmpl"],
+        )
         copyTree(
             os.path.join(eric7SourceDir, "CodeTemplates"),
-            cfg['ericCodeTemplatesDir'],
-            ['*.tmpl'])
+            cfg["ericCodeTemplatesDir"],
+            ["*.tmpl"],
+        )
         copyTree(
             os.path.join(eric7SourceDir, "DebugClients", "Python", "coverage"),
-            os.path.join(cfg['ericDir'], "DebugClients", "Python", "coverage"),
-            ['*.js', '*.html', '*.png', '*.css', '*.scss', '*.txt', '*.rst'])
-        
+            os.path.join(cfg["ericDir"], "DebugClients", "Python", "coverage"),
+            ["*.js", "*.html", "*.png", "*.css", "*.scss", "*.txt", "*.rst"],
+        )
+
         # copy some data files needed at various places
         copyTree(
             os.path.join(eric7SourceDir, "data"),
-            os.path.join(cfg['ericDir'], "data"),
-            ['*.txt'])
+            os.path.join(cfg["ericDir"], "data"),
+            ["*.txt"],
+        )
         copyTree(
             os.path.join(eric7SourceDir, "EricNetwork", "data"),
-            os.path.join(cfg['ericDir'], "EricNetwork", "data"),
-            ['*.dat', '*.txt'])
+            os.path.join(cfg["ericDir"], "EricNetwork", "data"),
+            ["*.dat", "*.txt"],
+        )
         copyTree(
             os.path.join(eric7SourceDir, "IconEditor", "cursors"),
-            os.path.join(cfg['ericDir'], "IconEditor", "cursors"),
-            ['*.xpm'])
+            os.path.join(cfg["ericDir"], "IconEditor", "cursors"),
+            ["*.xpm"],
+        )
         copyTree(
             os.path.join(eric7SourceDir, "UI", "data"),
-            os.path.join(cfg['ericDir'], "UI", "data"),
-            ['*.css'])
+            os.path.join(cfg["ericDir"], "UI", "data"),
+            ["*.css"],
+        )
         copyTree(
             os.path.join(eric7SourceDir, "WebBrowser"),
-            os.path.join(cfg['ericDir'], "WebBrowser"),
-            ['*.xbel', '*.xml', '*.html', '*.png', '*.gif', '*.js'])
-        
+            os.path.join(cfg["ericDir"], "WebBrowser"),
+            ["*.xbel", "*.xml", "*.html", "*.png", "*.gif", "*.js"],
+        )
+
         # copy the wrappers
         for wname in wnames:
-            shutilCopy(wname, cfg['bindir'], perm=0o755)
+            shutilCopy(wname, cfg["bindir"], perm=0o755)
             os.remove(wname)
         shutil.rmtree(scriptsDir)
-        
+
         # copy the license file
-        shutilCopy(os.path.join(sourceDir, "docs", "LICENSE.GPL3"),
-                   cfg['ericDir'])
-        
+        shutilCopy(os.path.join(sourceDir, "docs", "LICENSE.GPL3"), cfg["ericDir"])
+
         # create the global plugins directory
         createGlobalPluginsDir()
-        
+
     except OSError as msg:
-        sys.stderr.write(
-            'Error: {0}\nTry install with admin rights.\n'.format(msg))
-        return(7)
-    
+        sys.stderr.write("Error: {0}\nTry install with admin rights.\n".format(msg))
+        return 7
+
     # copy some text files to the doc area
     for name in ["LICENSE.GPL3", "THANKS", "changelog"]:
         try:
-            shutilCopy(os.path.join(sourceDir, "docs", name),
-                       cfg['ericDocDir'])
+            shutilCopy(os.path.join(sourceDir, "docs", name), cfg["ericDocDir"])
         except OSError:
-            print("Could not install '{0}'.".format(
-                os.path.join(sourceDir, "docs", name)))
-    for name in glob.glob(os.path.join(sourceDir, 'docs', 'README*.*')):
+            print(
+                "Could not install '{0}'.".format(os.path.join(sourceDir, "docs", name))
+            )
+    for name in glob.glob(os.path.join(sourceDir, "docs", "README*.*")):
         try:
-            shutilCopy(name, cfg['ericDocDir'])
+            shutilCopy(name, cfg["ericDocDir"])
         except OSError:
             print("Could not install '{0}'.".format(name))
-   
+
     # copy some more stuff
-    for name in ('default.ekj', 'default_Mac.ekj',
-                 'default.e4k', 'default_Mac.e4k'):
+    for name in ("default.ekj", "default_Mac.ekj", "default.e4k", "default_Mac.e4k"):
         try:
-            shutilCopy(os.path.join(sourceDir, "others", name),
-                       cfg['ericOthersDir'])
+            shutilCopy(os.path.join(sourceDir, "others", name), cfg["ericOthersDir"])
         except OSError:
-            print("Could not install '{0}'.".format(
-                os.path.join(sourceDir, "others", name)))
-    
+            print(
+                "Could not install '{0}'.".format(
+                    os.path.join(sourceDir, "others", name)
+                )
+            )
+
     # install the API file
     if installApis:
         for progLanguage in progLanguages:
-            apidir = os.path.join(cfg['apidir'], progLanguage.lower())
-            print("Installing {0} API files to '{1}'.".format(
-                progLanguage, apidir))
+            apidir = os.path.join(cfg["apidir"], progLanguage.lower())
+            print("Installing {0} API files to '{1}'.".format(progLanguage, apidir))
             if not os.path.exists(apidir):
                 os.makedirs(apidir)
-            for apiName in glob.glob(os.path.join(eric7SourceDir, "APIs",
-                                                  progLanguage, "*.api")):
+            for apiName in glob.glob(
+                os.path.join(eric7SourceDir, "APIs", progLanguage, "*.api")
+            ):
                 try:
                     shutilCopy(apiName, apidir)
                 except OSError:
-                    print("Could not install '{0}' (no permission)."
-                          .format(apiName))
-            for apiName in glob.glob(os.path.join(eric7SourceDir, "APIs",
-                                                  progLanguage, "*.bas")):
+                    print("Could not install '{0}' (no permission).".format(apiName))
+            for apiName in glob.glob(
+                os.path.join(eric7SourceDir, "APIs", progLanguage, "*.bas")
+            ):
                 try:
                     shutilCopy(apiName, apidir)
                 except OSError:
-                    print("Could not install '{0}' (no permission)."
-                          .format(apiName))
+                    print("Could not install '{0}' (no permission).".format(apiName))
             if progLanguage == "Python":
                 # copy Python3 API files to the same destination
-                for apiName in glob.glob(os.path.join(eric7SourceDir, "APIs",
-                                                      "Python3", "*.api")):
+                for apiName in glob.glob(
+                    os.path.join(eric7SourceDir, "APIs", "Python3", "*.api")
+                ):
                     try:
                         shutilCopy(apiName, apidir)
                     except OSError:
-                        print("Could not install '{0}' (no permission)."
-                              .format(apiName))
-                for apiName in glob.glob(os.path.join(eric7SourceDir, "APIs",
-                                                      "Python3", "*.bas")):
-                    if os.path.exists(os.path.join(
-                        apidir, os.path.basename(
-                            apiName.replace(".bas", ".api")))):
+                        print(
+                            "Could not install '{0}' (no permission).".format(apiName)
+                        )
+                for apiName in glob.glob(
+                    os.path.join(eric7SourceDir, "APIs", "Python3", "*.bas")
+                ):
+                    if os.path.exists(
+                        os.path.join(
+                            apidir, os.path.basename(apiName.replace(".bas", ".api"))
+                        )
+                    ):
                         try:
                             shutilCopy(apiName, apidir)
                         except OSError:
-                            print("Could not install '{0}' (no permission)."
-                                  .format(apiName))
-                
+                            print(
+                                "Could not install '{0}' (no permission).".format(
+                                    apiName
+                                )
+                            )
+
                 # copy MicroPython API files to the same destination
-                for apiName in glob.glob(os.path.join(eric7SourceDir, "APIs",
-                                                      "MicroPython", "*.api")):
+                for apiName in glob.glob(
+                    os.path.join(eric7SourceDir, "APIs", "MicroPython", "*.api")
+                ):
                     try:
                         shutilCopy(apiName, apidir)
                     except OSError:
-                        print("Could not install '{0}' (no permission)."
-                              .format(apiName))
-                for apiName in glob.glob(os.path.join(eric7SourceDir, "APIs",
-                                                      "MicroPython", "*.bas")):
-                    if os.path.exists(os.path.join(
-                        apidir, os.path.basename(
-                            apiName.replace(".bas", ".api")))):
+                        print(
+                            "Could not install '{0}' (no permission).".format(apiName)
+                        )
+                for apiName in glob.glob(
+                    os.path.join(eric7SourceDir, "APIs", "MicroPython", "*.bas")
+                ):
+                    if os.path.exists(
+                        os.path.join(
+                            apidir, os.path.basename(apiName.replace(".bas", ".api"))
+                        )
+                    ):
                         try:
                             shutilCopy(apiName, apidir)
                         except OSError:
-                            print("Could not install '{0}' (no permission)."
-                                  .format(apiName))
-    
+                            print(
+                                "Could not install '{0}' (no permission).".format(
+                                    apiName
+                                )
+                            )
+
     # Create menu entry for Linux systems
     if sys.platform.startswith("linux"):
         createLinuxSpecifics()
-    
+
     # Create Desktop and Start Menu entries for Windows systems
     elif sys.platform.startswith(("win", "cygwin")):
         createWindowsLinks()
-    
+
     # Create a Mac application bundle
     elif sys.platform == "darwin":
-        createMacAppBundle(cfg['ericDir'])
-    
+        createMacAppBundle(cfg["ericDir"])
+
     return 0
 
 
@@ -934,111 +997,139 @@
     Install Linux specific files.
     """
     global distDir, sourceDir
-    
+
     dataSourceDir = os.path.join(eric7SourceDir, "data", "linux")
-    
+
     if distDir:
         dst = os.path.normpath(os.path.join(distDir, "usr/share/icons"))
         if not os.path.exists(dst):
             os.makedirs(dst)
         shutilCopy(
             os.path.join(eric7SourceDir, "pixmaps", "eric_icon.png"),
-            os.path.join(dst, "eric.png"))
+            os.path.join(dst, "eric.png"),
+        )
         shutilCopy(
             os.path.join(eric7SourceDir, "pixmaps", "ericWeb48_icon.png"),
-            os.path.join(dst, "ericWeb.png"))
-        
+            os.path.join(dst, "ericWeb.png"),
+        )
+
         dst = os.path.normpath(
-            os.path.join(distDir, "usr/share/icons/hicolor/48x48/apps"))
+            os.path.join(distDir, "usr/share/icons/hicolor/48x48/apps")
+        )
         if not os.path.exists(dst):
             os.makedirs(dst)
         shutilCopy(
             os.path.join(eric7SourceDir, "pixmaps", "eric48_icon.png"),
-            os.path.join(dst, "eric.png"))
+            os.path.join(dst, "eric.png"),
+        )
         shutilCopy(
             os.path.join(eric7SourceDir, "pixmaps", "ericWeb48_icon.png"),
-            os.path.join(dst, "ericWeb.png"))
-        
-        dst = os.path.normpath(
-            os.path.join(distDir, "usr/share/applications"))
+            os.path.join(dst, "ericWeb.png"),
+        )
+
+        dst = os.path.normpath(os.path.join(distDir, "usr/share/applications"))
         if not os.path.exists(dst):
             os.makedirs(dst)
-        copyDesktopFile(os.path.join(dataSourceDir, "eric7.desktop.in"),
-                        os.path.join(dst, "eric7.desktop"))
+        copyDesktopFile(
+            os.path.join(dataSourceDir, "eric7.desktop.in"),
+            os.path.join(dst, "eric7.desktop"),
+        )
         copyDesktopFile(
             os.path.join(dataSourceDir, "eric7_browser.desktop.in"),
-            os.path.join(dst, "eric7_browser.desktop"))
-        
-        dst = os.path.normpath(
-            os.path.join(distDir, "usr/share/metainfo"))
+            os.path.join(dst, "eric7_browser.desktop"),
+        )
+
+        dst = os.path.normpath(os.path.join(distDir, "usr/share/metainfo"))
         if not os.path.exists(dst):
             os.makedirs(dst)
         copyAppStreamFile(
             os.path.join(dataSourceDir, "eric7.appdata.xml.in"),
-            os.path.join(dst, "eric7.appdata.xml"))
+            os.path.join(dst, "eric7.appdata.xml"),
+        )
     elif os.getuid() == 0:
         shutilCopy(
             os.path.join(eric7SourceDir, "pixmaps", "eric_icon.png"),
-            "/usr/share/icons/eric.png")
+            "/usr/share/icons/eric.png",
+        )
         shutilCopy(
             os.path.join(eric7SourceDir, "pixmaps", "eric48_icon.png"),
-            "/usr/share/icons/hicolor/48x48/apps/eric.png")
+            "/usr/share/icons/hicolor/48x48/apps/eric.png",
+        )
         copyDesktopFile(
             os.path.join(dataSourceDir, "eric7.desktop.in"),
-            "/usr/share/applications/eric7.desktop")
+            "/usr/share/applications/eric7.desktop",
+        )
         if os.path.exists("/usr/share/metainfo"):
             copyAppStreamFile(
                 os.path.join(dataSourceDir, "eric7.appdata.xml.in"),
-                "/usr/share/metainfo/eric7.appdata.xml")
+                "/usr/share/metainfo/eric7.appdata.xml",
+            )
         elif os.path.exists("/usr/share/appdata"):
             copyAppStreamFile(
                 os.path.join(dataSourceDir, "eric7.appdata.xml.in"),
-                "/usr/share/appdata/eric7.appdata.xml")
+                "/usr/share/appdata/eric7.appdata.xml",
+            )
         shutilCopy(
             os.path.join(eric7SourceDir, "pixmaps", "ericWeb48_icon.png"),
-            "/usr/share/icons/ericWeb.png")
+            "/usr/share/icons/ericWeb.png",
+        )
         shutilCopy(
             os.path.join(eric7SourceDir, "pixmaps", "ericWeb48_icon.png"),
-            "/usr/share/icons/hicolor/48x48/apps/ericWeb.png")
+            "/usr/share/icons/hicolor/48x48/apps/ericWeb.png",
+        )
         copyDesktopFile(
             os.path.join(dataSourceDir, "eric7_browser.desktop.in"),
-            "/usr/share/applications/eric7_browser.desktop")
+            "/usr/share/applications/eric7_browser.desktop",
+        )
     elif os.getuid() >= 1000:
         # it is assumed, that user ids start at 1000
-        localPath = os.path.join(os.path.expanduser("~"),
-                                 ".local", "share")
+        localPath = os.path.join(os.path.expanduser("~"), ".local", "share")
         # create directories first
-        for directory in [os.path.join(localPath, name)
-                          for name in ("icons", "icons/hicolor/48x48/apps",
-                                       "applications", "metainfo", "appdata")]:
+        for directory in [
+            os.path.join(localPath, name)
+            for name in (
+                "icons",
+                "icons/hicolor/48x48/apps",
+                "applications",
+                "metainfo",
+                "appdata",
+            )
+        ]:
             if not os.path.isdir(directory):
                 os.makedirs(directory)
         # now copy the files
         shutilCopy(
             os.path.join(eric7SourceDir, "pixmaps", "eric_icon.png"),
-            os.path.join(localPath, "icons", "eric.png"))
+            os.path.join(localPath, "icons", "eric.png"),
+        )
         shutilCopy(
             os.path.join(eric7SourceDir, "pixmaps", "eric48_icon.png"),
-            os.path.join(localPath, "icons/hicolor/48x48/apps", "eric.png"))
+            os.path.join(localPath, "icons/hicolor/48x48/apps", "eric.png"),
+        )
         copyDesktopFile(
             os.path.join(dataSourceDir, "eric7.desktop.in"),
-            os.path.join(localPath, "applications", "eric7.desktop"))
-        copyAppStreamFile(
-            os.path.join(dataSourceDir, "eric7.appdata.xml.in"),
-            os.path.join(localPath, "metainfo", "eric7.appdata.xml"))
+            os.path.join(localPath, "applications", "eric7.desktop"),
+        )
         copyAppStreamFile(
             os.path.join(dataSourceDir, "eric7.appdata.xml.in"),
-            os.path.join(localPath, "appdata", "eric7.appdata.xml"))
-        shutilCopy(
-            os.path.join(eric7SourceDir, "pixmaps", "ericWeb48_icon.png"),
-            os.path.join(localPath, "icons", "ericWeb.png"))
+            os.path.join(localPath, "metainfo", "eric7.appdata.xml"),
+        )
+        copyAppStreamFile(
+            os.path.join(dataSourceDir, "eric7.appdata.xml.in"),
+            os.path.join(localPath, "appdata", "eric7.appdata.xml"),
+        )
         shutilCopy(
             os.path.join(eric7SourceDir, "pixmaps", "ericWeb48_icon.png"),
-            os.path.join(localPath, "icons/hicolor/48x48/apps", "ericWeb.png"))
+            os.path.join(localPath, "icons", "ericWeb.png"),
+        )
+        shutilCopy(
+            os.path.join(eric7SourceDir, "pixmaps", "ericWeb48_icon.png"),
+            os.path.join(localPath, "icons/hicolor/48x48/apps", "ericWeb.png"),
+        )
         copyDesktopFile(
             os.path.join(dataSourceDir, "eric7_browser.desktop.in"),
-            os.path.join(localPath, "applications",
-                         "eric7_browser.desktop"))
+            os.path.join(localPath, "applications", "eric7_browser.desktop"),
+        )
 
 
 def createWindowsLinks():
@@ -1047,34 +1138,33 @@
     """
     try:
         # check, if pywin32 is available
-        from win32com.client import Dispatch    # __IGNORE_WARNING__
+        from win32com.client import Dispatch  # __IGNORE_WARNING__
     except ImportError:
         installed = pipInstall(
             "pywin32",
             "\nThe Python package 'pywin32' could not be imported.",
-            force=False
+            force=False,
         )
         if installed:
             # create the links via an external script to get around some
             # startup magic done by pywin32.pth
             args = [
                 sys.executable,
-                os.path.join(os.path.dirname(__file__),
-                             "create_windows_links.py"),
+                os.path.join(os.path.dirname(__file__), "create_windows_links.py"),
             ]
-            subprocess.run(args)                # secok
+            subprocess.run(args)  # secok
         else:
             print(
                 "\nThe Python package 'pywin32' is not installed. Desktop and"
                 " Start Menu entries will not be created."
             )
         return
-    
+
     regPath = (
-        "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer" +
-        "\\User Shell Folders"
+        "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"
+        + "\\User Shell Folders"
     )
-    
+
     # 1. create desktop shortcuts
     regName = "Desktop"
     desktopEntry = getWinregEntry(regName, regPath)
@@ -1083,7 +1173,7 @@
         for linkName, targetPath, iconPath in windowsDesktopEntries():
             linkPath = os.path.join(desktopFolder, linkName)
             createWindowsShortcut(linkPath, targetPath, iconPath)
-    
+
     # 2. create start menu entry and shortcuts
     regName = "Programs"
     programsEntry = getWinregEntry(regName, regPath)
@@ -1096,7 +1186,7 @@
             except OSError:
                 # maybe restrictions prohibited link creation
                 return
-        
+
         for linkName, targetPath, iconPath in windowsDesktopEntries():
             linkPath = os.path.join(eric7EntryPath, linkName)
             createWindowsShortcut(linkPath, targetPath, iconPath)
@@ -1111,38 +1201,35 @@
     @type str
     """
     global cfg, macAppBundleName, macPythonExe, macAppBundlePath
-    
+
     directories = {
-        "contents": "{0}/{1}/Contents/".format(
-            macAppBundlePath, macAppBundleName),
-        "exe": "{0}/{1}/Contents/MacOS".format(
-            macAppBundlePath, macAppBundleName),
-        "icns": "{0}/{1}/Contents/Resources".format(
-            macAppBundlePath, macAppBundleName)
+        "contents": "{0}/{1}/Contents/".format(macAppBundlePath, macAppBundleName),
+        "exe": "{0}/{1}/Contents/MacOS".format(macAppBundlePath, macAppBundleName),
+        "icns": "{0}/{1}/Contents/Resources".format(macAppBundlePath, macAppBundleName),
     }
     for directory in directories.values():
         if not os.path.exists(directory):
             os.makedirs(directory)
-    
+
     if macPythonExe == defaultMacPythonExe and macPythonExe:
         starter = os.path.join(directories["exe"], "eric")
         os.symlink(macPythonExe, starter)
     else:
         starter = "python{0}".format(sys.version_info.major)
-    
+
     wname = os.path.join(directories["exe"], "eric7")
-    
+
     # determine entry for DYLD_FRAMEWORK_PATH
     dyldLine = ""
     try:
         from PyQt6.QtCore import QLibraryInfo
-        qtLibraryDir = QLibraryInfo.path(
-            QLibraryInfo.LibraryPath.LibrariesPath)
+
+        qtLibraryDir = QLibraryInfo.path(QLibraryInfo.LibraryPath.LibrariesPath)
     except ImportError:
         qtLibraryDir = ""
     if qtLibraryDir:
         dyldLine = "DYLD_FRAMEWORK_PATH={0}\n".format(qtLibraryDir)
-    
+
     # determine entry for PATH
     pathLine = ""
     path = os.getenv("PATH", "")
@@ -1154,20 +1241,25 @@
             if path_ and path_ not in pathlist_n:
                 pathlist_n.append(path_)
         pathLine = "PATH={0}\n".format(os.pathsep.join(pathlist_n))
-    
+
     # create the wrapper script
-    wrapper = ('''#!/bin/sh\n'''
-               '''\n'''
-               '''{0}'''
-               '''{1}'''
-               '''exec "{2}" "{3}/{4}.py" "$@"\n'''
-               .format(pathLine, dyldLine, starter, pydir, "eric7"))
+    wrapper = (
+        """#!/bin/sh\n"""
+        """\n"""
+        """{0}"""
+        """{1}"""
+        """exec "{2}" "{3}/{4}.py" "$@"\n""".format(
+            pathLine, dyldLine, starter, pydir, "eric7"
+        )
+    )
     copyToFile(wname, wrapper)
-    os.chmod(wname, 0o755)                  # secok
-    
-    shutilCopy(os.path.join(eric7SourceDir, "pixmaps", "eric_2.icns"),
-               os.path.join(directories["icns"], "eric.icns"))
-    
+    os.chmod(wname, 0o755)  # secok
+
+    shutilCopy(
+        os.path.join(eric7SourceDir, "pixmaps", "eric_2.icns"),
+        os.path.join(directories["icns"], "eric.icns"),
+    )
+
     if os.path.exists(os.path.join("eric", "eric7", "UI", "Info.py")):
         # Installing from archive
         from eric.eric7.UI.Info import Version, CopyrightShort
@@ -1177,50 +1269,52 @@
     else:
         Version = "Unknown"
         CopyrightShort = "(c) 2002 - 2022 Detlev Offenbach"
-    
+
     copyToFile(
         os.path.join(directories["contents"], "Info.plist"),
-        '''<?xml version="1.0" encoding="UTF-8"?>\n'''
-        '''<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"\n'''
-        '''          "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n'''
-        '''<plist version="1.0">\n'''
-        '''<dict>\n'''
-        '''    <key>CFBundleExecutable</key>\n'''
-        '''    <string>eric7</string>\n'''
-        '''    <key>CFBundleIconFile</key>\n'''
-        '''    <string>eric.icns</string>\n'''
-        '''    <key>CFBundleInfoDictionaryVersion</key>\n'''
-        '''    <string>{1}</string>\n'''
-        '''    <key>CFBundleName</key>\n'''
-        '''    <string>{0}</string>\n'''
-        '''    <key>CFBundleDisplayName</key>\n'''
-        '''    <string>{0}</string>\n'''
-        '''    <key>CFBundlePackageType</key>\n'''
-        '''    <string>APPL</string>\n'''
-        '''    <key>CFBundleSignature</key>\n'''
-        '''    <string>ERIC-IDE</string>\n'''
-        '''    <key>CFBundleVersion</key>\n'''
-        '''    <string>{1}</string>\n'''
-        '''    <key>CFBundleGetInfoString</key>\n'''
-        '''    <string>{1}, {2}</string>\n'''
-        '''    <key>CFBundleIdentifier</key>\n'''
-        '''    <string>org.python-projects.eric-ide</string>\n'''
-        '''    <key>NSRequiresAquaSystemAppearance</key>\n'''
-        '''    <string>false</string>\n'''
-        '''    <key>LSEnvironment</key>\n'''
-        '''    <dict>\n'''
-        '''        <key>LANG</key>\n'''
-        '''        <string>en_US.UTF-8</string>\n'''
-        '''        <key>LC_ALL</key>\n'''
-        '''        <string>en_US.UTF-8</string>\n'''
-        '''        <key>LC_CTYPE</key>\n'''
-        '''        <string>en_US.UTF-8</string>\n'''
-        '''    </dict>\n'''
-        '''</dict>\n'''
-        '''</plist>\n'''.format(
+        """<?xml version="1.0" encoding="UTF-8"?>\n"""
+        """<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"\n"""
+        """          "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n"""
+        """<plist version="1.0">\n"""
+        """<dict>\n"""
+        """    <key>CFBundleExecutable</key>\n"""
+        """    <string>eric7</string>\n"""
+        """    <key>CFBundleIconFile</key>\n"""
+        """    <string>eric.icns</string>\n"""
+        """    <key>CFBundleInfoDictionaryVersion</key>\n"""
+        """    <string>{1}</string>\n"""
+        """    <key>CFBundleName</key>\n"""
+        """    <string>{0}</string>\n"""
+        """    <key>CFBundleDisplayName</key>\n"""
+        """    <string>{0}</string>\n"""
+        """    <key>CFBundlePackageType</key>\n"""
+        """    <string>APPL</string>\n"""
+        """    <key>CFBundleSignature</key>\n"""
+        """    <string>ERIC-IDE</string>\n"""
+        """    <key>CFBundleVersion</key>\n"""
+        """    <string>{1}</string>\n"""
+        """    <key>CFBundleGetInfoString</key>\n"""
+        """    <string>{1}, {2}</string>\n"""
+        """    <key>CFBundleIdentifier</key>\n"""
+        """    <string>org.python-projects.eric-ide</string>\n"""
+        """    <key>NSRequiresAquaSystemAppearance</key>\n"""
+        """    <string>false</string>\n"""
+        """    <key>LSEnvironment</key>\n"""
+        """    <dict>\n"""
+        """        <key>LANG</key>\n"""
+        """        <string>en_US.UTF-8</string>\n"""
+        """        <key>LC_ALL</key>\n"""
+        """        <string>en_US.UTF-8</string>\n"""
+        """        <key>LC_CTYPE</key>\n"""
+        """        <string>en_US.UTF-8</string>\n"""
+        """    </dict>\n"""
+        """</dict>\n"""
+        """</plist>\n""".format(
             macAppBundleName.replace(".app", ""),
             Version.split(None, 1)[0],
-            CopyrightShort))
+            CopyrightShort,
+        ),
+    )
 
 
 def createInstallConfig():
@@ -1228,67 +1322,72 @@
     Create the installation config dictionary.
     """
     global modDir, platBinDir, cfg, apisDir, installApis
-        
+
     ericdir = os.path.join(modDir, "eric7")
     cfg = {
-        'ericDir': ericdir,
-        'ericPixDir': os.path.join(ericdir, "pixmaps"),
-        'ericIconDir': os.path.join(ericdir, "icons"),
-        'ericDTDDir': os.path.join(ericdir, "DTDs"),
-        'ericCSSDir': os.path.join(ericdir, "CSSs"),
-        'ericStylesDir': os.path.join(ericdir, "Styles"),
-        'ericThemesDir': os.path.join(ericdir, "Themes"),
-        'ericDocDir': os.path.join(ericdir, "Documentation"),
-        'ericExamplesDir': os.path.join(ericdir, "Examples"),
-        'ericTranslationsDir': os.path.join(ericdir, "i18n"),
-        'ericTemplatesDir': os.path.join(ericdir, "DesignerTemplates"),
-        'ericCodeTemplatesDir': os.path.join(ericdir, 'CodeTemplates'),
-        'ericOthersDir': ericdir,
-        'bindir': platBinDir,
-        'mdir': modDir,
+        "ericDir": ericdir,
+        "ericPixDir": os.path.join(ericdir, "pixmaps"),
+        "ericIconDir": os.path.join(ericdir, "icons"),
+        "ericDTDDir": os.path.join(ericdir, "DTDs"),
+        "ericCSSDir": os.path.join(ericdir, "CSSs"),
+        "ericStylesDir": os.path.join(ericdir, "Styles"),
+        "ericThemesDir": os.path.join(ericdir, "Themes"),
+        "ericDocDir": os.path.join(ericdir, "Documentation"),
+        "ericExamplesDir": os.path.join(ericdir, "Examples"),
+        "ericTranslationsDir": os.path.join(ericdir, "i18n"),
+        "ericTemplatesDir": os.path.join(ericdir, "DesignerTemplates"),
+        "ericCodeTemplatesDir": os.path.join(ericdir, "CodeTemplates"),
+        "ericOthersDir": ericdir,
+        "bindir": platBinDir,
+        "mdir": modDir,
     }
     if installApis:
         if apisDir:
-            cfg['apidir'] = apisDir
+            cfg["apidir"] = apisDir
         else:
-            cfg['apidir'] = os.path.join(ericdir, "api")
+            cfg["apidir"] = os.path.join(ericdir, "api")
     else:
-        cfg['apidir'] = ""
+        cfg["apidir"] = ""
+
+
 configLength = 16
-    
+
 
 def createConfig():
     """
     Create a config file with the respective config entries.
     """
     global cfg, macAppBundlePath, configName
-    
+
     apis = []
     if installApis:
         for progLanguage in progLanguages:
             for apiName in sorted(
-                glob.glob(os.path.join(eric7SourceDir, "APIs", progLanguage,
-                                       "*.api"))):
+                glob.glob(os.path.join(eric7SourceDir, "APIs", progLanguage, "*.api"))
+            ):
                 apis.append(os.path.basename(apiName))
             if progLanguage == "Python":
                 # treat Python3 API files the same as Python API files
                 for apiName in sorted(
-                    glob.glob(os.path.join(eric7SourceDir, "APIs", "Python3",
-                                           "*.api"))):
+                    glob.glob(os.path.join(eric7SourceDir, "APIs", "Python3", "*.api"))
+                ):
                     apis.append(os.path.basename(apiName))
-                
+
                 # treat MicroPython API files the same as Python API files
                 for apiName in sorted(
-                    glob.glob(os.path.join(eric7SourceDir, "APIs",
-                                           "MicroPython", "*.api"))):
+                    glob.glob(
+                        os.path.join(eric7SourceDir, "APIs", "MicroPython", "*.api")
+                    )
+                ):
                     apis.append(os.path.basename(apiName))
-    
+
     macConfig = (
-        ("""    'macAppBundlePath': r'{0}',\n"""
-         """    'macAppBundleName': r'{1}',\n""").format(macAppBundlePath,
-                                                         macAppBundleName)
-        if sys.platform == "darwin" else
-        ""
+        (
+            """    'macAppBundlePath': r'{0}',\n"""
+            """    'macAppBundleName': r'{1}',\n"""
+        ).format(macAppBundlePath, macAppBundleName)
+        if sys.platform == "darwin"
+        else ""
     )
     config = (
         """# -*- coding: utf-8 -*-\n"""
@@ -1336,14 +1435,23 @@
         """        '"{{0}}" is not a valid configuration value'"""
         """.format(name))\n"""
     ).format(
-        cfg['ericDir'], cfg['ericPixDir'], cfg['ericIconDir'],
-        cfg['ericDTDDir'], cfg['ericCSSDir'],
-        cfg['ericStylesDir'], cfg['ericThemesDir'], cfg['ericDocDir'],
-        cfg['ericExamplesDir'], cfg['ericTranslationsDir'],
-        cfg['ericTemplatesDir'],
-        cfg['ericCodeTemplatesDir'], cfg['ericOthersDir'],
-        cfg['bindir'], cfg['mdir'],
-        cfg['apidir'], sorted(apis),
+        cfg["ericDir"],
+        cfg["ericPixDir"],
+        cfg["ericIconDir"],
+        cfg["ericDTDDir"],
+        cfg["ericCSSDir"],
+        cfg["ericStylesDir"],
+        cfg["ericThemesDir"],
+        cfg["ericDocDir"],
+        cfg["ericExamplesDir"],
+        cfg["ericTranslationsDir"],
+        cfg["ericTemplatesDir"],
+        cfg["ericCodeTemplatesDir"],
+        cfg["ericOthersDir"],
+        cfg["bindir"],
+        cfg["mdir"],
+        cfg["apidir"],
+        sorted(apis),
         macConfig,
     )
     copyToFile(configName, config)
@@ -1354,7 +1462,7 @@
     Record information about the way eric was installed.
     """
     global createInstallInfoFile, installInfo, installCwd, cfg
-    
+
     if createInstallInfoFile:
         installDateTime = datetime.datetime.now(tz=None)
         try:
@@ -1367,10 +1475,10 @@
         installInfo["install_cwd"] = installCwd
         installInfo["eric"] = cfg["ericDir"]
         installInfo["virtualenv"] = installInfo["eric"].startswith(
-            os.path.expanduser("~"))
+            os.path.expanduser("~")
+        )
         installInfo["installed"] = True
-        installInfo["installed_on"] = installDateTime.strftime(
-            "%Y-%m-%d %H:%M:%S")
+        installInfo["installed_on"] = installDateTime.strftime("%Y-%m-%d %H:%M:%S")
         installInfo["guessed"] = False
         installInfo["edited"] = False
         installInfo["pip"] = False
@@ -1384,7 +1492,7 @@
 def pipInstall(packageName, message, force=True):
     """
     Install the given package via pip.
-    
+
     @param packageName name of the package to be installed
     @type str
     @param message message to be shown to the user
@@ -1396,50 +1504,64 @@
     @rtype bool
     """
     global yes2All
-    
+
     ok = False
     if yes2All or force:
         answer = "y"
     else:
-        print("{0}\nShall '{1}' be installed using pip? (Y/n)"
-              .format(message, packageName), end=" ")
-        answer = input()                            # secok
+        print(
+            "{0}\nShall '{1}' be installed using pip? (Y/n)".format(
+                message, packageName
+            ),
+            end=" ",
+        )
+        answer = input()  # secok
     if answer in ("", "Y", "y"):
-        exitCode = subprocess.run(                  # secok
-            [sys.executable, "-m", "pip", "install", "--prefer-binary",
-             "--upgrade", packageName]
+        exitCode = subprocess.run(  # secok
+            [
+                sys.executable,
+                "-m",
+                "pip",
+                "install",
+                "--prefer-binary",
+                "--upgrade",
+                packageName,
+            ]
         ).returncode
-        ok = (exitCode == 0)
-    
+        ok = exitCode == 0
+
     return ok
 
 
 def isPipOutdated():
     """
     Check, if pip is outdated.
-    
+
     @return flag indicating an outdated pip
     @rtype bool
     """
     try:
-        pipOut = subprocess.run(          # secok
-            [sys.executable, "-m", "pip", "list", "--outdated",
-             "--format=json"],
-            check=True, capture_output=True, text=True
+        pipOut = subprocess.run(  # secok
+            [sys.executable, "-m", "pip", "list", "--outdated", "--format=json"],
+            check=True,
+            capture_output=True,
+            text=True,
         ).stdout
     except (OSError, subprocess.CalledProcessError):
-        pipOut = "[]"       # default empty list
+        pipOut = "[]"  # default empty list
     try:
         jsonList = json.loads(pipOut)
     except Exception:
         jsonList = []
     for package in jsonList:
         if isinstance(package, dict) and package["name"] == "pip":
-            print("'pip' is outdated (installed {0}, available {1})".format(
-                package["version"], package["latest_version"]
-            ))
+            print(
+                "'pip' is outdated (installed {0}, available {1})".format(
+                    package["version"], package["latest_version"]
+                )
+            )
             return True
-    
+
     return False
 
 
@@ -1448,21 +1570,22 @@
     Update the installed pip package.
     """
     global yes2All
-    
+
     if yes2All:
         answer = "y"
     else:
         print("Shall 'pip' be updated (recommended)? (Y/n)", end=" ")
-        answer = input()            # secok
+        answer = input()  # secok
     if answer in ("", "Y", "y"):
-        subprocess.run(             # secok
-            [sys.executable, "-m", "pip", "install", "--upgrade", "pip"])
+        subprocess.run(  # secok
+            [sys.executable, "-m", "pip", "install", "--upgrade", "pip"]
+        )
 
 
 def versionToStr(version):
     """
     Function to convert a version number into a version string.
-    
+
     @param version version number to convert
     @type int
     @return version string
@@ -1470,9 +1593,9 @@
     """
     parts = []
     while version:
-        parts.append(version & 0xff)
+        parts.append(version & 0xFF)
         version >>= 8
-    return '.'.join(str(p) for p in reversed(parts))
+    return ".".join(str(p) for p in reversed(parts))
 
 
 def doDependancyChecks():
@@ -1480,121 +1603,124 @@
     Perform some dependency checks.
     """
     global verbose
-    
+
     requiredVersions = {
-        "pyqt6": 0x60200,               # v6.2.0
-        "pyqt6-charts": 0x60200,        # v6.2.0
-        "pyqt6-webengine": 0x60200,     # v6.2.0
-        "pyqt6-qscintilla": 0x20d00,    # v2.13.0
-        "sip": 0x60100,                 # v6.1.0
+        "pyqt6": 0x60200,  # v6.2.0
+        "pyqt6-charts": 0x60200,  # v6.2.0
+        "pyqt6-webengine": 0x60200,  # v6.2.0
+        "pyqt6-qscintilla": 0x20D00,  # v2.13.0
+        "sip": 0x60100,  # v6.1.0
     }
-    
+
     try:
         isSudo = os.getuid() == 0 and sys.platform != "darwin"
         # disregard sudo installs on macOS
     except AttributeError:
         isSudo = False
-    
-    print('Checking dependencies')
-    
+
+    print("Checking dependencies")
+
     # update pip first even if we don't need to install anything
     if not isSudo and isPipOutdated():
         updatePip()
         print("\n")
-    
+
     # perform dependency checks
     if sys.version_info < (3, 7, 0) or sys.version_info >= (3, 12, 0):
-        print('Sorry, you must have Python 3.7.0 or higher, but less 3.12.0.')
-        print("Yours is {0}.".format(
-            ".".join(str(v) for v in sys.version_info[:3])
-        ))
+        print("Sorry, you must have Python 3.7.0 or higher, but less 3.12.0.")
+        print("Yours is {0}.".format(".".join(str(v) for v in sys.version_info[:3])))
         exit(5)
-    
+
     try:
-        import xml.etree            # __IGNORE_WARNING__
+        import xml.etree  # __IGNORE_WARNING__
     except ImportError:
-        print('Your Python installation is missing the XML module.')
-        print('Please install it and try again.')
+        print("Your Python installation is missing the XML module.")
+        print("Please install it and try again.")
         exit(5)
-    
+
     try:
         from PyQt6.QtCore import qVersion
     except ImportError as err:
         msg = "'PyQt6' could not be detected.{0}".format(
-            "\nError: {0}".format(err) if verbose else "")
+            "\nError: {0}".format(err) if verbose else ""
+        )
         installed = not isSudo and pipInstall(
-            "PyQt6>={0}".format(versionToStr(requiredVersions["pyqt6"])),
-            msg
+            "PyQt6>={0}".format(versionToStr(requiredVersions["pyqt6"])), msg
         )
         if installed:
             # try to import it again
             try:
                 from PyQt6.QtCore import qVersion
             except ImportError as msg:
-                print('Sorry, please install PyQt6.')
-                print('Error: {0}'.format(msg))
+                print("Sorry, please install PyQt6.")
+                print("Error: {0}".format(msg))
                 exit(1)
         else:
-            print('Sorry, please install PyQt6.')
-            print('Error: {0}'.format(msg))
+            print("Sorry, please install PyQt6.")
+            print("Error: {0}".format(msg))
             exit(1)
     print("Found PyQt6")
-    
+
     try:
         pyuic = "pyuic6"
-        from PyQt6 import uic      # __IGNORE_WARNING__
+        from PyQt6 import uic  # __IGNORE_WARNING__
     except ImportError as err:
         print("Sorry, {0} is not installed.".format(pyuic))
         if verbose:
-            print('Error: {0}'.format(err))
+            print("Error: {0}".format(err))
         exit(1)
     print("Found {0}".format(pyuic))
-    
+
     try:
-        from PyQt6 import QtWebEngineWidgets    # __IGNORE_WARNING__
+        from PyQt6 import QtWebEngineWidgets  # __IGNORE_WARNING__
     except ImportError as err:
         if isSudo:
             print("Optional 'PyQt6-WebEngine' could not be detected.")
         else:
-            msg = (
-                "Optional 'PyQt6-WebEngine' could not be detected.{0}"
-                .format("\nError: {0}".format(err) if verbose else "")
+            msg = "Optional 'PyQt6-WebEngine' could not be detected.{0}".format(
+                "\nError: {0}".format(err) if verbose else ""
             )
             pipInstall(
                 "PyQt6-WebEngine>={0}".format(
-                    versionToStr(requiredVersions["pyqt6-webengine"])),
-                msg
+                    versionToStr(requiredVersions["pyqt6-webengine"])
+                ),
+                msg,
             )
-    
+
     try:
-        from PyQt6 import QtCharts    # __IGNORE_WARNING__
+        from PyQt6 import QtCharts  # __IGNORE_WARNING__
     except ImportError as err:
         if isSudo:
             print("Optional 'PyQt6-Charts' could not be detected.")
         else:
             msg = "Optional 'PyQt6-Charts' could not be detected.{0}".format(
-                "\nError: {0}".format(err) if verbose else "")
+                "\nError: {0}".format(err) if verbose else ""
+            )
             pipInstall(
                 "PyQt6-Charts>={0}".format(
-                    versionToStr(requiredVersions["pyqt6-charts"])),
-                msg
+                    versionToStr(requiredVersions["pyqt6-charts"])
+                ),
+                msg,
             )
     print("Found PyQt6-Charts")
-    
+
     try:
-        from PyQt6 import Qsci      # __IGNORE_WARNING__
+        from PyQt6 import Qsci  # __IGNORE_WARNING__
     except ImportError as err:
         msg = "'PyQt6-QScintilla' could not be detected.{0}".format(
-            "\nError: {0}".format(err) if verbose else "")
+            "\nError: {0}".format(err) if verbose else ""
+        )
         installed = not isSudo and pipInstall(
             "PyQt6-QScintilla>={0}".format(
-                versionToStr(requiredVersions["pyqt6-qscintilla"])),
-            msg
+                versionToStr(requiredVersions["pyqt6-qscintilla"])
+            ),
+            msg,
         )
         if installed:
             # try to import it again
             try:
-                from PyQt6 import Qsci      # __IGNORE_WARNING__
+                from PyQt6 import Qsci  # __IGNORE_WARNING__
+
                 message = None
             except ImportError as msg:
                 message = str(msg)
@@ -1603,13 +1729,18 @@
         if message:
             print("Sorry, please install QScintilla2 and")
             print("its PyQt6 wrapper.")
-            print('Error: {0}'.format(message))
+            print("Error: {0}".format(message))
             exit(1)
     print("Found PyQt6-QScintilla")
-    
+
     impModulesList = [
-        "PyQt6.QtGui", "PyQt6.QtNetwork", "PyQt6.QtPrintSupport",
-        "PyQt6.QtSql", "PyQt6.QtSvg", "PyQt6.QtSvgWidgets", "PyQt6.QtWidgets",
+        "PyQt6.QtGui",
+        "PyQt6.QtNetwork",
+        "PyQt6.QtPrintSupport",
+        "PyQt6.QtSql",
+        "PyQt6.QtSvg",
+        "PyQt6.QtSvgWidgets",
+        "PyQt6.QtWidgets",
     ]
     optionalModulesList = {
         # key is pip project name
@@ -1635,7 +1766,7 @@
     }
     if not ignorePyqt6Tools:
         optionalModulesList["qt6-applications"] = ("qt6_applications", "")
-    
+
     # check mandatory modules
     modulesOK = True
     for impModule in impModulesList:
@@ -1644,13 +1775,13 @@
             __import__(impModule)
             print("Found", name)
         except ImportError as err:
-            print('Sorry, please install {0}.'.format(name))
+            print("Sorry, please install {0}.".format(name))
             if verbose:
-                print('Error: {0}'.format(err))
+                print("Error: {0}".format(err))
             modulesOK = False
     if not modulesOK:
         exit(1)
-    
+
     # check optional modules
     for optPackage in optionalModulesList:
         try:
@@ -1658,18 +1789,13 @@
             print("Found", optPackage)
         except ImportError as err:
             if isSudo:
-                print("Optional '{0}' could not be detected."
-                      .format(optPackage))
+                print("Optional '{0}' could not be detected.".format(optPackage))
             else:
                 msg = "Optional '{0}' could not be detected.{1}".format(
-                    optPackage,
-                    "\nError: {0}".format(err) if verbose else ""
+                    optPackage, "\nError: {0}".format(err) if verbose else ""
                 )
-                pipInstall(
-                    optPackage + optionalModulesList[optPackage][1],
-                    msg
-                )
-    
+                pipInstall(optPackage + optionalModulesList[optPackage][1], msg)
+
     # determine the platform dependent black list
     if sys.platform.startswith(("win", "cygwin")):
         PlatformBlackLists = PlatformsBlackLists["windows"]
@@ -1677,21 +1803,21 @@
         PlatformBlackLists = PlatformsBlackLists["linux"]
     else:
         PlatformBlackLists = PlatformsBlackLists["mac"]
-    
+
     print("\nVersion Information")
     print("-------------------")
-    
+
     print("Python: {0:d}.{1:d}.{2:d}".format(*sys.version_info[:3]))
-    
+
     # check version of Qt
     # ===================
-    qtMajor = int(qVersion().split('.')[0])
-    qtMinor = int(qVersion().split('.')[1])
+    qtMajor = int(qVersion().split(".")[0])
+    qtMinor = int(qVersion().split(".")[1])
     print("Qt6: {0}".format(qVersion().strip()))
     if qtMajor == 6 and qtMinor < 1:
-        print('Sorry, you must have Qt version 6.1.0 or better.')
+        print("Sorry, you must have Qt version 6.1.0 or better.")
         exit(2)
-    
+
     # check version of sip
     # ====================
     with contextlib.suppress(ImportError, AttributeError):
@@ -1701,83 +1827,86 @@
             import sip
         print("sip:", sip.SIP_VERSION_STR.strip())
         # always assume, that snapshots or dev versions are new enough
-        if (
-            "snapshot" not in sip.SIP_VERSION_STR and
-            "dev" not in sip.SIP_VERSION_STR
-        ):
+        if "snapshot" not in sip.SIP_VERSION_STR and "dev" not in sip.SIP_VERSION_STR:
             if sip.SIP_VERSION < requiredVersions["sip"]:
                 print(
-                    'Sorry, you must have sip {0} or higher or'
-                    ' a recent development release.'
-                    .format(versionToStr(requiredVersions["sip"]))
+                    "Sorry, you must have sip {0} or higher or"
+                    " a recent development release.".format(
+                        versionToStr(requiredVersions["sip"])
+                    )
                 )
                 exit(3)
             # check for blacklisted versions
             for vers in BlackLists["sip"] + PlatformBlackLists["sip"]:
                 if vers == sip.SIP_VERSION:
                     print(
-                        'Sorry, sip version {0} is not compatible with eric.'
-                        .format(versionToStr(vers)))
-                    print('Please install another version.')
+                        "Sorry, sip version {0} is not compatible with eric.".format(
+                            versionToStr(vers)
+                        )
+                    )
+                    print("Please install another version.")
                     exit(3)
-    
+
     # check version of PyQt6
     # ======================
     from PyQt6.QtCore import PYQT_VERSION, PYQT_VERSION_STR
+
     print("PyQt6:", PYQT_VERSION_STR.strip())
     # always assume, that snapshots or dev versions are new enough
     if "snapshot" not in PYQT_VERSION_STR and "dev" not in PYQT_VERSION_STR:
         if PYQT_VERSION < requiredVersions["pyqt6"]:
             print(
-                'Sorry, you must have PyQt {0} or better or'
-                ' a recent development release.'
-                .format(versionToStr(requiredVersions["pyqt6"]))
+                "Sorry, you must have PyQt {0} or better or"
+                " a recent development release.".format(
+                    versionToStr(requiredVersions["pyqt6"])
+                )
             )
             exit(4)
         # check for blacklisted versions
         for vers in BlackLists["PyQt6"] + PlatformBlackLists["PyQt6"]:
             if vers == PYQT_VERSION:
-                print('Sorry, PyQt version {0} is not compatible with eric.'
-                      .format(versionToStr(vers)))
-                print('Please install another version.')
+                print(
+                    "Sorry, PyQt version {0} is not compatible with eric.".format(
+                        versionToStr(vers)
+                    )
+                )
+                print("Please install another version.")
                 exit(4)
-    
+
     # check version of QScintilla
     # ===========================
     from PyQt6.Qsci import QSCINTILLA_VERSION, QSCINTILLA_VERSION_STR
+
     print("PyQt6-QScintilla:", QSCINTILLA_VERSION_STR.strip())
     # always assume, that snapshots or dev versions are new enough
-    if (
-        "snapshot" not in QSCINTILLA_VERSION_STR and
-        "dev" not in QSCINTILLA_VERSION_STR
-    ):
+    if "snapshot" not in QSCINTILLA_VERSION_STR and "dev" not in QSCINTILLA_VERSION_STR:
         if QSCINTILLA_VERSION < requiredVersions["pyqt6-qscintilla"]:
             print(
-                'Sorry, you must have PyQt6-QScintilla {0} or higher or'
-                ' a recent development release.'
-                .format(versionToStr(requiredVersions["pyqt6-qscintilla"]))
+                "Sorry, you must have PyQt6-QScintilla {0} or higher or"
+                " a recent development release.".format(
+                    versionToStr(requiredVersions["pyqt6-qscintilla"])
+                )
             )
             exit(5)
         # check for blacklisted versions
-        for vers in (
-            BlackLists["QScintilla2"] +
-            PlatformBlackLists["QScintilla2"]
-        ):
+        for vers in BlackLists["QScintilla2"] + PlatformBlackLists["QScintilla2"]:
             if vers == QSCINTILLA_VERSION:
                 print(
-                    'Sorry, QScintilla2 version {0} is not compatible with'
-                    ' eric.'.format(versionToStr(vers)))
-                print('Please install another version.')
+                    "Sorry, QScintilla2 version {0} is not compatible with"
+                    " eric.".format(versionToStr(vers))
+                )
+                print("Please install another version.")
                 exit(5)
-    
+
     # print version info for additional modules
     with contextlib.suppress(NameError, AttributeError):
         print("PyQt6-Charts:", QtCharts.PYQT_CHART_VERSION_STR)
-    
+
     with contextlib.suppress(ImportError, AttributeError):
         from PyQt6 import QtWebEngineCore
+
         print("PyQt6-WebEngine:", QtWebEngineCore.PYQT_WEBENGINE_VERSION_STR)
-    
+
     print()
     print("All dependencies ok.")
     print()
@@ -1787,7 +1916,7 @@
     """
     Local function to create the Python source file name for the compiled
     .ui file.
-    
+
     @param py_dir suggested name of the directory (string)
     @param py_file suggested name for the compile source file (string)
     @return tuple of directory name (string) and source file name (string)
@@ -1800,30 +1929,30 @@
     Compile the .ui files to Python sources.
     """
     from PyQt6.uic import compileUiDir
+
     compileUiDir(eric7SourceDir, True, __pyName)
 
 
 def prepareInfoFile(fileName):
     """
     Function to prepare an Info.py file when installing from source.
-    
+
     @param fileName name of the Python file containing the info (string)
     """
     if not fileName:
         return
-    
+
     with contextlib.suppress(OSError):
         os.rename(fileName, fileName + ".orig")
     localHg = (
         os.path.join(sys.exec_prefix, "Scripts", "hg.exe")
-        if sys.platform.startswith(("win", "cygwin")) else
-        os.path.join(sys.exec_prefix, "bin", "hg")
+        if sys.platform.startswith(("win", "cygwin"))
+        else os.path.join(sys.exec_prefix, "bin", "hg")
     )
     for hg in (localHg, "hg"):
         with contextlib.suppress(OSError, subprocess.CalledProcessError):
-            hgOut = subprocess.run(                     # secok
-                [hg, "identify", "-i"], check=True,
-                capture_output=True, text=True
+            hgOut = subprocess.run(  # secok
+                [hg, "identify", "-i"], check=True, capture_output=True, text=True
             ).stdout
             if hgOut:
                 break
@@ -1835,9 +1964,8 @@
             hgOut = hgOut[:-1]
         with open(fileName + ".orig", "r", encoding="utf-8") as f:
             text = f.read()
-        text = (
-            text.replace("@@REVISION@@", hgOut)
-            .replace("@@VERSION@@", "rev_" + hgOut)
+        text = text.replace("@@REVISION@@", hgOut).replace(
+            "@@VERSION@@", "rev_" + hgOut
         )
         copyToFile(fileName, text)
     else:
@@ -1847,7 +1975,7 @@
 def getWinregEntry(name, path):
     """
     Function to get an entry from the Windows Registry.
-    
+
     @param name variable name
     @type str
     @param path registry path of the variable
@@ -1859,10 +1987,9 @@
         import winreg
     except ImportError:
         return None
-    
+
     try:
-        registryKey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, path, 0,
-                                     winreg.KEY_READ)
+        registryKey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, path, 0, winreg.KEY_READ)
         value, _ = winreg.QueryValueEx(registryKey, name)
         winreg.CloseKey(registryKey)
         return value
@@ -1873,7 +2000,7 @@
 def createWindowsShortcut(linkPath, targetPath, iconPath):
     """
     Create Windows shortcut.
-    
+
     @param linkPath path of the shortcut file
     @type str
     @param targetPath path the shortcut shall point to
@@ -1883,9 +2010,9 @@
     """
     from win32com.client import Dispatch
     from pywintypes import com_error
-    
+
     with contextlib.suppress(com_error):
-        shell = Dispatch('WScript.Shell')
+        shell = Dispatch("WScript.Shell")
         shortcut = shell.CreateShortCut(linkPath)
         shortcut.Targetpath = targetPath
         shortcut.WorkingDirectory = os.path.dirname(targetPath)
@@ -1896,7 +2023,7 @@
 def windowsDesktopNames():
     """
     Function to generate the link names for the Windows Desktop.
-    
+
     @return list of desktop link names
     @rtype list of str
     """
@@ -1906,33 +2033,36 @@
 def windowsDesktopEntries():
     """
     Function to generate data for the Windows Desktop links.
-    
+
     @return list of tuples containing the desktop link name,
         the link target and the icon target
     @rtype list of tuples of (str, str, str)
     """
     global cfg
-    
+
     majorVersion, minorVersion = sys.version_info[:2]
     entriesTemplates = [
-        ("eric7 (Python {0}.{1}).lnk",
-         os.path.join(cfg["bindir"], "eric7.cmd"),
-         os.path.join(cfg["ericPixDir"], "eric7.ico")),
-        ("eric7 Browser (Python {0}.{1}).lnk",
-         os.path.join(cfg["bindir"], "eric7_browser.cmd"),
-         os.path.join(cfg["ericPixDir"], "ericWeb48.ico")),
+        (
+            "eric7 (Python {0}.{1}).lnk",
+            os.path.join(cfg["bindir"], "eric7.cmd"),
+            os.path.join(cfg["ericPixDir"], "eric7.ico"),
+        ),
+        (
+            "eric7 Browser (Python {0}.{1}).lnk",
+            os.path.join(cfg["bindir"], "eric7_browser.cmd"),
+            os.path.join(cfg["ericPixDir"], "ericWeb48.ico"),
+        ),
     ]
-    
+
     return [
-        (e[0].format(majorVersion, minorVersion), e[1], e[2])
-        for e in entriesTemplates
+        (e[0].format(majorVersion, minorVersion), e[1], e[2]) for e in entriesTemplates
     ]
 
 
 def windowsProgramsEntry():
     """
     Function to generate the name of the Start Menu top entry.
-    
+
     @return name of the Start Menu top entry
     @rtype str
     """
@@ -1957,39 +2087,45 @@
     global createInstallInfoFile, installCwd
     global ignorePyqt6Tools
     global verbose
-    
+
     if sys.version_info < (3, 7, 0) or sys.version_info > (3, 99, 99):
-        print('Sorry, eric requires at least Python 3.7 for running.')
+        print("Sorry, eric requires at least Python 3.7 for running.")
         exit(5)
-    
+
     progName = os.path.basename(argv[0])
-    
+
     installCwd = os.getcwd()
-    
+
     if os.path.dirname(argv[0]):
         os.chdir(os.path.dirname(argv[0]))
-    
+
     initGlobals()
 
     try:
         if sys.platform.startswith(("win", "cygwin")):
             optlist, args = getopt.getopt(
-                argv[1:], "chvxza:b:d:f:",
-                ["help", "no-apis", "no-info", "no-tools", "verbose", "yes"])
+                argv[1:],
+                "chvxza:b:d:f:",
+                ["help", "no-apis", "no-info", "no-tools", "verbose", "yes"],
+            )
         elif sys.platform == "darwin":
             optlist, args = getopt.getopt(
-                argv[1:], "chvxza:b:d:f:i:m:n:p:",
-                ["help", "no-apis", "no-info", "no-tools", "verbose", "yes"])
+                argv[1:],
+                "chvxza:b:d:f:i:m:n:p:",
+                ["help", "no-apis", "no-info", "no-tools", "verbose", "yes"],
+            )
         else:
             optlist, args = getopt.getopt(
-                argv[1:], "chvxza:b:d:f:i:",
-                ["help", "no-apis", "no-info", "no-tools", "verbose", "yes"])
+                argv[1:],
+                "chvxza:b:d:f:i:",
+                ["help", "no-apis", "no-info", "no-tools", "verbose", "yes"],
+            )
     except getopt.GetoptError as err:
         print(err)
         usage()
 
     global platBinDir
-    
+
     depChecks = True
 
     for opt, arg in optlist:
@@ -2012,11 +2148,13 @@
         elif opt == "-f":
             with open(arg) as f:
                 try:
-                    exec(compile(f.read(), arg, 'exec'), globals())
+                    exec(compile(f.read(), arg, "exec"), globals())
                     # secok
                     if len(cfg) != configLength:
-                        print("The configuration dictionary in '{0}' is"
-                              " incorrect. Aborting".format(arg))
+                        print(
+                            "The configuration dictionary in '{0}' is"
+                            " incorrect. Aborting".format(arg)
+                        )
                         exit(6)
                 except Exception:
                     cfg = {}
@@ -2038,47 +2176,47 @@
             createInstallInfoFile = False
         elif opt in ["-v", "--verbose"]:
             verbose = True
-    
+
     infoName = ""
     installFromSource = not os.path.isdir(sourceDir)
-    
+
     # check dependencies
     if depChecks:
         doDependancyChecks()
-    
+
     if installFromSource:
         sourceDir = os.path.abspath("..")
-    
+
     eric7SourceDir = (
         os.path.join(sourceDir, "eric7")
-        if os.path.exists(os.path.join(sourceDir, "eric7")) else
-        os.path.join(sourceDir, "src", "eric7")
+        if os.path.exists(os.path.join(sourceDir, "eric7"))
+        else os.path.join(sourceDir, "src", "eric7")
     )
-    
+
     # cleanup source if installing from source
     if installFromSource:
         print("Cleaning up source ...")
         cleanupSource(eric7SourceDir)
         print()
-        
+
         configName = os.path.join(eric7SourceDir, "eric7config.py")
         if os.path.exists(os.path.join(sourceDir, ".hg")):
             # we are installing from source with repo
             infoName = os.path.join(eric7SourceDir, "UI", "Info.py")
             prepareInfoFile(infoName)
-    
+
     if len(cfg) == 0:
         createInstallConfig()
-    
+
     # get rid of development config file, if it exists
     with contextlib.suppress(OSError):
         if installFromSource:
             os.rename(configName, configName + ".orig")
-            configNameC = configName + 'c'
+            configNameC = configName + "c"
             if os.path.exists(configNameC):
                 os.remove(configNameC)
         os.remove(configName)
-    
+
     # cleanup old installation
     print("Cleaning up old installation ...")
     try:
@@ -2088,7 +2226,7 @@
             else:
                 cleanUp()
     except OSError as msg:
-        sys.stderr.write('Error: {0}\nTry install as root.\n'.format(msg))
+        sys.stderr.write("Error: {0}\nTry install as root.\n".format(msg))
         exit(7)
 
     # Create a config file and delete the default one
@@ -2096,16 +2234,16 @@
     createConfig()
 
     createInstallInfo()
-    
+
     # Compile .ui files
     print("\nCompiling user interface files ...")
     # step 1: remove old Ui_*.py files
     for root, _, files in os.walk(sourceDir):
-        for file in [f for f in files if fnmatch.fnmatch(f, 'Ui_*.py')]:
+        for file in [f for f in files if fnmatch.fnmatch(f, "Ui_*.py")]:
             os.remove(os.path.join(root, file))
     # step 2: compile the forms
     compileUiFiles()
-    
+
     if doCompile:
         print("\nCompiling source files ...")
         skipRe = re.compile(r"DebugClients[\\/]Python[\\/]")
@@ -2113,48 +2251,50 @@
         if distDir:
             compileall.compile_dir(
                 eric7SourceDir,
-                ddir=os.path.join(distDir, modDir, cfg['ericDir']),
+                ddir=os.path.join(distDir, modDir, cfg["ericDir"]),
                 rx=skipRe,
-                quiet=True)
+                quiet=True,
+            )
             py_compile.compile(
-                configName,
-                dfile=os.path.join(distDir, modDir, "eric7config.py"))
+                configName, dfile=os.path.join(distDir, modDir, "eric7config.py")
+            )
         else:
             compileall.compile_dir(
                 eric7SourceDir,
-                ddir=os.path.join(modDir, cfg['ericDir']),
+                ddir=os.path.join(modDir, cfg["ericDir"]),
                 rx=skipRe,
-                quiet=True)
-            py_compile.compile(configName,
-                               dfile=os.path.join(modDir, "eric7config.py"))
+                quiet=True,
+            )
+            py_compile.compile(configName, dfile=os.path.join(modDir, "eric7config.py"))
         sys.stdout = sys.__stdout__
     print("\nInstalling eric ...")
     res = installEric()
-    
+
     if createInstallInfoFile:
-        with open(os.path.join(cfg["ericDir"],
-                               installInfoName), "w") as installInfoFile:
+        with open(
+            os.path.join(cfg["ericDir"], installInfoName), "w"
+        ) as installInfoFile:
             json.dump(installInfo, installInfoFile, indent=2)
-    
+
     # do some cleanup
     with contextlib.suppress(OSError):
         if installFromSource:
             os.remove(configName)
-            configNameC = configName + 'c'
+            configNameC = configName + "c"
             if os.path.exists(configNameC):
                 os.remove(configNameC)
             os.rename(configName + ".orig", configName)
     with contextlib.suppress(OSError):
         if installFromSource and infoName:
             os.remove(infoName)
-            infoNameC = infoName + 'c'
+            infoNameC = infoName + "c"
             if os.path.exists(infoNameC):
                 os.remove(infoNameC)
             os.rename(infoName + ".orig", infoName)
-    
+
     print("\nInstallation complete.")
     print()
-    
+
     exit(res)
 
 
@@ -2164,9 +2304,11 @@
     except SystemExit:
         raise
     except Exception:
-        print("""An internal error occured.  Please report all the output"""
-              """ of the program,\nincluding the following traceback, to"""
-              """ eric-bugs@eric-ide.python-projects.org.\n""")
+        print(
+            """An internal error occured.  Please report all the output"""
+            """ of the program,\nincluding the following traceback, to"""
+            """ eric-bugs@eric-ide.python-projects.org.\n"""
+        )
         raise
 
 #

eric ide

mercurial