Repository: spine-tools/Spine-Toolbox (language: python)

Issue:
Drop support for Python 3.8 by the end of October
Python 3.8 will [meet its end-of-life in October 2024](https://peps.python.org/pep-0569/). We should drop the support from Toolbox and related repositories around the same time after which we can start using features available in Python 3.9 in the code. Technically, dropping support for 3.8 means a small change in `pyproject.toml` but we should notify our users that are still on 3.8 in advance so they have time to react. Perhaps a message in the Event log in case Toolbox notices it is running on 3.8 explaining the situation suffices?

Now:
- [x] Add notification for users still on 3.8 about the incoming change

In late October:
- [x] Update `pyproject.toml` and relevant documentation
- [x] Start enjoying the benefits 3.9 gives us


Discussion / hints:
In developer call it was agreed that we will also update to v0.9 since this is kind of breaking change.

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 96add8e90..4e914126f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.1.0/)
 
 ## [Unreleased]
 
+This version of Spine Toolbox requires Python version 3.9 or later.
+
 ### Added
 
 ### Changed
diff --git a/README.md b/README.md
index cef95a683..071e5efea 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 # Spine Toolbox
 Link to the documentation: [https://spine-toolbox.readthedocs.io/en/latest/?badge=latest](https://spine-toolbox.readthedocs.io/en/latest/?badge=latest)
 
-[![Python](https://img.shields.io/badge/python-3.8%20|%203.9%20|%203.10%20|%203.11|%203.12-blue.svg)](https://www.python.org/downloads/release/python-379/)
+[![Python](https://img.shields.io/badge/python-3.9%20|%203.10%20|%203.11%20|%203.12-blue.svg)](https://www.python.org/downloads/release/python-379/)
 [![Documentation Status](https://readthedocs.org/projects/spine-toolbox/badge/?version=latest)](https://spine-toolbox.readthedocs.io/en/latest/?badge=latest)
 [![Test suite](https://github.com/spine-tools/Spine-Toolbox/actions/workflows/test_runner.yml/badge.svg)](https://github.com/spine-tools/Spine-Toolbox/actions/workflows/test_runner.yml)
 [![codecov](https://codecov.io/gh/spine-tools/Spine-Toolbox/branch/master/graph/badge.svg)](https://codecov.io/gh/spine-tools/Spine-Toolbox)
@@ -244,7 +244,7 @@ run it, and follow the instructions to install Spine Toolbox.
 
 ### About requirements
 
-Python 3.8.1 or later is required. Python 3.8.0 is not supported due to problems in DLL loading on Windows.
+Python 3.9 or later is required.
 
 See the files `pyproject.toml` and `requirements.txt` for packages required to run Spine Toolbox.
 (Additional packages needed for development are listed in `dev-requirements.txt`.)
@@ -277,7 +277,7 @@ also [Problems in starting the application](#problems-in-starting-the-applicatio
 
 #### Installation fails
 
-Please make sure you are using Python 3.8.1 or later to install the requirements.
+Please make sure you are using Python 3.9 or later to install the requirements.
 
 #### 'No Python' error when installing with pipx
 
@@ -317,8 +317,6 @@ The required `qtconsole` package from the ***conda-forge*** channel also
 installs `qt` and `PyQt` packages. Since this is a `PySide6` application, those 
 are not needed and there is a chance of conflicts between the packages.
 
-**Note**: Python 3.8.0 is not supported. Use Python 3.8.1 or later.
-
 ## Recorded Webinars showing the use of Spine Tools
 
 ### Spine Toolbox: Data, workflow and scenario management for modelling
diff --git a/pyproject.toml b/pyproject.toml
index e93cd760c..891f76b71 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -11,7 +11,7 @@ classifiers = [
     "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
     "Operating System :: OS Independent",
 ]
-requires-python = ">=3.8.1"
+requires-python = ">=3.9, <3.13"
 dependencies = [
     "PySide6 >= 6.5.0, != 6.5.3, != 6.6.3, != 6.7.0, < 6.8",
     "jupyter_client >=6.0",
diff --git a/spinetoolbox/main.py b/spinetoolbox/main.py
index 75215534b..97ac4acd6 100644
--- a/spinetoolbox/main.py
+++ b/spinetoolbox/main.py
@@ -47,7 +47,6 @@ def main():
     )
     if not pyside6_version_check():
         return 1
-    _add_pywin32_system32_to_path()
     parser = _make_argument_parser()
     args = parser.parse_args()
     if args.execute_only or args.list_items or args.execute_remotely:
@@ -98,14 +97,3 @@ def _make_argument_parser():
     )
     parser.add_argument("--execute-remotely", help="execute remotely", action="append", metavar="SERVER CONFIG FILE")
     return parser
-
-
-def _add_pywin32_system32_to_path():
-    """Adds a directory to PATH on Windows that is required to make pywin32 work
-    on (Conda) Python 3.8. See https://github.com/spine-tools/Spine-Toolbox/issues/1230."""
-    if sys.platform != "win32":
-        return
-    if sys.version_info[0:2] == (3, 8):
-        p = os.path.join(sys.exec_prefix, "Lib", "site-packages", "pywin32_system32")
-        if os.path.exists(p):
-            os.environ["PATH"] = p + ";" + os.environ["PATH"]
diff --git a/spinetoolbox/ui_main.py b/spinetoolbox/ui_main.py
index dfbcec7dd..a89261653 100644
--- a/spinetoolbox/ui_main.py
+++ b/spinetoolbox/ui_main.py
@@ -441,7 +441,7 @@ def init_tasks(self, project_dir_from_args):
         """
         self._display_welcome_message()
         if sys.version_info < (3, 9):
-            self._display_python_38_deprecation_message()
+            self._display_deprecated_python_warning()
         self.init_project(project_dir_from_args)
 
     def _display_welcome_message(self):
@@ -455,12 +455,11 @@ def _display_welcome_message(self):
         welcome_msg = f"Welcome to Spine Toolbox! If you need help, please read the {getting_started_anchor} guide."
         self.msg.emit(welcome_msg)
 
-    def _display_python_38_deprecation_message(self):
-        """Shows Python 3.8 deprecation message in the event log."""
+    def _display_deprecated_python_warning(self):
+        """Shows a warning message in Event log."""
         self.msg_warning.emit("Please upgrade your Python.")
         self.msg_warning.emit(
-            f"Looks like you are running Python {sys.version_info[0]}.{sys.version_info[1]}. "
-            f"Support for <b>Python older than 3.9 </b> will be dropped in September 2024."
+            f"Your Python version {sys.version_info[0]}.{sys.version_info[1]} is unsupported. Expect trouble."
         )
 
     def init_project(self, project_dir):


Test patch:
diff --git a/.github/workflows/test_runner.yml b/.github/workflows/test_runner.yml
index 718aeeff0..3e6f7287b 100644
--- a/.github/workflows/test_runner.yml
+++ b/.github/workflows/test_runner.yml
@@ -17,7 +17,7 @@ jobs:
     strategy:
       fail-fast: true
       matrix:
-        python-version: [3.8, 3.9, "3.10", 3.11, 3.12]
+        python-version: ["3.9", "3.10", "3.11", "3.12"]
         os: [windows-latest, ubuntu-22.04]
     uses: ./.github/workflows/unit_tests.yml
     with:
@@ -29,7 +29,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        python-version: [3.8, 3.9, "3.10", 3.11, 3.12]
+        python-version: ["3.9", "3.10", "3.11", "3.12"]
         os: [windows-latest, ubuntu-22.04]
     uses: ./.github/workflows/execution_tests.yml
     with: