From c069278a1f3249327cef20310e0826cf720f84fe Mon Sep 17 00:00:00 2001 From: masklinn Date: Sat, 27 Dec 2025 11:29:16 +0100 Subject: [PATCH 1/7] Remove support for Python 3.9, bump minver to 3.10 3.9 reached end of life in november 2025. Fixes #283, fixes #284 --- .github/workflows/ci.yml | 1 - pyproject.toml | 5 ++--- tox.ini | 4 ++-- ua-parser-builtins/pyproject.toml | 3 +-- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 633c55e..acfa5b3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -84,7 +84,6 @@ jobs: - sdist - source python-version: - - "3.9" - "3.10" - "3.11" - "3.12" diff --git a/pyproject.toml b/pyproject.toml index fb94bbf..14bf83c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ name = "ua-parser" description = "Python port of Browserscope's user agent parser" version = "1.0.1" readme = "README.rst" -requires-python = ">=3.9" +requires-python = ">=3.10" dependencies = ["ua-parser-builtins"] license = {text = "Apache 2.0"} @@ -33,7 +33,6 @@ classifiers = [ "Topic :: Internet :: WWW/HTTP", "Topic :: Software Development :: Libraries :: Python Modules", "Programming Language :: Python", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", @@ -81,7 +80,7 @@ combine-as-imports = true "tests/test_legacy.py" = ["PT030"] [tool.mypy] -python_version = "3.9" +python_version = "3.10" files = "src,tests" # can't use strict because it's only global diff --git a/tox.ini b/tox.ini index da50c20..d557291 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] min_version = 4.0 -env_list = py3{9,10,11,12,13} +env_list = py3{10,11,12,13} pypy{310,311} graalpy check, format, typecheck @@ -21,7 +21,7 @@ deps = commands = pytest -Werror --doctest-glob="*.rst" {posargs} -[testenv:py3{9,10,11,12,13}] +[testenv:py3{10,11,12,13}] labels = test, cpy deps = pytest diff --git a/ua-parser-builtins/pyproject.toml b/ua-parser-builtins/pyproject.toml index 0086e85..ba88500 100644 --- a/ua-parser-builtins/pyproject.toml +++ b/ua-parser-builtins/pyproject.toml @@ -7,7 +7,7 @@ name = "ua-parser-builtins" description = "Precompiled rules for User Agent Parser" readme = "README.md" dependencies = [] -requires-python = ">=3.9" +requires-python = ">=3.10" license = {text = "Apache 2.0"} urls = {repository = "https://github.com/ua-parser/uap-python"} dynamic = ["version"] @@ -25,7 +25,6 @@ classifiers = [ "Topic :: Internet :: WWW/HTTP", "Topic :: Software Development :: Libraries :: Python Modules", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", From 96e3ad62d3064f2b8df422b7403b5c0517b9c639 Mon Sep 17 00:00:00 2001 From: masklinn Date: Sat, 27 Dec 2025 11:33:04 +0100 Subject: [PATCH 2/7] Remove support for pypy 3.10 Starting with 7.3.20 released July 2025, pypy stops supporting python 3.10 --- .github/workflows/ci.yml | 1 - tox.ini | 5 +---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index acfa5b3..bce0c92 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -88,7 +88,6 @@ jobs: - "3.11" - "3.12" - "3.13" - - "pypy-3.10" - "pypy-3.11" - "graalpy-24" include: diff --git a/tox.ini b/tox.ini index d557291..fb42e87 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,7 @@ [tox] min_version = 4.0 env_list = py3{10,11,12,13} - pypy{310,311} + pypy{311} graalpy check, format, typecheck @@ -30,9 +30,6 @@ deps = ua-parser-rs ./ua-parser-builtins -[testenv:pypy{310,311}] -labels = test, pypy - [testenv:check] labels = check package = skip From 5b6b0af1a8037274f8b89effd3fcab9700828244 Mon Sep 17 00:00:00 2001 From: masklinn Date: Sat, 27 Dec 2025 11:39:50 +0100 Subject: [PATCH 3/7] Add support for cpython 3.14 Fixes #274 Also add google re2 to the 3.14 test matrix, kinda (3.13 was already added a few commits back "by mistake"), which fixes #276 --- .github/workflows/ci.yml | 1 + pyproject.toml | 1 + tox.ini | 4 ++-- ua-parser-builtins/pyproject.toml | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bce0c92..79a46c3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -88,6 +88,7 @@ jobs: - "3.11" - "3.12" - "3.13" + - "3.14" - "pypy-3.11" - "graalpy-24" include: diff --git a/pyproject.toml b/pyproject.toml index 14bf83c..d2421d6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,6 +37,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Programming Language :: Python :: Implementation :: GraalPy", diff --git a/tox.ini b/tox.ini index fb42e87..d35e475 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] min_version = 4.0 -env_list = py3{10,11,12,13} +env_list = py3{10,11,12,13,14} pypy{311} graalpy check, format, typecheck @@ -21,7 +21,7 @@ deps = commands = pytest -Werror --doctest-glob="*.rst" {posargs} -[testenv:py3{10,11,12,13}] +[testenv:py3{10,11,12,13,14}] labels = test, cpy deps = pytest diff --git a/ua-parser-builtins/pyproject.toml b/ua-parser-builtins/pyproject.toml index ba88500..6fc800d 100644 --- a/ua-parser-builtins/pyproject.toml +++ b/ua-parser-builtins/pyproject.toml @@ -29,6 +29,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Programming Language :: Python :: Implementation :: GraalPy", From 7638ca335d3e170ed72f8c8e0589204c1a134c7a Mon Sep 17 00:00:00 2001 From: masklinn Date: Sat, 27 Dec 2025 12:51:23 +0100 Subject: [PATCH 4/7] Add support for graal 25 Switch to tox-uv and its versioning, as I couldn't get tox and pyenv to collaborate on different graal versions. This seems to work. Fixes #281 --- .github/workflows/ci.yml | 4 ++-- tox.ini | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 79a46c3..485e170 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -90,14 +90,14 @@ jobs: - "3.13" - "3.14" - "pypy-3.11" - - "graalpy-24" + - "graalpy-25" include: - source: sdist artifact: dist/*.tar.gz - source: wheel artifact: dist/*.whl - opts: "" - - python-version: graalpy-24 + - python-version: graalpy-25 opts: "--experimental-options --engine.CompileOnly='~tregex re'" steps: - name: Checkout working copy diff --git a/tox.ini b/tox.ini index d35e475..31cbec7 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ min_version = 4.0 env_list = py3{10,11,12,13,14} pypy{311} - graalpy + graalpy3{11,12} check, format, typecheck [testenv] From 5be313168e8c034167491cb92fbfb05b6f0ac74b Mon Sep 17 00:00:00 2001 From: masklinn Date: Sat, 27 Dec 2025 13:07:52 +0100 Subject: [PATCH 5/7] Add support for free-threaded python Fixes #275 --- .github/workflows/ci.yml | 1 + tox.ini | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 485e170..ac6765e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -89,6 +89,7 @@ jobs: - "3.12" - "3.13" - "3.14" + - "3.14t" - "pypy-3.11" - "graalpy-25" include: diff --git a/tox.ini b/tox.ini index 31cbec7..63cddcd 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] min_version = 4.0 -env_list = py3{10,11,12,13,14} +env_list = py3{10,11,12,13,14,14t} pypy{311} graalpy3{11,12} check, format, typecheck From a9bfdcd9d4e773d3d360759d86e33d8a0c36dd65 Mon Sep 17 00:00:00 2001 From: masklinn Date: Sat, 27 Dec 2025 13:15:22 +0100 Subject: [PATCH 6/7] Unify CI check Having to update the required statuses in the branch protection rules every time the test matrix is updated is a pain in the ass. --- .github/workflows/ci.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ac6765e..f88cf2a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -140,3 +140,12 @@ jobs: run: python -m pip install ${{ matrix.artifact || '.' }} - name: run tests run: python ${{ matrix.opts }} -m pytest -v -Werror -Wignore::ImportWarning --doctest-glob="*.rst" -ra + # necessary to create a unified CI result and not have to update + # branch protection rules every time the matrix gets updated + results: + name: "CI Results" + needs: ["checks", "test"] + runs-on: ubuntu-latest + permissions: {} + steps: + - run: exit 0 From 0c54802d503acc74f2ac1442eddb55a1552a4809 Mon Sep 17 00:00:00 2001 From: masklinn Date: Sat, 27 Dec 2025 13:42:55 +0100 Subject: [PATCH 7/7] Update and pin all actions --- .github/workflows/ci.yml | 29 +++++++++++++++----------- .github/workflows/release-builtins.yml | 16 +++++++------- .github/workflows/release-main.yml | 10 +++++---- .github/workflows/zizmor.yml | 8 ++++--- .github/zizmor.yml | 4 ++++ 5 files changed, 41 insertions(+), 26 deletions(-) create mode 100644 .github/zizmor.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f88cf2a..f82d553 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,27 +4,32 @@ on: push: pull_request: +permissions: {} + jobs: checks: runs-on: ubuntu-latest steps: - name: Checkout working copy - uses: actions/checkout@v4 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # 6.0.1 with: submodules: true fetch-depth: 0 persist-credentials: false - name: ruff check - uses: chartboost/ruff-action@v1 + uses: astral-sh/ruff-action@57714a7c8a2e59f32539362ba31877a1957dded1 # 3.5.1 + with: + version: "latest" - name: ruff format if: always() - uses: chartboost/ruff-action@v1 + uses: astral-sh/ruff-action@57714a7c8a2e59f32539362ba31877a1957dded1 # 3.5.1 with: - args: format --diff + version: "latest" + args: format --check --diff - name: Set up Python id: setup_python if: always() - uses: actions/setup-python@v5 + uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # 6.1.0 with: python-version: "3.x" - name: Install mypy @@ -44,12 +49,12 @@ jobs: steps: - name: Checkout working copy - uses: actions/checkout@v4 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # 6.0.1 with: submodules: true persist-credentials: false - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # 6.1.0 with: python-version: "3.x" - name: Install dependency @@ -60,14 +65,14 @@ jobs: run: | python -mbuild - name: Upload sdist - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # 6.0.0 with: name: sdist path: dist/*.tar.gz retention-days: 1 - name: Upload wheel - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # 6.0.0 with: name: wheel path: dist/*.whl @@ -102,13 +107,13 @@ jobs: opts: "--experimental-options --engine.CompileOnly='~tregex re'" steps: - name: Checkout working copy - uses: actions/checkout@v4 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # 6.0.1 with: submodules: true fetch-depth: 0 persist-credentials: false - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # 6.1.0 with: python-version: ${{ matrix.python-version }} allow-prereleases: true @@ -132,7 +137,7 @@ jobs: - run: 'python -mpip install --only-binary :all: google-re2 || true' - name: download ${{ matrix.source }} artifact if: matrix.artifact - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # 7.0.0 with: name: ${{ matrix.source }} path: dist/ diff --git a/.github/workflows/release-builtins.yml b/.github/workflows/release-builtins.yml index 538ef90..db013a2 100644 --- a/.github/workflows/release-builtins.yml +++ b/.github/workflows/release-builtins.yml @@ -2,6 +2,8 @@ name: Publish ua-parser builtins run-name: Publish ${{ inputs.tag || 'master' }} to ${{ inputs.environment || 'pypy (scheduled)' }} +permissions: {} + on: schedule: # schedule a dev release on every 1st of the month, at 2034 UTC @@ -23,13 +25,13 @@ jobs: outputs: release: ${{ steps.check.outputs.release }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # 6.0.1 with: submodules: true fetch-depth: 0 persist-credentials: false - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # 6.1.0 with: python-version: "3.x" @@ -70,7 +72,7 @@ jobs: mv ua-parser-builtins/dist . - name: Store the distribution packages if: ${{ steps.check.outputs.release == 'true' }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # 6.0.0 with: name: python-package-distributions path: dist/ @@ -90,12 +92,12 @@ jobs: steps: - name: Download all the dists - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # 7.0.0 with: name: python-package-distributions path: dist/ - name: Publish - uses: pypa/gh-action-pypi-publish@release/v1 + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # 1.13.0 with: repository-url: https://test.pypi.org/legacy/ skip-existing: true @@ -114,11 +116,11 @@ jobs: steps: - name: Download all the dists - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # 7.0.0 with: name: python-package-distributions path: dist/ - name: Publish - uses: pypa/gh-action-pypi-publish@release/v1 + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # 1.13.0 with: verbose: true diff --git a/.github/workflows/release-main.yml b/.github/workflows/release-main.yml index bc6fca9..0e42d7e 100644 --- a/.github/workflows/release-main.yml +++ b/.github/workflows/release-main.yml @@ -5,6 +5,8 @@ on: release: types: [created] +permissions: {} + env: ENVNAME: ${{ github.event_name == 'release' && 'pypi' || 'testpypi' }} @@ -21,11 +23,11 @@ jobs: steps: - name: Checkout working copy - uses: actions/checkout@v4 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # 6.0.1 with: persist-credentials: false - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # 6.1.0 with: python-version: "3.x" - name: Install dependency @@ -36,7 +38,7 @@ jobs: run: python -mbuild - name: Publish to testpypi if: ${{ env.ENVNAME == 'testpypi' }} - uses: pypa/gh-action-pypi-publish@release/v1 # zizmor: ignore[use-trusted-publishing] + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # 1.13.0 with: repository-url: https://test.pypi.org/legacy/ skip-existing: true @@ -44,7 +46,7 @@ jobs: password: ${{ secrets.PUBLISH_TOKEN }} - name: Publish to pypi if: ${{ env.ENVNAME == 'pypi' }} - uses: pypa/gh-action-pypi-publish@release/v1 # zizmor: ignore[use-trusted-publishing] + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # 1.13.0 with: verbose: true password: ${{ secrets.PUBLISH_TOKEN }} diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index 5bf4f98..f94fa7b 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -4,6 +4,8 @@ on: push: pull_request: +permissions: {} + jobs: zizmor: runs-on: ubuntu-latest @@ -13,12 +15,12 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # 6.0.1 with: persist-credentials: false - name: Install the latest version of uv - uses: astral-sh/setup-uv@v5 + uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 # 7.1.6 - name: Run zizmor run: uvx zizmor --format sarif . > results.sarif @@ -26,7 +28,7 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@v3 + uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # 4.31.9 with: sarif_file: results.sarif category: zizmor diff --git a/.github/zizmor.yml b/.github/zizmor.yml new file mode 100644 index 0000000..62ab71e --- /dev/null +++ b/.github/zizmor.yml @@ -0,0 +1,4 @@ +rules: + use-trusted-publishing: + ignore: + - release-main.yml # can't do that until pypi/support#6661