From cfe47d3cb03372635cac202f9cba59c06839f57a Mon Sep 17 00:00:00 2001 From: Vito Date: Mon, 26 Oct 2026 22:23:06 -0700 Subject: [PATCH] ci: support and test Python 3.12-3.14 only (#356) (#357) * ci: test Python 3.11-3.14 and require Python 3.11 (#356) Python 3.10 reaches end of life in October 2026 and no PromptManager users run it; 3.14 is current and was untested. The test matrix runs 3.11-3.14 on Linux, Windows and macOS, bandit runs on 3.11, and requires-python is >=3.11 so the package no longer claims a version CI does not test. The packaging test drops its 3.10-only tomllib fallback. The required checks follow the matrix (py3.10 -> py3.14). * ci: narrow Python support to 3.12-3.14 (#356) ComfyUI recommends 3.13, names 3.12 as the fallback and 3.14 as working (its README); PromptManager supports exactly those. requires-python is >=3.12, the test matrix and the required checks drop 3.11, and bandit runs on 3.12. --- .github/branch-protection.json | 9 +++------ .github/workflows/code-quality.yml | 4 ++-- .github/workflows/test.yml | 3 ++- README.md | 4 ++-- pyproject.toml | 2 +- tests/test_packaging.py | 28 +++++----------------------- 6 files changed, 15 insertions(+), 35 deletions(-) diff --git a/.github/branch-protection.json b/.github/branch-protection.json index adc552b..47797f4 100644 --- a/.github/branch-protection.json +++ b/.github/branch-protection.json @@ -2,18 +2,15 @@ "required_status_checks": { "strict": true, "contexts": [ - "py3.10 on ubuntu-latest", - "py3.11 on ubuntu-latest", "py3.12 on ubuntu-latest", "py3.13 on ubuntu-latest", - "py3.10 on windows-latest", - "py3.11 on windows-latest", + "py3.14 on ubuntu-latest", "py3.12 on windows-latest", "py3.13 on windows-latest", - "py3.10 on macos-latest", - "py3.11 on macos-latest", + "py3.14 on windows-latest", "py3.12 on macos-latest", "py3.13 on macos-latest", + "py3.14 on macos-latest", "coverage gate (85%)", "black and flake8", "frontend modules", diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index b50684f..4b9a9ca 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -26,10 +26,10 @@ jobs: steps: - uses: actions/checkout@v7 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v7 with: - python-version: "3.10" + python-version: "3.12" - name: Install bandit run: pip install bandit[toml] diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2d032ac..b4965c7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,6 +26,7 @@ env: # Measured 2026-10-26 on runs 40257217681 (3be0ada), 40240706568 (fb9134f), 40228167328 (f9835aa): # py matrix, slowest py3.10 on windows-latest: 12m43s / 15m54s / 14m53s -> 27 min # (ubuntu 5m27s-6m27s, macos 6m14s-8m30s, windows 11m42s-15m54s) +# 3.10 and 3.11 left the matrix and 3.14 joined it in #356; re-measure after three green main runs. # real ComfyUI compatibility: 13m32s / 8m55s / 11m46s -> 24 min # coverage gate (85%): 7m26s / 7m22s / 7m54s -> 15 min # perf budget 30s / 29s / 27s, black and flake8 39s / 37s / 39s, @@ -39,7 +40,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] - python-version: ["3.10", "3.11", "3.12", "3.13"] + python-version: ["3.12", "3.13", "3.14"] steps: - uses: actions/checkout@v7 diff --git a/README.md b/README.md index 67a2698..7a918ef 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # ComfyUI Prompt Manager ![License](https://img.shields.io/badge/license-MIT-blue.svg) -![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg) +![Python](https://img.shields.io/badge/python-3.12%2B-blue.svg) ![ComfyUI](https://img.shields.io/badge/ComfyUI-compatible-green.svg) ![Tests](https://github.com/ComfyAssets/ComfyUI_PromptManager/workflows/Tests/badge.svg) ![Code Quality](https://github.com/ComfyAssets/ComfyUI_PromptManager/workflows/Code%20Quality/badge.svg) @@ -933,7 +933,7 @@ node --test tests/js/*.test.js # frontend pure modules python -m coverage run -m tests.run_suite && python -m coverage combine && python -m coverage report ``` -CI runs the suite on Linux, Windows and macOS for Python 3.10 to 3.13 with an 85% coverage gate. `python -m unittest discover -s tests` still works; see `TESTING.md` ("Time limits and hangs") for the watchdog. Tests that delete a database file first check that nothing in the process still holds it open (`tests/open_handles.py`), so a connection leak fails on Linux the way it would on Windows. +CI runs the suite on Linux, Windows and macOS for Python 3.12 to 3.14 with an 85% coverage gate. `python -m unittest discover -s tests` still works; see `TESTING.md` ("Time limits and hangs") for the watchdog. Tests that delete a database file first check that nothing in the process still holds it open (`tests/open_handles.py`), so a connection leak fails on Linux the way it would on Windows. ### Code Style diff --git a/pyproject.toml b/pyproject.toml index 24e82c3..c6b89a6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ name = "promptmanager" description = "A powerful ComfyUI custom node that extends the standard text encoder with persistent prompt storage, advanced search capabilities, and an automatic image gallery system using SQLite." version = "3.3.1" license = {file = "LICENSE"} -requires-python = ">=3.10" +requires-python = ">=3.12" dependencies = ["watchdog>=2.1.0", "Pillow>=8.0.0"] [build-system] diff --git a/tests/test_packaging.py b/tests/test_packaging.py index 8f7925c..5ecd4b5 100644 --- a/tests/test_packaging.py +++ b/tests/test_packaging.py @@ -26,27 +26,9 @@ def _read(name): def _pyproject(): - try: - import tomllib # Python 3.11+ - except ImportError: # pragma: no cover - exercised on 3.10 only - tomllib = None - text = _read("pyproject.toml") - if tomllib is not None: - return tomllib.loads(text) - # Minimal fallback for 3.10: pull the dependency list out with a regex. - match = re.search(r"dependencies\s*=\s*\[(.*?)\]", text, re.S) - deps = re.findall(r'"([^"]*)"', match.group(1)) if match else [] - return { - "project": { - "dependencies": deps, - "requires-python": ( - re.search(r'requires-python\s*=\s*"([^"]+)"', text).group(1) - if "requires-python" in text - else None - ), - }, - "build-system": {} if "[build-system]" in text else None, - } + import tomllib + + return tomllib.loads(_read("pyproject.toml")) class PyprojectContract(unittest.TestCase): @@ -65,8 +47,8 @@ class PyprojectContract(unittest.TestCase): } self.assertEqual(deps, wanted) - def test_requires_python_floor_is_3_10(self): - self.assertEqual(_pyproject()["project"]["requires-python"], ">=3.10") + def test_requires_python_floor_is_3_12(self): + self.assertEqual(_pyproject()["project"]["requires-python"], ">=3.12") def test_build_system_is_declared(self): self.assertIsNotNone(_pyproject().get("build-system"))