diff --git a/.github/checkgroup.yml b/.github/checkgroup.yml index 9e0a537e70f4d..3c1910c35582f 100644 --- a/.github/checkgroup.yml +++ b/.github/checkgroup.yml @@ -19,21 +19,21 @@ subprojects: - "!*.md" - "!**/*.md" checks: - - "pl-cpu (macOS-13, lightning, 3.8, 2.1, oldest)" + - "pl-cpu (macOS-13, lightning, 3.9, 2.1, oldest)" - "pl-cpu (macOS-14, lightning, 3.10, 2.1)" - "pl-cpu (macOS-14, lightning, 3.10, 2.2)" - "pl-cpu (macOS-14, lightning, 3.10, 2.3)" - - "pl-cpu (ubuntu-20.04, lightning, 3.8, 2.1, oldest)" + - "pl-cpu (ubuntu-20.04, lightning, 3.9, 2.1, oldest)" - "pl-cpu (ubuntu-20.04, lightning, 3.10, 2.1)" - "pl-cpu (ubuntu-20.04, lightning, 3.10, 2.2)" - "pl-cpu (ubuntu-20.04, lightning, 3.10, 2.3)" - - "pl-cpu (windows-2022, lightning, 3.8, 2.1, oldest)" + - "pl-cpu (windows-2022, lightning, 3.9, 2.1, oldest)" - "pl-cpu (windows-2022, lightning, 3.10, 2.1)" - "pl-cpu (windows-2022, lightning, 3.10, 2.2)" - "pl-cpu (windows-2022, lightning, 3.10, 2.3)" - - "pl-cpu (macOS-14, pytorch, 3.8, 2.1)" - - "pl-cpu (ubuntu-20.04, pytorch, 3.8, 2.1)" - - "pl-cpu (windows-2022, pytorch, 3.8, 2.1)" + - "pl-cpu (macOS-14, pytorch, 3.9, 2.1)" + - "pl-cpu (ubuntu-20.04, pytorch, 3.9, 2.1)" + - "pl-cpu (windows-2022, pytorch, 3.9, 2.1)" - "pl-cpu (macOS-12, pytorch, 3.11, 2.1)" - "pl-cpu (ubuntu-22.04, pytorch, 3.11, 2.1)" - "pl-cpu (windows-2022, pytorch, 3.11, 2.1)" @@ -167,21 +167,21 @@ subprojects: - "!*.md" - "!**/*.md" checks: - - "fabric-cpu (macOS-13, lightning, 3.8, 2.1, oldest)" + - "fabric-cpu (macOS-13, lightning, 3.9, 2.1, oldest)" - "fabric-cpu (macOS-14, lightning, 3.11, 2.1)" - "fabric-cpu (macOS-14, lightning, 3.11, 2.2)" - "fabric-cpu (macOS-14, lightning, 3.10, 2.3)" - - "fabric-cpu (ubuntu-20.04, lightning, 3.8, 2.1, oldest)" + - "fabric-cpu (ubuntu-20.04, lightning, 3.9, 2.1, oldest)" - "fabric-cpu (ubuntu-20.04, lightning, 3.11, 2.1)" - "fabric-cpu (ubuntu-20.04, lightning, 3.11, 2.2)" - "fabric-cpu (ubuntu-20.04, lightning, 3.11, 2.3)" - - "fabric-cpu (windows-2022, lightning, 3.8, 2.1, oldest)" + - "fabric-cpu (windows-2022, lightning, 3.9, 2.1, oldest)" - "fabric-cpu (windows-2022, lightning, 3.11, 2.1)" - "fabric-cpu (windows-2022, lightning, 3.11, 2.2)" - "fabric-cpu (windows-2022, lightning, 3.11, 2.3)" - - "fabric-cpu (macOS-14, fabric, 3.8, 2.1)" - - "fabric-cpu (ubuntu-20.04, fabric, 3.8, 2.1)" - - "fabric-cpu (windows-2022, fabric, 3.8, 2.1)" + - "fabric-cpu (macOS-14, fabric, 3.9, 2.1)" + - "fabric-cpu (ubuntu-20.04, fabric, 3.9, 2.1)" + - "fabric-cpu (windows-2022, fabric, 3.9, 2.1)" - "fabric-cpu (macOS-12, fabric, 3.11, 2.1)" - "fabric-cpu (ubuntu-22.04, fabric, 3.11, 2.1)" - "fabric-cpu (windows-2022, fabric, 3.11, 2.1)" @@ -248,27 +248,27 @@ subprojects: - "!*.md" - "!**/*.md" checks: - - "install-pkg (ubuntu-22.04, fabric, 3.8)" + - "install-pkg (ubuntu-22.04, fabric, 3.9)" - "install-pkg (ubuntu-22.04, fabric, 3.11)" - - "install-pkg (ubuntu-22.04, pytorch, 3.8)" + - "install-pkg (ubuntu-22.04, pytorch, 3.9)" - "install-pkg (ubuntu-22.04, pytorch, 3.11)" - - "install-pkg (ubuntu-22.04, lightning, 3.8)" + - "install-pkg (ubuntu-22.04, lightning, 3.9)" - "install-pkg (ubuntu-22.04, lightning, 3.11)" - - "install-pkg (ubuntu-22.04, notset, 3.8)" + - "install-pkg (ubuntu-22.04, notset, 3.9)" - "install-pkg (ubuntu-22.04, notset, 3.11)" - - "install-pkg (macOS-12, fabric, 3.8)" + - "install-pkg (macOS-12, fabric, 3.9)" - "install-pkg (macOS-12, fabric, 3.11)" - - "install-pkg (macOS-12, pytorch, 3.8)" + - "install-pkg (macOS-12, pytorch, 3.9)" - "install-pkg (macOS-12, pytorch, 3.11)" - - "install-pkg (macOS-12, lightning, 3.8)" + - "install-pkg (macOS-12, lightning, 3.9)" - "install-pkg (macOS-12, lightning, 3.11)" - - "install-pkg (macOS-12, notset, 3.8)" + - "install-pkg (macOS-12, notset, 3.9)" - "install-pkg (macOS-12, notset, 3.11)" - - "install-pkg (windows-2022, fabric, 3.8)" + - "install-pkg (windows-2022, fabric, 3.9)" - "install-pkg (windows-2022, fabric, 3.11)" - - "install-pkg (windows-2022, pytorch, 3.8)" + - "install-pkg (windows-2022, pytorch, 3.9)" - "install-pkg (windows-2022, pytorch, 3.11)" - - "install-pkg (windows-2022, lightning, 3.8)" + - "install-pkg (windows-2022, lightning, 3.9)" - "install-pkg (windows-2022, lightning, 3.11)" - - "install-pkg (windows-2022, notset, 3.8)" + - "install-pkg (windows-2022, notset, 3.9)" - "install-pkg (windows-2022, notset, 3.11)" diff --git a/.github/workflows/ci-pkg-install.yml b/.github/workflows/ci-pkg-install.yml index 6e82167410ec3..d22a8d3ace1e2 100644 --- a/.github/workflows/ci-pkg-install.yml +++ b/.github/workflows/ci-pkg-install.yml @@ -44,7 +44,7 @@ jobs: matrix: os: ["ubuntu-22.04", "macOS-12", "windows-2022"] pkg-name: ["fabric", "pytorch", "lightning", "notset"] - python-version: ["3.8", "3.11"] + python-version: ["3.9", "3.11"] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 diff --git a/.github/workflows/ci-tests-fabric.yml b/.github/workflows/ci-tests-fabric.yml index 8d5ed3e9e7fa4..e961de773c939 100644 --- a/.github/workflows/ci-tests-fabric.yml +++ b/.github/workflows/ci-tests-fabric.yml @@ -58,25 +58,25 @@ jobs: - { os: "ubuntu-22.04", pkg-name: "fabric", python-version: "3.11", pytorch-version: "2.1" } - { os: "windows-2022", pkg-name: "fabric", python-version: "3.11", pytorch-version: "2.1" } # "oldest" versions tests, only on minimum Python - - { os: "macOS-13", pkg-name: "lightning", python-version: "3.8", pytorch-version: "2.1", requires: "oldest" } + - { os: "macOS-13", pkg-name: "lightning", python-version: "3.9", pytorch-version: "2.1", requires: "oldest" } - { os: "ubuntu-20.04", pkg-name: "lightning", - python-version: "3.8", + python-version: "3.9", pytorch-version: "2.1", requires: "oldest", } - { os: "windows-2022", pkg-name: "lightning", - python-version: "3.8", + python-version: "3.9", pytorch-version: "2.1", requires: "oldest", } # "fabric" installs the standalone package - - { os: "macOS-14", pkg-name: "fabric", python-version: "3.8", pytorch-version: "2.1" } - - { os: "ubuntu-20.04", pkg-name: "fabric", python-version: "3.8", pytorch-version: "2.1" } - - { os: "windows-2022", pkg-name: "fabric", python-version: "3.8", pytorch-version: "2.1" } + - { os: "macOS-14", pkg-name: "fabric", python-version: "3.9", pytorch-version: "2.1" } + - { os: "ubuntu-20.04", pkg-name: "fabric", python-version: "3.9", pytorch-version: "2.1" } + - { os: "windows-2022", pkg-name: "fabric", python-version: "3.9", pytorch-version: "2.1" } timeout-minutes: 25 # because of building grpcio on Mac env: PACKAGE_NAME: ${{ matrix.pkg-name }} diff --git a/.github/workflows/ci-tests-pytorch.yml b/.github/workflows/ci-tests-pytorch.yml index 6ff9fbf05bf14..86122863216b2 100644 --- a/.github/workflows/ci-tests-pytorch.yml +++ b/.github/workflows/ci-tests-pytorch.yml @@ -61,25 +61,25 @@ jobs: - { os: "ubuntu-22.04", pkg-name: "pytorch", python-version: "3.11", pytorch-version: "2.1" } - { os: "windows-2022", pkg-name: "pytorch", python-version: "3.11", pytorch-version: "2.1" } # "oldest" versions tests, only on minimum Python - - { os: "macOS-13", pkg-name: "lightning", python-version: "3.8", pytorch-version: "2.1", requires: "oldest" } + - { os: "macOS-13", pkg-name: "lightning", python-version: "3.9", pytorch-version: "2.1", requires: "oldest" } - { os: "ubuntu-20.04", pkg-name: "lightning", - python-version: "3.8", + python-version: "3.9", pytorch-version: "2.1", requires: "oldest", } - { os: "windows-2022", pkg-name: "lightning", - python-version: "3.8", + python-version: "3.9", pytorch-version: "2.1", requires: "oldest", } # "pytorch" installs the standalone package - - { os: "macOS-14", pkg-name: "pytorch", python-version: "3.8", pytorch-version: "2.1" } - - { os: "ubuntu-20.04", pkg-name: "pytorch", python-version: "3.8", pytorch-version: "2.1" } - - { os: "windows-2022", pkg-name: "pytorch", python-version: "3.8", pytorch-version: "2.1" } + - { os: "macOS-14", pkg-name: "pytorch", python-version: "3.9", pytorch-version: "2.1" } + - { os: "ubuntu-20.04", pkg-name: "pytorch", python-version: "3.9", pytorch-version: "2.1" } + - { os: "windows-2022", pkg-name: "pytorch", python-version: "3.9", pytorch-version: "2.1" } timeout-minutes: 50 env: PACKAGE_NAME: ${{ matrix.pkg-name }} diff --git a/.github/workflows/release-pkg.yml b/.github/workflows/release-pkg.yml index 968e27e773bfd..a11751c13790e 100644 --- a/.github/workflows/release-pkg.yml +++ b/.github/workflows/release-pkg.yml @@ -24,7 +24,7 @@ defaults: env: FREEZE_REQUIREMENTS: 1 TORCH_URL: "https://download.pytorch.org/whl/cpu/torch_stable.html" - PYTHON_VER: "3.8" + PYTHON_VER: "3.9" jobs: build-packages: diff --git a/src/lightning/__setup__.py b/src/lightning/__setup__.py index 4bc4dff23be50..8d4f21435488e 100644 --- a/src/lightning/__setup__.py +++ b/src/lightning/__setup__.py @@ -93,8 +93,8 @@ def _setup_args() -> Dict[str, Any]: "long_description_content_type": "text/markdown", "include_package_data": True, "zip_safe": False, - "keywords": ["deep learning", "pytorch", "AI"], # todo: aggregate tags from all packages - "python_requires": ">=3.8", # todo: take the lowes based on all packages + "keywords": ["deep learning", "pytorch", "AI"], + "python_requires": ">=3.9", "entry_points": { "console_scripts": [ "fabric = lightning.fabric.cli:_main", diff --git a/src/lightning/fabric/CHANGELOG.md b/src/lightning/fabric/CHANGELOG.md index 985759830769d..993df019fc3bd 100644 --- a/src/lightning/fabric/CHANGELOG.md +++ b/src/lightning/fabric/CHANGELOG.md @@ -30,7 +30,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Removed support for PyTorch 2.1 ([#20009](https://github.com/Lightning-AI/lightning/pull/20009)) -- +- Removed support for Python 3.8 ([#20071](https://github.com/Lightning-AI/lightning/pull/20071)) ### Fixed diff --git a/src/lightning/fabric/utilities/imports.py b/src/lightning/fabric/utilities/imports.py index c8fa1ddf1e083..f180d40d2c4ba 100644 --- a/src/lightning/fabric/utilities/imports.py +++ b/src/lightning/fabric/utilities/imports.py @@ -30,7 +30,6 @@ _TORCH_GREATER_EQUAL_2_3 = compare_version("torch", operator.ge, "2.3.0") _TORCH_GREATER_EQUAL_2_4 = compare_version("torch", operator.ge, "2.4.0") -_PYTHON_GREATER_EQUAL_3_8_0 = (sys.version_info.major, sys.version_info.minor) >= (3, 8) _PYTHON_GREATER_EQUAL_3_10_0 = (sys.version_info.major, sys.version_info.minor) >= (3, 10) _UTILITIES_GREATER_EQUAL_0_10 = compare_version("lightning_utilities", operator.ge, "0.10.0") diff --git a/src/lightning/fabric/utilities/registry.py b/src/lightning/fabric/utilities/registry.py index a3b2ac442b46b..9ad0f90221429 100644 --- a/src/lightning/fabric/utilities/registry.py +++ b/src/lightning/fabric/utilities/registry.py @@ -12,13 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. import logging +from importlib.metadata import entry_points from inspect import getmembers, isclass from types import ModuleType from typing import Any, List, Type, Union from lightning_utilities import is_overridden -from lightning.fabric.utilities.imports import _PYTHON_GREATER_EQUAL_3_8_0, _PYTHON_GREATER_EQUAL_3_10_0 +from lightning.fabric.utilities.imports import _PYTHON_GREATER_EQUAL_3_10_0 _log = logging.getLogger(__name__) @@ -35,16 +36,9 @@ def _load_external_callbacks(group: str) -> List[Any]: A list of all callbacks collected from external factories. """ - if _PYTHON_GREATER_EQUAL_3_8_0: - from importlib.metadata import entry_points - - factories = ( - entry_points(group=group) if _PYTHON_GREATER_EQUAL_3_10_0 else entry_points().get(group, {}) # type: ignore[arg-type] - ) - else: - from pkg_resources import iter_entry_points - - factories = iter_entry_points(group) # type: ignore[assignment] + factories = ( + entry_points(group=group) if _PYTHON_GREATER_EQUAL_3_10_0 else entry_points().get(group, {}) # type: ignore[arg-type] + ) external_callbacks: List[Any] = [] for factory in factories: diff --git a/src/lightning/pytorch/CHANGELOG.md b/src/lightning/pytorch/CHANGELOG.md index 4f8c32bcf8434..d9eea0b147dc2 100644 --- a/src/lightning/pytorch/CHANGELOG.md +++ b/src/lightning/pytorch/CHANGELOG.md @@ -30,7 +30,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Removed support for PyTorch 2.1 ([#20009](https://github.com/Lightning-AI/lightning/pull/20009)) -- +- Removed support for Python 3.8 ([#20071](https://github.com/Lightning-AI/lightning/pull/20071)) + ### Fixed diff --git a/src/lightning/pytorch/trainer/connectors/signal_connector.py b/src/lightning/pytorch/trainer/connectors/signal_connector.py index ca9e3eb249474..05a975326005f 100644 --- a/src/lightning/pytorch/trainer/connectors/signal_connector.py +++ b/src/lightning/pytorch/trainer/connectors/signal_connector.py @@ -9,7 +9,7 @@ import lightning.pytorch as pl from lightning.fabric.plugins.environments import SLURMEnvironment -from lightning.fabric.utilities.imports import _IS_WINDOWS, _PYTHON_GREATER_EQUAL_3_8_0 +from lightning.fabric.utilities.imports import _IS_WINDOWS from lightning.pytorch.utilities.rank_zero import rank_prefixed_message, rank_zero_info # copied from signal.pyi @@ -133,26 +133,8 @@ def _get_current_signal_handlers() -> Dict[_SIGNUM, _HANDLER]: @staticmethod def _valid_signals() -> Set[signal.Signals]: - """Returns all valid signals supported on the current platform. - - Behaves identically to :func:`signals.valid_signals` in Python 3.8+ and implements the equivalent behavior for - older Python versions. - - """ - if _PYTHON_GREATER_EQUAL_3_8_0: - return signal.valid_signals() - if _IS_WINDOWS: - # supported signals on Windows: https://docs.python.org/3/library/signal.html#signal.signal - return { - signal.SIGABRT, - signal.SIGFPE, - signal.SIGILL, - signal.SIGINT, - signal.SIGSEGV, - signal.SIGTERM, - signal.SIGBREAK, - } - return set(signal.Signals) + """Returns all valid signals supported on the current platform.""" + return signal.valid_signals() @staticmethod def _has_already_handler(signum: _SIGNUM) -> bool: diff --git a/tests/tests_fabric/utilities/test_registry.py b/tests/tests_fabric/utilities/test_registry.py index 75e6e12f5abff..a06e5c8e82615 100644 --- a/tests/tests_fabric/utilities/test_registry.py +++ b/tests/tests_fabric/utilities/test_registry.py @@ -1,8 +1,8 @@ import contextlib from unittest import mock -from unittest.mock import Mock +from unittest.mock import MagicMock, Mock -from lightning.fabric.utilities.imports import _PYTHON_GREATER_EQUAL_3_8_0, _PYTHON_GREATER_EQUAL_3_10_0 +from lightning.fabric.utilities.imports import _PYTHON_GREATER_EQUAL_3_10_0 from lightning.fabric.utilities.registry import _load_external_callbacks @@ -47,18 +47,14 @@ def factory_multiple_callbacks_list(): @contextlib.contextmanager def _make_entry_point_query_mock(callback_factory): - query_mock = Mock() + query_mock = MagicMock() entry_point = Mock() entry_point.name = "mocked" entry_point.load.return_value = callback_factory if _PYTHON_GREATER_EQUAL_3_10_0: query_mock.return_value = [entry_point] - import_path = "importlib.metadata.entry_points" - elif _PYTHON_GREATER_EQUAL_3_8_0: - query_mock().get.return_value = [entry_point] - import_path = "importlib.metadata.entry_points" else: - query_mock.return_value = [entry_point] - import_path = "pkg_resources.iter_entry_points" - with mock.patch(import_path, query_mock): + query_mock().get.return_value = [entry_point] + + with mock.patch("lightning.fabric.utilities.registry.entry_points", query_mock): yield diff --git a/tests/tests_pytorch/trainer/connectors/test_callback_connector.py b/tests/tests_pytorch/trainer/connectors/test_callback_connector.py index ac848b68d14ed..eb09413cafcce 100644 --- a/tests/tests_pytorch/trainer/connectors/test_callback_connector.py +++ b/tests/tests_pytorch/trainer/connectors/test_callback_connector.py @@ -14,11 +14,11 @@ import contextlib import logging from unittest import mock -from unittest.mock import Mock +from unittest.mock import MagicMock, Mock import pytest import torch -from lightning.fabric.utilities.imports import _PYTHON_GREATER_EQUAL_3_8_0, _PYTHON_GREATER_EQUAL_3_10_0 +from lightning.fabric.utilities.imports import _PYTHON_GREATER_EQUAL_3_10_0 from lightning.pytorch import Callback, LightningModule, Trainer from lightning.pytorch.callbacks import ( EarlyStopping, @@ -293,20 +293,16 @@ def factory_multiple_callbacks_list(): @contextlib.contextmanager def _make_entry_point_query_mock(callback_factory): - query_mock = Mock() + query_mock = MagicMock() entry_point = Mock() entry_point.name = "mocked" entry_point.load.return_value = callback_factory if _PYTHON_GREATER_EQUAL_3_10_0: query_mock.return_value = [entry_point] - import_path = "importlib.metadata.entry_points" - elif _PYTHON_GREATER_EQUAL_3_8_0: - query_mock().get.return_value = [entry_point] - import_path = "importlib.metadata.entry_points" else: - query_mock.return_value = [entry_point] - import_path = "pkg_resources.iter_entry_points" - with mock.patch(import_path, query_mock): + query_mock().get.return_value = [entry_point] + + with mock.patch("lightning.fabric.utilities.registry.entry_points", query_mock): yield diff --git a/tests/tests_pytorch/trainer/logging_/test_eval_loop_logging.py b/tests/tests_pytorch/trainer/logging_/test_eval_loop_logging.py index f005a41e0d75c..b90d767a23caf 100644 --- a/tests/tests_pytorch/trainer/logging_/test_eval_loop_logging.py +++ b/tests/tests_pytorch/trainer/logging_/test_eval_loop_logging.py @@ -24,7 +24,6 @@ import numpy as np import pytest import torch -from lightning.fabric.utilities.imports import _PYTHON_GREATER_EQUAL_3_8_0 from lightning.pytorch import Trainer, callbacks from lightning.pytorch.callbacks.progress.rich_progress import _RICH_AVAILABLE from lightning.pytorch.demos.boring_classes import BoringModel, RandomDataset @@ -557,8 +556,7 @@ def test_step(self, batch, batch_idx): ] def get_metrics_at_idx(idx): - mock_call = mock_log_metrics.mock_calls[idx] - return mock_call.kwargs["metrics"] if _PYTHON_GREATER_EQUAL_3_8_0 else mock_call[2]["metrics"] + return mock_log_metrics.mock_calls[idx].kwargs["metrics"] assert get_metrics_at_idx(2)["valid_loss_0_step"] == model.val_losses[2] assert get_metrics_at_idx(3)["valid_loss_0_step"] == model.val_losses[3] @@ -736,8 +734,7 @@ def test_dataloader(self): cb_metrics = set(trainer.callback_metrics) assert cb_metrics == {"foo/dataloader_idx_0", "foo/dataloader_idx_1", "foobar"} - mock_call = mock_log_metrics.mock_calls[0] - logged_metrics = mock_call.kwargs["metrics"] if _PYTHON_GREATER_EQUAL_3_8_0 else mock_call[2]["metrics"] + logged_metrics = mock_log_metrics.mock_calls[0].kwargs["metrics"] cb_metrics.add("epoch") assert set(logged_metrics) == cb_metrics