diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b3b907c..3309acd 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -65,7 +65,7 @@ jobs: strategy: fail-fast: true matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.11", "3.12", "3.13", "3.14"] steps: - name: Checkout repository diff --git a/AGENTS.md b/AGENTS.md index da9b34c..3fe40d4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -41,7 +41,7 @@ Do not tell the user you are "done" or that changes are "complete" until all thr - Use ruff for formatting and linting - Configuration is in `pyproject.toml` under `[tool.ruff]` - Line length: 100 characters -- Target Python version: 3.9+ +- Target Python version: 3.11+ --- diff --git a/docs/index.md b/docs/index.md index 89c1654..92309d8 100644 --- a/docs/index.md +++ b/docs/index.md @@ -10,7 +10,7 @@ classes whose constructor arguments describe their state. python -m pip install serializable ``` -Python 3.9 or later is required. +Python 3.11 or later is required. ## Save and reload an object diff --git a/pyproject.toml b/pyproject.toml index 0afcfd6..782479d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,15 +18,13 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", "Typing :: Typed", ] -requires-python = ">=3.9" +requires-python = ">=3.11" dependencies = [ "typechecks>=0.0.2", ] @@ -55,7 +53,7 @@ include = ["serializable*"] serializable = ["py.typed"] [tool.ruff] -target-version = "py39" +target-version = "py311" line-length = 100 src = ["serializable", "tests"] exclude = [ @@ -85,8 +83,8 @@ ignore = [ "B008", # do not perform function calls in argument defaults "B905", # zip() without explicit strict "SIM108", # use ternary operator instead of if-else - "UP007", # use X | Y for type unions (need Python 3.10+) - "UP045", # use X | None for Optional (need Python 3.10+) + "UP007", # retain the established Union annotation style + "UP045", # retain the established Optional annotation style ] [tool.ruff.lint.per-file-ignores] @@ -103,9 +101,7 @@ ignore = [ known-first-party = ["serializable"] [tool.mypy] -# Annotations are never evaluated at runtime (`from __future__ import annotations`), -# so checking them as 3.10 also covers 3.9, which mypy 2 can no longer target. -python_version = "3.10" +python_version = "3.11" [tool.pytest.ini_options] testpaths = ["tests"] diff --git a/serializable/version.py b/serializable/version.py index 156ccc6..ce2b93e 100644 --- a/serializable/version.py +++ b/serializable/version.py @@ -1,4 +1,4 @@ -__version__ = "1.3.1" +__version__ = "1.3.2" def print_version(): diff --git a/tasks/todo.md b/tasks/todo.md new file mode 100644 index 0000000..220e48c --- /dev/null +++ b/tasks/todo.md @@ -0,0 +1,26 @@ +# Python 3.11 support floor (#24) + +## Specification + +Require Python 3.11 or newer without adding an upper bound. Advertise the +tested 3.11–3.14 range, remove 3.9/3.10 from CI, and align Ruff and mypy's +language targets. Keep runtime serialization behavior and dependencies as they +are. Bump the patch version for the release. + +## Plan + +- [x] Read issue, packaging, CI, repository guidance, and existing tests. +- [x] Check plan before implementation: this is a metadata/tooling policy change; + the current test matrix already covers all four retained versions. +- [x] Update metadata, CI, type-check targets, and version. +- [x] Run `./format.sh`, `./lint.sh`, and `./test.sh` in an isolated environment. +- [x] Verify installation metadata and dependency resolution on Python 3.11 and + 3.14; review the diff. +- [ ] Open PR, pass CI, merge, deploy from clean master, and verify publication. + +## Review + +`./format.sh` left all 21 source/test files unchanged. `./lint.sh` passed +Ruff, formatter, and mypy checks. `./test.sh` passed all 100 tests on both +Python 3.11.12 and 3.14.6. Isolated dependency checks passed at both endpoints; +installed metadata reports version 1.3.2 and `Requires-Python: >=3.11`.