Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate Python 3.8 #2888

Merged
merged 6 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 5 additions & 23 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ on:
value: ${{ jobs.package.outputs.artifact-basename }}

env:
min_python_version: "3.8"
min_python_version: "3.9"
max_python_version: "3.12"
FORCE_COLOR: "1"

Expand Down Expand Up @@ -75,30 +75,11 @@ jobs:
strategy:
fail-fast: false
matrix:
platform: [ "macos-12", "macos-14", "ubuntu-latest", "windows-latest" ]
python-version: [ "3.8", "3.12", "3.13-dev" ]
platform: [ "macos-latest", "ubuntu-latest", "windows-latest" ]
python-version: [ "3.9", "3.10", "3.11", "3.12", "3.13" ]
include:
- experimental: false
# Test Python 3.9-3.11 on Ubuntu only
- platform: "ubuntu-latest"
python-version: "3.9"
experimental: false
- platform: "ubuntu-latest"
python-version: "3.10"
experimental: false
- platform: "ubuntu-latest"
python-version: "3.11"
experimental: false
# Allow development Python to fail without failing entire job.
- python-version: "3.13-dev"
experimental: true
exclude:
# macos-14 (i.e. arm64) does not support Python 3.8
- platform: "macos-14"
python-version: "3.8"
# Pillow isn't available for Python 3.13 on Windows
- platform: "windows-latest"
python-version: "3.13-dev"

steps:
- name: Checkout
uses: actions/checkout@v4.2.0
Expand All @@ -109,6 +90,7 @@ jobs:
uses: actions/setup-python@v5.2.0
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true

- name: Install Tox
uses: beeware/.github/.github/actions/install-requirement@main
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ repos:
rev: v3.17.0
hooks:
- id: pyupgrade
args: [--py38-plus]
args: [--py39-plus]
- repo: https://github.com/PyCQA/isort
rev: 5.13.2
hooks:
Expand Down
3 changes: 1 addition & 2 deletions android/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ dynamic = ["version", "dependencies"]
name = "toga-android"
description = "An Android backend for the Toga widget toolkit."
readme = "README.rst"
requires-python = ">= 3.8"
requires-python = ">= 3.9"
license.text = "New BSD"
authors = [
{name="Russell Keith-Magee", email="russell@keith-magee.com"},
Expand All @@ -33,7 +33,6 @@ classifiers = [
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
Expand Down
1 change: 1 addition & 0 deletions changes/2888.removal.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Toga no longer supports Python 3.8.
3 changes: 1 addition & 2 deletions cocoa/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ dynamic = ["version", "dependencies"]
name = "toga-cocoa"
description = "A Cocoa (macOS) backend for the Toga widget toolkit."
readme = "README.rst"
requires-python = ">= 3.8"
requires-python = ">= 3.9"
license.text = "New BSD"
authors = [
{name="Russell Keith-Magee", email="russell@keith-magee.com"},
Expand All @@ -34,7 +34,6 @@ classifiers = [
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
Expand Down
3 changes: 2 additions & 1 deletion core/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ install a backend that implements the core Toga API for that platform:
* **iOS** `toga-iOS <https://pypi.org/project/toga-iOS>`__
* **Linux** `toga-gtk <https://pypi.org/project/toga-gtk>`__
* **macOS** `toga-cocoa <https://pypi.org/project/toga-cocoa>`__
* **Textual** `toga-textual <https://pypi.org/project/toga-textual>`__
* **Web** `toga-web <https://pypi.org/project/toga-web>`__
* **Windows** `toga-winforms <https://pypi.org/project/toga-winforms>`__

Minimum requirements
--------------------

Toga requires **Python 3.8** or newer. Python 2 is not supported.
Toga requires **Python 3.9** or newer.

Each backend also has specific requirements and pre-requisites. See the `platform
documentation <https://toga.readthedocs.io/en/latest/reference/platforms.html>`__ for
Expand Down
7 changes: 2 additions & 5 deletions core/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ dynamic = ["version"]
name = "toga-core"
description = "A Python native, OS native GUI toolkit."
readme = "README.rst"
requires-python = ">= 3.8"
requires-python = ">= 3.9"
license.text = "New BSD"
authors = [
{name="Russell Keith-Magee", email="russell@keith-magee.com"},
Expand Down Expand Up @@ -45,7 +45,6 @@ classifiers = [
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
Expand All @@ -69,9 +68,7 @@ dev = [
"coverage[toml] == 7.6.1",
"coverage-conditional-plugin == 0.9.0",
"Pillow == 10.4.0",
# Pre-commit 3.6.0 deprecated support for Python 3.8
"pre-commit == 3.5.0 ; python_version < '3.9'",
"pre-commit == 4.0.0 ; python_version >= '3.9'",
"pre-commit == 4.0.0",
"pytest == 8.3.3",
"pytest-asyncio == 0.24.0",
"pytest-freezer == 0.4.8",
Expand Down
4 changes: 2 additions & 2 deletions core/src/toga/command.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from collections.abc import Iterator
from typing import TYPE_CHECKING, MutableMapping, MutableSet, Protocol
from collections.abc import Iterator, MutableMapping, MutableSet
from typing import TYPE_CHECKING, Protocol

from toga.handlers import simple_handler, wrapped_handler
from toga.icons import Icon
Expand Down
16 changes: 8 additions & 8 deletions core/src/toga/documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import itertools
import sys
from abc import ABC, abstractmethod
from collections.abc import Iterator
from collections.abc import Iterator, Mapping, Sequence
from pathlib import Path
from typing import TYPE_CHECKING, Mapping, Sequence
from typing import TYPE_CHECKING

import toga
from toga import dialogs
Expand Down Expand Up @@ -225,11 +225,11 @@ def __getitem__(self, path_or_index):
return self.elements[path_or_index]

# Look up by path
if sys.version_info < (3, 9): # pragma: no-cover-if-gte-py39
if sys.version_info < (3, 10): # pragma: no-cover-if-gte-py310
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the case that wasn't being caught by the "min + max" testing scheme. Since the problem only exists on Windows, testing 3.8 + 3.12 passed the test; 3.9 was also affected, but wasn't being checked.

# resolve() *should* turn the path into an absolute path;
# but on Windows, with Python 3.8, it doesn't.
# but on Windows, with Python 3.9, it doesn't.
path = Path(path_or_index).absolute().resolve()
else: # pragma: no-cover-if-lt-py39
else: # pragma: no-cover-if-lt-py310
path = Path(path_or_index).resolve()
for item in self.elements:
if item.path == path:
Expand Down Expand Up @@ -320,11 +320,11 @@ def open(self, path: Path | str) -> Document:
match a registered document type.
"""
try:
if sys.version_info < (3, 9): # pragma: no-cover-if-gte-py39
if sys.version_info < (3, 10): # pragma: no-cover-if-gte-py310
# resolve() *should* turn the path into an absolute path;
# but on Windows, with Python 3.8, it doesn't.
# but on Windows, with Python 3.9, it doesn't.
path = Path(path).absolute().resolve()
else: # pragma: no-cover-if-lt-py39
else: # pragma: no-cover-if-lt-py310
path = Path(path).resolve()
document = self.app.documents[path]
document.focus()
Expand Down
3 changes: 1 addition & 2 deletions core/src/toga/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@
import traceback
import warnings
from abc import ABC
from collections.abc import Awaitable, Generator
from typing import (
TYPE_CHECKING,
Any,
Awaitable,
Callable,
Generator,
NoReturn,
Protocol,
TypeVar,
Expand Down
4 changes: 2 additions & 2 deletions core/src/toga/sources/tree_source.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from collections.abc import Iterator
from typing import Iterable, Mapping, TypeVar
from collections.abc import Iterable, Iterator, Mapping
from typing import TypeVar

from .base import Source
from .list_source import Row, _find_item
Expand Down
4 changes: 2 additions & 2 deletions core/src/toga/statusicons.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import sys
from abc import abstractmethod
from collections.abc import Iterator
from typing import TYPE_CHECKING, Mapping, Sequence
from collections.abc import Iterator, Mapping, Sequence
from typing import TYPE_CHECKING

import toga
from toga.command import Command, CommandSet, Group
Expand Down
4 changes: 2 additions & 2 deletions core/src/toga/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import warnings
from builtins import id as identifier
from collections.abc import Coroutine, Iterator
from collections.abc import Coroutine, Iterator, MutableSet
from pathlib import Path
from typing import TYPE_CHECKING, Any, MutableSet, Protocol, TypeVar
from typing import TYPE_CHECKING, Any, Protocol, TypeVar

import toga
from toga import dialogs
Expand Down
3 changes: 1 addition & 2 deletions demo/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ dynamic = ["version", "dependencies"]
name = "toga-demo"
description = "A demonstration of the capabilities of the Toga widget toolkit."
readme = "README.rst"
requires-python = ">= 3.8"
requires-python = ">= 3.9"
license.text = "New BSD"
authors = [
{name="Russell Keith-Magee", email="russell@keith-magee.com"},
Expand Down Expand Up @@ -40,7 +40,6 @@ classifiers = [
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
Expand Down
3 changes: 1 addition & 2 deletions dummy/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ dynamic = ["version", "dependencies"]
name = "toga-dummy"
description = "A dummy testing backend for the Toga widget toolkit."
readme = "README.rst"
requires-python = ">= 3.8"
requires-python = ">= 3.9"
license.text = "New BSD"
authors = [
{name="Russell Keith-Magee", email="russell@keith-magee.com"},
Expand All @@ -32,7 +32,6 @@ classifiers = [
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
Expand Down
3 changes: 1 addition & 2 deletions gtk/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ dynamic = ["version", "dependencies"]
name = "toga-gtk"
description = "A GTK backend for the Toga widget toolkit."
readme = "README.rst"
requires-python = ">= 3.8"
requires-python = ">= 3.9"
license.text = "New BSD"
authors = [
{name="Russell Keith-Magee", email="russell@keith-magee.com"},
Expand All @@ -35,7 +35,6 @@ classifiers = [
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
Expand Down
3 changes: 1 addition & 2 deletions iOS/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ dynamic = ["version", "dependencies"]
name = "toga-iOS"
description = "An iOS backend for the Toga widget toolkit."
readme = "README.rst"
requires-python = ">= 3.8"
requires-python = ">= 3.9"
license.text = "New BSD"
authors = [
{name="Russell Keith-Magee", email="russell@keith-magee.com"},
Expand All @@ -33,7 +33,6 @@ classifiers = [
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
Expand Down
3 changes: 0 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ no-cover-if-lt-py311 = "sys_version_info < (3, 11) and os_environ.get('COVERAGE_
no-cover-if-gte-py311 = "sys_version_info > (3, 11) and os_environ.get('COVERAGE_EXCLUDE_PYTHON_VERSION') != 'disable'"
no-cover-if-lt-py310 = "sys_version_info < (3, 10) and os_environ.get('COVERAGE_EXCLUDE_PYTHON_VERSION') != 'disable'"
no-cover-if-gte-py310 = "sys_version_info > (3, 10) and os_environ.get('COVERAGE_EXCLUDE_PYTHON_VERSION') != 'disable'"
no-cover-if-lt-py39 = "sys_version_info < (3, 9) and os_environ.get('COVERAGE_EXCLUDE_PYTHON_VERSION') != 'disable'"
no-cover-if-gte-py39 = "sys_version_info > (3, 9) and os_environ.get('COVERAGE_EXCLUDE_PYTHON_VERSION') != 'disable'"


[tool.isort]
profile = "black"
Expand Down
3 changes: 1 addition & 2 deletions textual/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ dynamic = ["version", "dependencies"]
name = "toga-textual"
description = "A Textual backend for the Toga widget toolkit."
readme = "README.rst"
requires-python = ">= 3.8"
requires-python = ">= 3.9"
license.text = "New BSD"
authors = [
{name="Russell Keith-Magee", email="russell@keith-magee.com"},
Expand All @@ -34,7 +34,6 @@ classifiers = [
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
Expand Down
3 changes: 1 addition & 2 deletions toga/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ dynamic = ["version", "dependencies"]
name = "toga"
description = "A Python native, OS native GUI toolkit."
readme = "README.rst"
requires-python = ">= 3.8"
requires-python = ">= 3.9"
license.text = "New BSD"
authors = [
{name="Russell Keith-Magee", email="russell@keith-magee.com"},
Expand Down Expand Up @@ -45,7 +45,6 @@ classifiers = [
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
Expand Down
13 changes: 5 additions & 8 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,15 @@ extend-ignore =
E203,

[tox]
# Add Python 3.13 once a wheel for Pillow is available
envlist = py{38,39,310,311,312}-cov,coverage
envlist = py{39,310,311,312,313}-cov,coverage
labels =
test = py-cov,coverage
test38 = py38-cov,coverage38
test39 = py39-cov,coverage39
test310 = py310-cov,coverage310
test311 = py311-cov,coverage311
test312 = py312-cov,coverage312
test313 = py313-cov,coverage313
ci = towncrier-check,docs-lint,pre-commit,py{38,39,310,311,312}-cov,coverage-fail-platform
ci = towncrier-check,docs-lint,pre-commit,py{39,310,311,312,313}-cov,coverage-fail-platform
skip_missing_interpreters = True

[testenv:pre-commit]
Expand All @@ -27,7 +25,7 @@ deps =
commands = pre-commit run --all-files --show-diff-on-failure --color=always

# The leading comma generates the "py" environment
[testenv:py{,38,39,310,311,312,313}{,-cov}]
[testenv:py{,39,310,311,312,313}{,-cov}]
depends = pre-commit
changedir = core
skip_install = True
Expand All @@ -42,14 +40,13 @@ commands =
!cov: python -m pytest {posargs:-vv --color yes}
cov : python -m coverage run -m pytest {posargs:-vv --color yes}

[testenv:coverage{,38,39,310,311,312,313}{,-html}{,-keep}{,-fail}{,-platform}]
depends = pre-commit,py{,38,39,310,311,312,313}{,-cov}
[testenv:coverage{,39,310,311,312,313}{,-html}{,-keep}{,-fail}{,-platform}]
depends = pre-commit,py{,39,310,311,312,313}{,-cov}
changedir = core
skip_install = True
# by default, coverage should run on oldest supported Python for testing platform coverage.
# however, coverage for a particular Python version should match the version used for pytest.
base_python =
coverage38: py38
coverage39: py39
coverage310: py310
coverage311: py311
Expand Down
Loading
Loading