feat(dev): Python 3.14 default development target, drop 3.8 support

This commit is contained in:
BJ Dierkes 2025-11-02 20:27:38 -06:00
parent 7c347abe43
commit dad85d287a
15 changed files with 49 additions and 60 deletions

View File

@ -65,7 +65,7 @@ jobs:
# FIXME ? # FIXME ?
# os: [ubuntu-latest, macos-latest, windows-latest] # os: [ubuntu-latest, macos-latest, windows-latest]
os: [ubuntu-latest] os: [ubuntu-latest]
python-version: ["3.8", "3.9", "3.11", "3.12", "3.13", "pypy3.10"] python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14", "pypy3.10"]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4

View File

@ -12,7 +12,8 @@ Features:
Refactoring: Refactoring:
- None - `[dev]` Python 3.14 Default Development Target
- `[dev]` Remove Support for Python 3.8 (EOL)
Misc: Misc:

View File

@ -1,4 +1,4 @@
FROM python:3.13-alpine FROM python:3.14-alpine
LABEL MAINTAINER="BJ Dierkes <derks@datafolklabs.com>" LABEL MAINTAINER="BJ Dierkes <derks@datafolklabs.com>"
ENV PS1="\[\e[0;33m\]|> cement <| \[\e[1;35m\]\W\[\e[0m\] \[\e[0m\]# " ENV PS1="\[\e[0;33m\]|> cement <| \[\e[1;35m\]\W\[\e[0m\] \[\e[0m\]# "
ENV PATH="${PATH}:/root/.local/bin" ENV PATH="${PATH}:/root/.local/bin"

View File

@ -3,11 +3,11 @@
dev: dev:
docker compose up -d docker compose up -d
docker compose exec cement pdm install docker compose exec cement pdm install
docker compose exec cement-py38 pdm install
docker compose exec cement-py39 pdm install docker compose exec cement-py39 pdm install
docker compose exec cement-py310 pdm install docker compose exec cement-py310 pdm install
docker compose exec cement-py311 pdm install docker compose exec cement-py311 pdm install
docker compose exec cement-py312 pdm install docker compose exec cement-py312 pdm install
docker compose exec cement-py313 pdm install
docker compose exec cement /bin/bash docker compose exec cement /bin/bash
test: comply test: comply

View File

@ -42,7 +42,7 @@ Cement core features include (but are not limited to):
- 100% PEP8 compliance (`ruff`) - 100% PEP8 compliance (`ruff`)
- Type annotation compliance (`mypy`) - Type annotation compliance (`mypy`)
- Extensive API Reference (`sphinx`) - Extensive API Reference (`sphinx`)
- Tested on Python 3.8+ - Tested on Python 3.9+
## Optional Extensions ## Optional Extensions
@ -92,17 +92,17 @@ All execution is done *inside the docker containers*.
**Testing Alternative Versions of Python** **Testing Alternative Versions of Python**
The latest stable version of Python 3 is the default, and target version accessible as the `cement` container within Docker Compose. For testing against alternative versions of python, additional containers are created (ex: `cement-py38`, `cement-py39`, etc). You can access these containers via: The latest stable version of Python 3 is the default, and target version accessible as the `cement` container within Docker Compose. For testing against alternative versions of python, additional containers are created (ex: `cement-py39`, `cement-py310`, etc). You can access these containers via:
``` ```
$ docker-compose ps $ docker-compose ps
Name Command State Ports Name Command State Ports
------------------------------------------------------------------------- -------------------------------------------------------------------------
cement_cement-py38_1 /bin/bash Up
cement_cement-py39_1 /bin/bash Up cement_cement-py39_1 /bin/bash Up
cement_cement-py310_1 /bin/bash Up cement_cement-py310_1 /bin/bash Up
cement_cement-py311_1 /bin/bash Up cement_cement-py311_1 /bin/bash Up
cement_cement-py312_1 /bin/bash Up cement_cement-py312_1 /bin/bash Up
cement_cement-py313_1 /bin/bash Up
cement_cement_1 /bin/bash Up cement_cement_1 /bin/bash Up
cement_memcached_1 docker-entrypoint.sh memcached Up 11211/tcp cement_memcached_1 docker-entrypoint.sh memcached Up 11211/tcp
cement_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp cement_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp

View File

@ -5,7 +5,6 @@ Cement plugin extension module.
from __future__ import annotations from __future__ import annotations
import os import os
import sys import sys
import importlib
import importlib.util import importlib.util
import importlib.machinery import importlib.machinery
import re import re

View File

@ -1,7 +1,7 @@
{ {
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.14.0/.schema/devbox.schema.json", "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.14.0/.schema/devbox.schema.json",
"packages": { "packages": {
"python": "3.13", "python": "3.14",
"pdm": "latest", "pdm": "latest",
"libmemcached": "latest", "libmemcached": "latest",
"zlib": { "zlib": {

View File

@ -212,60 +212,60 @@
} }
} }
}, },
"python@3.13": { "python@3.14": {
"last_modified": "2025-05-16T20:19:48Z", "last_modified": "2025-10-08T01:30:28Z",
"plugin_version": "0.0.4", "plugin_version": "0.0.4",
"resolved": "github:NixOS/nixpkgs/12a55407652e04dcf2309436eb06fef0d3713ef3#python313", "resolved": "github:NixOS/nixpkgs/8b5c9dd8856f0c0cf46cc91f2c21c106a9d42e25#python314",
"source": "devbox-search", "source": "devbox-search",
"version": "3.13.3", "version": "3.14.0",
"systems": { "systems": {
"aarch64-darwin": { "aarch64-darwin": {
"outputs": [ "outputs": [
{ {
"name": "out", "name": "out",
"path": "/nix/store/1a8xg8l3m67hxinxzzcsak9736qm9vsf-python3-3.13.3", "path": "/nix/store/2sqv05h8017f38w5rvppb2f5wbbisnwp-python3-3.14.0",
"default": true "default": true
} }
], ],
"store_path": "/nix/store/1a8xg8l3m67hxinxzzcsak9736qm9vsf-python3-3.13.3" "store_path": "/nix/store/2sqv05h8017f38w5rvppb2f5wbbisnwp-python3-3.14.0"
}, },
"aarch64-linux": { "aarch64-linux": {
"outputs": [ "outputs": [
{ {
"name": "out", "name": "out",
"path": "/nix/store/yy0xvc2rydhrs0h1v8d7r3sql347xzz5-python3-3.13.3", "path": "/nix/store/zlph3shgrkfmrhkxbgmi6qa26gfzl58q-python3-3.14.0",
"default": true "default": true
}, },
{ {
"name": "debug", "name": "debug",
"path": "/nix/store/42bxfqfrh8cwspl7szr0cw8739xv8qlq-python3-3.13.3-debug" "path": "/nix/store/3zmfrpjfpqaxcl68hlg5nfzvx49awjks-python3-3.14.0-debug"
} }
], ],
"store_path": "/nix/store/yy0xvc2rydhrs0h1v8d7r3sql347xzz5-python3-3.13.3" "store_path": "/nix/store/zlph3shgrkfmrhkxbgmi6qa26gfzl58q-python3-3.14.0"
}, },
"x86_64-darwin": { "x86_64-darwin": {
"outputs": [ "outputs": [
{ {
"name": "out", "name": "out",
"path": "/nix/store/gbrigjhghz9v2p0zf9b2fnvs0g0yx7q4-python3-3.13.3", "path": "/nix/store/bq9ss2vlr05zdrhcfmvclm0gsrc7i6xb-python3-3.14.0",
"default": true "default": true
} }
], ],
"store_path": "/nix/store/gbrigjhghz9v2p0zf9b2fnvs0g0yx7q4-python3-3.13.3" "store_path": "/nix/store/bq9ss2vlr05zdrhcfmvclm0gsrc7i6xb-python3-3.14.0"
}, },
"x86_64-linux": { "x86_64-linux": {
"outputs": [ "outputs": [
{ {
"name": "out", "name": "out",
"path": "/nix/store/2mab9iiwhcqwk75qwvp3zv0bvbiaq6cs-python3-3.13.3", "path": "/nix/store/76lchhz5hhik0j5hjy6lwwn3ik0x54aa-python3-3.14.0",
"default": true "default": true
}, },
{ {
"name": "debug", "name": "debug",
"path": "/nix/store/9z6k8ijl2md0y2n95yprbjj4vxbfsi15-python3-3.13.3-debug" "path": "/nix/store/rjm597f2d9bjllyjnv3y20261bwxd108-python3-3.14.0-debug"
} }
], ],
"store_path": "/nix/store/2mab9iiwhcqwk75qwvp3zv0bvbiaq6cs-python3-3.13.3" "store_path": "/nix/store/76lchhz5hhik0j5hjy6lwwn3ik0x54aa-python3-3.14.0"
} }
} }
}, },

View File

@ -53,13 +53,6 @@ services:
- memcached - memcached
- mailpit - mailpit
cement-py38:
<<: *DEFAULTS
image: "cement:dev-py38"
build:
context: .
dockerfile: docker/Dockerfile.dev-py38
cement-py39: cement-py39:
<<: *DEFAULTS <<: *DEFAULTS
image: "cement:dev-py39" image: "cement:dev-py39"
@ -87,3 +80,10 @@ services:
build: build:
context: . context: .
dockerfile: docker/Dockerfile.dev-py312 dockerfile: docker/Dockerfile.dev-py312
cement-py313:
<<: *DEFAULTS
image: "cement:dev-py313"
build:
context: .
dockerfile: docker/Dockerfile.dev-py313

View File

@ -1,6 +1,6 @@
FROM python:3.13-alpine FROM python:3.14-alpine
LABEL MAINTAINER="BJ Dierkes <derks@datafolklabs.com>" LABEL MAINTAINER="BJ Dierkes <derks@datafolklabs.com>"
ENV PS1="\[\e[0;33m\]|> cement-py313 <| \[\e[1;35m\]\W\[\e[0m\] \[\e[0m\]# " ENV PS1="\[\e[0;33m\]|> cement-py314 <| \[\e[1;35m\]\W\[\e[0m\] \[\e[0m\]# "
ENV PATH="${PATH}:/root/.local/bin" ENV PATH="${PATH}:/root/.local/bin"
WORKDIR /src WORKDIR /src

View File

@ -1,4 +1,4 @@
FROM python:3.13-rc-alpine FROM python:3.13-alpine
LABEL MAINTAINER="BJ Dierkes <derks@datafolklabs.com>" LABEL MAINTAINER="BJ Dierkes <derks@datafolklabs.com>"
ENV PS1="\[\e[0;33m\]|> cement-py313 <| \[\e[1;35m\]\W\[\e[0m\] \[\e[0m\]# " ENV PS1="\[\e[0;33m\]|> cement-py313 <| \[\e[1;35m\]\W\[\e[0m\] \[\e[0m\]# "
ENV PATH="${PATH}:/root/.local/bin" ENV PATH="${PATH}:/root/.local/bin"

View File

@ -1,6 +1,6 @@
FROM python:3.8-alpine FROM python:3.14-alpine
LABEL MAINTAINER="BJ Dierkes <derks@datafolklabs.com>" LABEL MAINTAINER="BJ Dierkes <derks@datafolklabs.com>"
ENV PS1="\[\e[0;33m\]|> cement-py38 <| \[\e[1;35m\]\W\[\e[0m\] \[\e[0m\]# " ENV PS1="\[\e[0;33m\]|> cement-py314 <| \[\e[1;35m\]\W\[\e[0m\] \[\e[0m\]# "
ENV PATH="${PATH}:/root/.local/bin" ENV PATH="${PATH}:/root/.local/bin"
WORKDIR /src WORKDIR /src
@ -22,7 +22,7 @@ RUN apk update \
&& ln -sf /usr/bin/vim /usr/bin/vi && ln -sf /usr/bin/vim /usr/bin/vi
RUN pipx install pdm RUN pipx install pdm
COPY . /src COPY . /src
COPY docker/vimrc /root/.vimrc COPY ./docker/vimrc /root/.vimrc
COPY docker/bashrc /root/.bashrc COPY ./docker/bashrc /root/.bashrc
RUN pdm install RUN pdm install
CMD ["/bin/bash"] CMD ["/bin/bash"]

View File

@ -5,10 +5,10 @@
groups = ["default", "alarm", "argparse", "cli", "colorlog", "configparser", "daemon", "dev", "docs", "dummy", "generate", "jinja2", "json", "logging", "memcached", "mustache", "plugin", "print", "redis", "scrub", "smtp", "tabulate", "watchdog", "yaml"] groups = ["default", "alarm", "argparse", "cli", "colorlog", "configparser", "daemon", "dev", "docs", "dummy", "generate", "jinja2", "json", "logging", "memcached", "mustache", "plugin", "print", "redis", "scrub", "smtp", "tabulate", "watchdog", "yaml"]
strategy = ["inherit_metadata"] strategy = ["inherit_metadata"]
lock_version = "4.5.0" lock_version = "4.5.0"
content_hash = "sha256:edb453570d1f7e2dcd14a71e866fa1814be1c5341a716c96164858feae2e3662" content_hash = "sha256:88e91afb3db1d8d71ebff4abd3d4d3e29b3415592657bd9fe104948d542d1ee5"
[[metadata.targets]] [[metadata.targets]]
requires_python = ">=3.8" requires_python = ">=3.9"
[[package]] [[package]]
name = "alabaster" name = "alabaster"
@ -55,7 +55,7 @@ name = "certifi"
version = "2024.2.2" version = "2024.2.2"
requires_python = ">=3.6" requires_python = ">=3.6"
summary = "Python package for providing Mozilla's CA Bundle." summary = "Python package for providing Mozilla's CA Bundle."
groups = ["docs"] groups = ["dev", "docs"]
files = [ files = [
{file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"},
{file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"},
@ -66,7 +66,7 @@ name = "charset-normalizer"
version = "3.3.2" version = "3.3.2"
requires_python = ">=3.7.0" requires_python = ">=3.7.0"
summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
groups = ["docs"] groups = ["dev", "docs"]
files = [ files = [
{file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"},
{file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"},
@ -380,7 +380,7 @@ name = "idna"
version = "3.6" version = "3.6"
requires_python = ">=3.5" requires_python = ">=3.5"
summary = "Internationalized Domain Names in Applications (IDNA)" summary = "Internationalized Domain Names in Applications (IDNA)"
groups = ["docs"] groups = ["dev", "docs"]
files = [ files = [
{file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"},
{file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"},
@ -702,17 +702,6 @@ files = [
{file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"}, {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"},
] ]
[[package]]
name = "pytz"
version = "2024.1"
summary = "World timezone definitions, modern and historical"
groups = ["docs"]
marker = "python_version < \"3.9\""
files = [
{file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"},
{file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"},
]
[[package]] [[package]]
name = "pyyaml" name = "pyyaml"
version = "6.0.3" version = "6.0.3"
@ -814,7 +803,7 @@ name = "requests"
version = "2.31.0" version = "2.31.0"
requires_python = ">=3.7" requires_python = ">=3.7"
summary = "Python HTTP for Humans." summary = "Python HTTP for Humans."
groups = ["docs"] groups = ["dev", "docs"]
dependencies = [ dependencies = [
"certifi>=2017.4.17", "certifi>=2017.4.17",
"charset-normalizer<4,>=2", "charset-normalizer<4,>=2",
@ -1054,7 +1043,7 @@ name = "urllib3"
version = "2.2.1" version = "2.2.1"
requires_python = ">=3.8" requires_python = ">=3.8"
summary = "HTTP library with thread-safe connection pooling, file post, and more." summary = "HTTP library with thread-safe connection pooling, file post, and more."
groups = ["docs"] groups = ["dev", "docs"]
files = [ files = [
{file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"},
{file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"},

View File

@ -16,7 +16,7 @@ classifiers = [
dynamic = ["version", "README"] dynamic = ["version", "README"]
requires-python = ">=3.8" requires-python = ">=3.9"
dependencies = [] dependencies = []
[project.optional-dependencies] [project.optional-dependencies]
@ -69,7 +69,7 @@ precision = 2
[tool.ruff] [tool.ruff]
target-version = "py38" target-version = "py39"
line-length = 100 line-length = 100
indent-width = 4 indent-width = 4
exclude = [ exclude = [
@ -107,7 +107,7 @@ unfixable = []
# ignore_missing_imports = true # ignore_missing_imports = true
[tool.mypy] [tool.mypy]
python_version = "3.8" python_version = "3.9"
disallow_untyped_calls = true disallow_untyped_calls = true
disallow_untyped_defs = true disallow_untyped_defs = true
disallow_any_unimported = false disallow_any_unimported = false

View File

@ -2,7 +2,7 @@
set -e set -e
[ -z "$CEMENT_VERSION" ] && CEMENT_VERSION="3.0" [ -z "$CEMENT_VERSION" ] && CEMENT_VERSION="3.0"
[ -z "$PYTHON_VERSIONS" ] && PYTHON_VERSIONS="3.8 3.9 3.10 3.11 3.12 3.13" [ -z "$PYTHON_VERSIONS" ] && PYTHON_VERSIONS="3.9 3.10 3.11 3.12 3.13 3.14"
function smoke-test { function smoke-test {
pyver=$1 pyver=$1