From 2ddfd71d81c9369fe6a13ed2cde7bf304d7d6caa Mon Sep 17 00:00:00 2001 From: Vlada Dusek Date: Tue, 13 Oct 2026 09:38:22 +0200 Subject: [PATCH 1/2] feat: add support for Python 3.15 --- .github/workflows/_checks.yaml | 12 ++++++------ .rules.md | 2 +- pyproject.toml | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/_checks.yaml b/.github/workflows/_checks.yaml index a9cadc3ce..37f65ba6d 100644 --- a/.github/workflows/_checks.yaml +++ b/.github/workflows/_checks.yaml @@ -41,13 +41,13 @@ jobs: name: Lint check uses: apify/workflows/.github/workflows/python_lint_check.yaml@main with: - python_versions: '["3.11", "3.12", "3.13", "3.14"]' + python_versions: '["3.11", "3.12", "3.13", "3.14", "3.15"]' type_check: name: Type check uses: apify/workflows/.github/workflows/python_type_check.yaml@main with: - python_versions: '["3.11", "3.12", "3.13", "3.14"]' + python_versions: '["3.11", "3.12", "3.13", "3.14", "3.15"]' markdown_lint_check: name: Markdown lint check @@ -135,9 +135,9 @@ jobs: uses: apify/workflows/.github/workflows/python_unit_tests.yaml@main secrets: inherit with: - python_versions: '["3.11", "3.12", "3.13", "3.14"]' + python_versions: '["3.11", "3.12", "3.13", "3.14", "3.15"]' operating_systems: '["ubuntu-latest", "windows-latest"]' - python_version_for_codecov: "3.14" + python_version_for_codecov: "3.15" operating_system_for_codecov: ubuntu-latest tests_concurrency: "4" @@ -156,7 +156,7 @@ jobs: strategy: matrix: os: ["ubuntu-latest"] - python-version: ["3.11", "3.14"] + python-version: ["3.11", "3.15"] runs-on: ${{ matrix.os }} @@ -190,7 +190,7 @@ jobs: if: >- ${{ matrix.os == 'ubuntu-latest' && - matrix.python-version == '3.14' && + matrix.python-version == '3.15' && env.CODECOV_TOKEN != '' }} uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1 diff --git a/.rules.md b/.rules.md index 047895dbf..03d582c51 100644 --- a/.rules.md +++ b/.rules.md @@ -4,7 +4,7 @@ This file provides guidance to programming agents when working with code in this ## Project Overview -The Apify SDK for Python (`apify` package on PyPI) is the official library for creating [Apify Actors](https://docs.apify.com/platform/actors) in Python. It provides Actor lifecycle management, storage access (datasets, key-value stores, request queues), event handling, proxy configuration, and pay-per-event charging. It builds on top of the [Crawlee](https://crawlee.dev/python) web scraping framework and the [Apify API Client](https://docs.apify.com/api/client/python). Supports Python 3.11–3.14. Build system: uv_build. +The Apify SDK for Python (`apify` package on PyPI) is the official library for creating [Apify Actors](https://docs.apify.com/platform/actors) in Python. It provides Actor lifecycle management, storage access (datasets, key-value stores, request queues), event handling, proxy configuration, and pay-per-event charging. It builds on top of the [Crawlee](https://crawlee.dev/python) web scraping framework and the [Apify API Client](https://docs.apify.com/api/client/python). Supports Python 3.11–3.15. Build system: uv_build. ## Common Commands diff --git a/pyproject.toml b/pyproject.toml index bfb018bbe..c1fe7feb7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,6 +20,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", + "Programming Language :: Python :: 3.15", "Topic :: Software Development :: Libraries", "Typing :: Typed", ] From 70c7f5280a9c2220b3a46094747ba36b801ae92c Mon Sep 17 00:00:00 2001 From: Vlada Dusek Date: Tue, 13 Oct 2026 09:49:23 +0200 Subject: [PATCH 2/2] test: compare decoded gzip payload in test_to_gzip --- tests/unit/scrapy/extensions/test_httpcache.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/unit/scrapy/extensions/test_httpcache.py b/tests/unit/scrapy/extensions/test_httpcache.py index f178a13c7..5aa07b0ae 100644 --- a/tests/unit/scrapy/extensions/test_httpcache.py +++ b/tests/unit/scrapy/extensions/test_httpcache.py @@ -36,10 +36,13 @@ def test_gzip() -> None: def test_to_gzip() -> None: - """`to_gzip` produces the expected gzip-compressed JSON bytes for a fixed mtime.""" + """`to_gzip` produces gzip-compressed JSON with the given mtime in its header.""" data_bytes = to_gzip(FIXTURE_DICT, mtime=0) - assert data_bytes == FIXTURE_BYTES + # The header's extra-flags byte and the deflate stream differ across CPython and zlib versions, so + # compare the decompressed payload and the mtime. + assert gzip.decompress(data_bytes) == gzip.decompress(FIXTURE_BYTES) + assert read_gzip_time(data_bytes) == 0 def test_from_gzip() -> None: