From e8aad681b39de3f33d5cc3f7f455a54155d2c408 Mon Sep 17 00:00:00 2001 From: Juro Oravec Date: Wed, 22 Oct 2025 00:35:34 +0200 Subject: [PATCH] refactor: add support for python 3.14 (#1468) --- .devcontainer/devcontainer.json | 4 +- .github/copilot-instructions.md | 2 +- .github/workflows/tests.yml | 14 +++- CHANGELOG.md | 2 + docs/community/development.md | 3 +- docs/overview/compatibility.md | 1 + pyproject.toml | 3 +- requirements-ci-python38.txt | 118 ++++++++++++++++++++++++++++++++ requirements-ci.txt | 6 +- requirements-dev.txt | 2 +- requirements-docs.txt | 2 +- tox.ini | 31 +++++++-- 12 files changed, 171 insertions(+), 17 deletions(-) create mode 100644 requirements-ci-python38.txt diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 9558bffd..88cbd8fb 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,8 +1,8 @@ // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.0/containers/python-3 { - // Uncomment to run Python 3.13 or other specific version - // "image": "mcr.microsoft.com/devcontainers/python:3.13-bullseye", + // Uncomment to run Python 3.14 or other specific version + // "image": "mcr.microsoft.com/devcontainers/python:3.14-bullseye", // Configure tool-specific properties. "customizations": { diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 7b876413..62fcb715 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -74,7 +74,7 @@ The package provides custom Django management commands: ### CI/CD Information - GitHub Actions workflow: `.github/workflows/tests.yml` -- Tests run on Python 3.8-3.13 with Django 4.2-5.2 +- Tests run on Python 3.8-3.14 with Django 4.2-5.2 - Includes Playwright browser testing (requires `playwright install chromium --with-deps`) - Documentation building uses mkdocs - Pre-commit hooks run ruff diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f622f0fb..40d2526a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,7 +13,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13', '3.14'] os: [ubuntu-latest, windows-latest] steps: @@ -34,10 +34,18 @@ jobs: with: python-version: ${{ matrix.python-version }} cache: "pip" - - name: Install dependencies + - name: Install dependencies (Python 3.8) + if: matrix.python-version == '3.8' + run: | + python -m pip install --upgrade pip + python -m pip install -r requirements-ci-python38.txt + - name: Install dependencies (Python > 3.8) + if: matrix.python-version != '3.8' run: | python -m pip install --upgrade pip python -m pip install -r requirements-ci.txt + - name: Install Playwright browsers + run: | # See https://playwright.dev/python/docs/intro#installing-playwright-pytest playwright install chromium --with-deps - name: Run tests @@ -73,7 +81,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.13'] + python-version: ['3.14'] steps: - uses: actions/checkout@v5 diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ab2ef9b..4d5f76b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -107,6 +107,8 @@ #### Refactor +- Add support for Python 3.14 + - Extension authors: The `ExtensionComponentConfig` can be instantiated with `None` instead of a component instance. This allows to call component-level extension methods outside of the normal rendering lifecycle. diff --git a/docs/community/development.md b/docs/community/development.md index 20700aae..c47efc96 100644 --- a/docs/community/development.md +++ b/docs/community/development.md @@ -37,7 +37,8 @@ pyenv install -s 3.10 pyenv install -s 3.11 pyenv install -s 3.12 pyenv install -s 3.13 -pyenv local 3.8 3.9 3.10 3.11 3.12 3.13 +pyenv install -s 3.14 +pyenv local 3.8 3.9 3.10 3.11 3.12 3.13 3.14 tox -p ``` diff --git a/docs/overview/compatibility.md b/docs/overview/compatibility.md index 7bdf543f..f4a79eca 100644 --- a/docs/overview/compatibility.md +++ b/docs/overview/compatibility.md @@ -8,6 +8,7 @@ Django-components supports all supported combinations versions of [Django](https | 3.11 | 4.2, 5.1, 5.2 | | 3.12 | 4.2, 5.1, 5.2 | | 3.13 | 5.1, 5.2 | +| 3.14 | 5.2 | ### Operating systems diff --git a/pyproject.toml b/pyproject.toml index 65e1c909..84451e26 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,10 +27,11 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", ] dependencies = [ 'Django>=4.2', - 'djc-core-html-parser>=1.0.2', + 'djc-core-html-parser>=1.0.3', 'typing-extensions>=4.12.2', ] license = { text = "MIT" } diff --git a/requirements-ci-python38.txt b/requirements-ci-python38.txt new file mode 100644 index 00000000..1d71b948 --- /dev/null +++ b/requirements-ci-python38.txt @@ -0,0 +1,118 @@ +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile requirements-ci.in +# +asv==0.6.5 + # via -r requirements-ci.in +asv-runner==0.2.1 + # via asv +build==1.2.2.post1 + # via asv +cachetools==5.5.2 + # via tox +certifi==2025.1.31 + # via requests +chardet==5.2.0 + # via tox +charset-normalizer==3.4.1 + # via requests +colorama==0.4.6 + # via tox +distlib==0.3.9 + # via virtualenv +exceptiongroup==1.2.2 + # via pytest +filelock==3.16.1 + # via + # tox + # virtualenv +greenlet==3.1.1 + # via playwright +idna==3.10 + # via requests +importlib-metadata==8.5.0 + # via + # asv + # asv-runner + # build +iniconfig==2.0.0 + # via pytest +json5==0.10.0 + # via asv +packaging==24.2 + # via + # asv + # build + # pyproject-api + # pytest + # tox +pathspec==0.12.1 + # via -r requirements-ci.in +platformdirs==4.3.6 + # via + # tox + # virtualenv +playwright==1.48.0 + # via -r requirements-ci.in +pluggy==1.5.0 + # via + # pytest + # tox +pyee==12.0.0 + # via playwright +pympler==1.1 + # via asv +pyproject-api==1.8.0 + # via tox +pyproject-hooks==1.2.0 + # via build +pytest==8.3.5 + # via + # pytest-asyncio + # pytest-django +pytest-asyncio==0.24.0 + # via -r requirements-ci.in +pytest-django==4.11.1 + # via -r requirements-ci.in +pyyaml==6.0.2 + # via asv +requests==2.32.3 + # via -r requirements-ci.in +tabulate==0.9.0 + # via asv +tomli==2.2.1 + # via + # asv + # build + # pyproject-api + # pytest + # tox +tox==4.25.0 + # via + # -r requirements-ci.in + # tox-gh-actions +tox-gh-actions==3.4.0 + # via -r requirements-ci.in +types-requests==2.32.0.20241016 + # via -r requirements-ci.in +typing-extensions==4.13.2 + # via + # -r requirements-ci.in + # pyee + # tox + # virtualenv +urllib3==2.2.3 + # via + # requests + # types-requests +virtualenv==20.35.3 + # via + # -r requirements-ci.in + # asv + # tox +whitenoise==6.7.0 + # via -r requirements-ci.in +zipp==3.20.2 + # via importlib-metadata diff --git a/requirements-ci.txt b/requirements-ci.txt index 1d71b948..dc079fa8 100644 --- a/requirements-ci.txt +++ b/requirements-ci.txt @@ -28,7 +28,7 @@ filelock==3.16.1 # via # tox # virtualenv -greenlet==3.1.1 +greenlet==3.2.4 # via playwright idna==3.10 # via requests @@ -54,13 +54,13 @@ platformdirs==4.3.6 # via # tox # virtualenv -playwright==1.48.0 +playwright==1.55.0 # via -r requirements-ci.in pluggy==1.5.0 # via # pytest # tox -pyee==12.0.0 +pyee==13.0.0 # via playwright pympler==1.1 # via asv diff --git a/requirements-dev.txt b/requirements-dev.txt index e252d0c6..01c86bfe 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -36,7 +36,7 @@ django==4.2.25 # django-template-partials django-template-partials==25.2 # via -r requirements-dev.in -djc-core-html-parser==1.0.2 +djc-core-html-parser==1.0.3 # via -r requirements-dev.in exceptiongroup==1.3.0 # via pytest diff --git a/requirements-docs.txt b/requirements-docs.txt index 9d60ac75..ddeacb02 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -42,7 +42,7 @@ defusedxml==0.7.1 # via cairosvg django==5.2.5 # via -r requirements-docs.in -djc-core-html-parser==1.0.2 +djc-core-html-parser==1.0.3 # via -r requirements-docs.in ghp-import==2.1.0 # via mkdocs diff --git a/tox.ini b/tox.ini index 07cd812e..555b7d2e 100644 --- a/tox.ini +++ b/tox.ini @@ -7,6 +7,7 @@ envlist = py{38,39}-django42 py{310,311,312}-django{42,51,52} py{313}-django{51,52} + py{314}-django{52} ruff coverage mypy @@ -18,7 +19,8 @@ python = 3.10: py310-django{42,51,52} 3.11: py311-django{42,51,52} 3.12: py312-django{42,51,52} - 3.13: py313-django{51,52}, ruff, coverage, mypy + 3.13: py313-django{51,52} + 3.14: py314-django{52}, ruff, coverage, mypy isolated_build = true @@ -29,7 +31,7 @@ deps = django42: Django>=4.2,<4.3 django51: Django>=5.1,<5.2 django52: Django>=5.2,<5.3 - djc-core-html-parser==1.0.2 + djc-core-html-parser==1.0.3 pytest pytest-xdist pytest-django @@ -38,7 +40,9 @@ deps = # NOTE: Keep playwright is sync with the version in requirements-ci.txt # Othrwise we get error: # playwright._impl._errors.Error: BrowserType.launch: Executable doesn't exist at /home/runner/.cache/ms-playwright/chromium-1140/chrome-linux/chrome - playwright==1.48.0 + !py38: playwright==1.55.0 + # For py38 run specific old version + py38: playwright==1.48.0 pydantic requests types-requests @@ -47,6 +51,25 @@ deps = django-template-partials commands = pytest {posargs} +# TODO: Delete this when Django 4.2 reaches end of life +[testenv:py38-django42] +deps = + django42: Django>=4.2,<4.3 + django51: Django>=5.1,<5.2 + django52: Django>=5.2,<5.3 + djc-core-html-parser==1.0.3 + pytest + pytest-xdist + pytest-django + pytest-asyncio + syrupy # pytest snapshot testing + playwright==1.48.0 + pydantic + requests + types-requests + whitenoise + django-template-partials + [testenv:ruff] deps = ruff commands = @@ -60,7 +83,7 @@ deps = pytest-asyncio syrupy # snapshot testing # NOTE: Keep playwright in sync with the version in requirements-ci.txt - playwright==1.48.0 + playwright==1.55.0 pydantic requests types-requests