Skip to content

Commit 788f73b

Browse files
nstarmanclaude
andauthored
🔥 build: drop Python 3.9, add Python 3.14 support (#53)
* 🔥 build: drop Python 3.9, add Python 3.14 support Python 3.9 is end-of-life. Bump the minimum supported version to 3.10 and extend support up to Python 3.14 across packaging metadata, type/lint tooling, and CI. - requires-python: >=3.9 -> >=3.10 - drop the 3.9 trove classifier, add the 3.14 classifier - mypy python_version, ruff target-version, pylint py-version -> 3.10 - CI test matrix: ["3.9", "3.13"] -> ["3.10", "3.14"] Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ♻️ refactor: drop `from __future__ import annotations` No longer needed now that the minimum supported Python is 3.10. Forward references in `_core.py` (`Comparator`, `OptionalDependencyEnum`) are quoted since they are now evaluated at runtime. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * 👷 ci: don't pull the dev group into lint/test runs The `uv run` steps re-synced the project's default `dev` group (and its heavy `ipykernel` -> `pyzmq` chain) on top of the selective `Install` step, which broke on Python 3.14 / Windows + macOS where pyzmq 26.2.0 has no wheel and fails to build from source. Use `uv run --no-sync` so the steps reuse exactly the environment the preceding `uv sync --no-default-groups --group ...` created. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 370c3ae commit 788f73b

6 files changed

Lines changed: 32 additions & 239 deletions

File tree

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
- name: Install
3030
run: uv sync --no-default-groups --group nox --group lint --locked
3131
- name: Lint
32-
run: uv run --frozen nox -s lint
32+
run: uv run --no-sync nox -s lint
3333

3434
tests:
3535
name: Check Python ${{ matrix.python-version }} on ${{ matrix.runs-on }}
@@ -40,7 +40,7 @@ jobs:
4040
strategy:
4141
fail-fast: false
4242
matrix:
43-
python-version: ["3.9", "3.13"]
43+
python-version: ["3.10", "3.14"]
4444
runs-on: [ubuntu-latest, macos-latest, windows-latest]
4545

4646
steps:
@@ -55,7 +55,7 @@ jobs:
5555

5656
- name: Test package
5757
run: |
58-
uv run --frozen nox -s test -- --cov --cov-report=xml --cov-report=term --durations=20
58+
uv run --no-sync nox -s test -- --cov --cov-report=xml --cov-report=term --durations=20
5959
6060
- name: Upload coverage report
6161
uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0

.python-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.9
1+
3.10

pyproject.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ classifiers = [
1414
"Programming Language :: Python :: 3.11",
1515
"Programming Language :: Python :: 3.12",
1616
"Programming Language :: Python :: 3.13",
17-
"Programming Language :: Python :: 3.9",
17+
"Programming Language :: Python :: 3.14",
1818
"Programming Language :: Python",
1919
"Topic :: Scientific/Engineering",
2020
"Typing :: Typed",
@@ -27,7 +27,7 @@ dynamic = ["version"]
2727
license.file = "LICENSE"
2828
name = "optional_dependencies"
2929
readme = "README.md"
30-
requires-python = ">=3.9"
30+
requires-python = ">=3.10"
3131

3232
[project.urls]
3333
"Bug Tracker" = "https://github.com/GalacticDynamics/optional_dependencies/issues"
@@ -100,7 +100,7 @@ skip = ["uv.lock"]
100100
'^conftest\.py$', # nox test configuration
101101
]
102102
files = ["src"]
103-
python_version = "3.9"
103+
python_version = "3.10"
104104
strict = true
105105
warn_unreachable = true
106106
warn_unused_configs = true
@@ -113,7 +113,7 @@ skip = ["uv.lock"]
113113

114114
[tool.ruff]
115115
src = ["src"]
116-
target-version = "py39"
116+
target-version = "py310"
117117

118118
[tool.ruff.lint]
119119
extend-select = ["ALL"]
@@ -151,6 +151,6 @@ skip = ["uv.lock"]
151151
"missing-module-docstring",
152152
"wrong-import-position",
153153
]
154-
py-version = "3.9"
154+
py-version = "3.10"
155155
reports.output-format = "colorized"
156156
similarities.ignore-imports = "yes"

src/optional_dependencies/_core.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
"""Optional dependencies."""
22

3-
from __future__ import annotations
4-
53
__all__: list[str] = []
64

75
import operator
6+
from collections.abc import Callable
87
from dataclasses import dataclass
98
from enum import Enum
109
from types import MethodType
11-
from typing import Callable, Literal, cast
10+
from typing import Literal, cast
1211

1312
from packaging.utils import canonicalize_name
1413
from packaging.version import Version
@@ -25,9 +24,9 @@ class Comparator:
2524

2625
def __get__(
2726
self,
28-
instance: OptionalDependencyEnum | None,
29-
owner: type[OptionalDependencyEnum] | None,
30-
) -> Comparator | MethodType:
27+
instance: "OptionalDependencyEnum | None",
28+
owner: "type[OptionalDependencyEnum] | None",
29+
) -> "Comparator | MethodType":
3130
"""Get the descriptor.
3231
3332
Parameters
@@ -49,7 +48,7 @@ def __get__(
4948
# Bind the descriptor to the instance
5049
return MethodType(self.__call__, instance)
5150

52-
def __call__(self, enum: OptionalDependencyEnum, other: object) -> bool:
51+
def __call__(self, enum: "OptionalDependencyEnum", other: object) -> bool:
5352
"""Compare two versions.
5453
5554
Returns

src/optional_dependencies/utils.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
"""Optional dependencies."""
22

3-
from __future__ import annotations
4-
53
__all__ = [
64
"InstalledState",
75
"NOT_INSTALLED",

0 commit comments

Comments
 (0)