From fcc308a4e10f49a4f4b1c60f0024ae9e0006df79 Mon Sep 17 00:00:00 2001 From: Vlada Dusek Date: Wed, 22 Oct 2025 13:59:18 +0200 Subject: [PATCH 01/11] feat: Add support for Python 3.14 --- .github/workflows/build_and_deploy_docs.yaml | 2 +- .github/workflows/release.yaml | 6 +++--- .github/workflows/run_code_checks.yaml | 6 +++--- .github/workflows/templates_e2e_tests.yaml | 2 +- pyproject.toml | 3 ++- uv.lock | 2 +- 6 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build_and_deploy_docs.yaml b/.github/workflows/build_and_deploy_docs.yaml index d27b45dc10..3d74ba874d 100644 --- a/.github/workflows/build_and_deploy_docs.yaml +++ b/.github/workflows/build_and_deploy_docs.yaml @@ -10,7 +10,7 @@ on: env: NODE_VERSION: 20 - PYTHON_VERSION: 3.13 + PYTHON_VERSION: 3.14 jobs: build_and_deploy_docs: diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 3683e87c8e..acf286c69c 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -47,13 +47,13 @@ jobs: name: Lint check uses: apify/workflows/.github/workflows/python_lint_check.yaml@main with: - python-versions: '["3.10", "3.11", "3.12", "3.13"]' + python-versions: '["3.10", "3.11", "3.12", "3.13", "3.14"]' type_check: name: Type check uses: apify/workflows/.github/workflows/python_type_check.yaml@main with: - python-versions: '["3.10", "3.11", "3.12", "3.13"]' + python-versions: '["3.10", "3.11", "3.12", "3.13", "3.14"]' unit_tests: name: Unit tests @@ -61,7 +61,7 @@ jobs: secrets: httpbin_url: ${{ secrets.APIFY_HTTPBIN_TOKEN && format('https://httpbin.apify.actor?token={0}', secrets.APIFY_HTTPBIN_TOKEN) || 'https://httpbin.org'}} with: - python-versions: '["3.10", "3.11", "3.12", "3.13"]' + python-versions: '["3.10", "3.11", "3.12", "3.13", "3.14"]' update_changelog: name: Update changelog diff --git a/.github/workflows/run_code_checks.yaml b/.github/workflows/run_code_checks.yaml index 9bd2924f2a..42e3422870 100644 --- a/.github/workflows/run_code_checks.yaml +++ b/.github/workflows/run_code_checks.yaml @@ -21,13 +21,13 @@ jobs: name: Lint check uses: apify/workflows/.github/workflows/python_lint_check.yaml@main with: - python-versions: '["3.10", "3.11", "3.12", "3.13"]' + python-versions: '["3.10", "3.11", "3.12", "3.13", "3.14"]' type_check: name: Type check uses: apify/workflows/.github/workflows/python_type_check.yaml@main with: - python-versions: '["3.10", "3.11", "3.12", "3.13"]' + python-versions: '["3.10", "3.11", "3.12", "3.13", "3.14"]' unit_tests: name: Unit tests @@ -35,7 +35,7 @@ jobs: secrets: httpbin_url: ${{ secrets.APIFY_HTTPBIN_TOKEN && format('https://httpbin.apify.actor?token={0}', secrets.APIFY_HTTPBIN_TOKEN) || 'https://httpbin.org'}} with: - python-versions: '["3.10", "3.11", "3.12", "3.13"]' + python-versions: '["3.10", "3.11", "3.12", "3.13", "3.14"]' docs_check: name: Docs check diff --git a/.github/workflows/templates_e2e_tests.yaml b/.github/workflows/templates_e2e_tests.yaml index 3cce8c527d..414cfab65c 100644 --- a/.github/workflows/templates_e2e_tests.yaml +++ b/.github/workflows/templates_e2e_tests.yaml @@ -7,7 +7,7 @@ on: env: NODE_VERSION: 22 - PYTHON_VERSION: 3.13 + PYTHON_VERSION: 3.14 jobs: end_to_end_tests: diff --git a/pyproject.toml b/pyproject.toml index 8be6136b2c..9c38fc5ae6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,6 +20,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Topic :: Software Development :: Libraries", ] keywords = [ @@ -35,7 +36,7 @@ keywords = [ dependencies = [ "cachetools>=5.5.0", "colorama>=0.4.0", - "impit>=0.6.1", + "impit>=0.8.0", "more-itertools>=10.2.0", "protego>=0.5.0", "psutil>=6.0.0", diff --git a/uv.lock b/uv.lock index e76d024281..f10e04d50e 100644 --- a/uv.lock +++ b/uv.lock @@ -842,7 +842,7 @@ requires-dist = [ { name = "curl-cffi", marker = "extra == 'curl-impersonate'", specifier = ">=0.9.0" }, { name = "html5lib", marker = "extra == 'beautifulsoup'", specifier = ">=1.0" }, { name = "httpx", extras = ["brotli", "http2", "zstd"], marker = "extra == 'httpx'", specifier = ">=0.27.0" }, - { name = "impit", specifier = ">=0.6.1" }, + { name = "impit", specifier = ">=0.8.0" }, { name = "inquirer", marker = "extra == 'cli'", specifier = ">=3.3.0" }, { name = "jaro-winkler", marker = "extra == 'adaptive-crawler'", specifier = ">=2.0.3" }, { name = "more-itertools", specifier = ">=10.2.0" }, From 90c11b37df0b98a4a01f3504935a5be86a9dda2e Mon Sep 17 00:00:00 2001 From: Max Bohomolov Date: Thu, 13 Nov 2025 02:38:15 +0000 Subject: [PATCH 02/11] update linux test for python 3.14 --- tests/unit/_utils/test_system.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/unit/_utils/test_system.py b/tests/unit/_utils/test_system.py index 4e147d9c80..3a27f4e1d0 100644 --- a/tests/unit/_utils/test_system.py +++ b/tests/unit/_utils/test_system.py @@ -1,7 +1,7 @@ from __future__ import annotations import sys -from multiprocessing import Barrier, Process, Value, synchronize +from multiprocessing import Barrier, Process, Value, set_start_method, synchronize from multiprocessing.shared_memory import SharedMemory from typing import TYPE_CHECKING @@ -38,6 +38,7 @@ def test_memory_estimation_does_not_overestimate_due_to_shared_memory() -> None: equal to additional_memory_size_estimate_per_unshared_memory_child where the additional shared memory is exactly the same as the unshared memory. """ + set_start_method('fork', force=True) estimated_memory_expectation = Value('b', False) # noqa: FBT003 # Common usage pattern for multiprocessing.Value def parent_process() -> None: From dbbf699bade666d20c267935c52a7197df0fbfad Mon Sep 17 00:00:00 2001 From: Max Bohomolov Date: Thu, 13 Nov 2025 02:50:00 +0000 Subject: [PATCH 03/11] limit asyncpg for windows --- pyproject.toml | 2 +- uv.lock | 14 +++----------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d730539850..a43cdf20ef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,7 +73,7 @@ otel = [ ] sql_postgres = [ "sqlalchemy[asyncio]>=2.0.0,<3.0.0", - "asyncpg>=0.24.0" + "asyncpg>=0.24.0; sys_platform != 'win32' and python_version < '3.14'" ] sql_sqlite = [ "sqlalchemy[asyncio]>=2.0.0,<3.0.0", diff --git a/uv.lock b/uv.lock index 7b96a10a94..3226420cde 100644 --- a/uv.lock +++ b/uv.lock @@ -122,32 +122,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/83/83/44bd393919c504ffe4a82d0aed8ea0e55eb1571a1dea6a4922b723f0a03b/asyncpg-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7255812ac85099a0e1ffb81b10dc477b9973345793776b128a23e60148dd1af", size = 2947526, upload-time = "2024-10-20T00:29:15.871Z" }, { url = "https://files.pythonhosted.org/packages/08/85/e23dd3a2b55536eb0ded80c457b0693352262dc70426ef4d4a6fc994fa51/asyncpg-0.30.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:578445f09f45d1ad7abddbff2a3c7f7c291738fdae0abffbeb737d3fc3ab8b75", size = 2895390, upload-time = "2024-10-20T00:29:19.346Z" }, { url = "https://files.pythonhosted.org/packages/9b/26/fa96c8f4877d47dc6c1864fef5500b446522365da3d3d0ee89a5cce71a3f/asyncpg-0.30.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c42f6bb65a277ce4d93f3fba46b91a265631c8df7250592dd4f11f8b0152150f", size = 3015630, upload-time = "2024-10-20T00:29:21.186Z" }, - { url = "https://files.pythonhosted.org/packages/34/00/814514eb9287614188a5179a8b6e588a3611ca47d41937af0f3a844b1b4b/asyncpg-0.30.0-cp310-cp310-win32.whl", hash = "sha256:aa403147d3e07a267ada2ae34dfc9324e67ccc4cdca35261c8c22792ba2b10cf", size = 568760, upload-time = "2024-10-20T00:29:22.769Z" }, - { url = "https://files.pythonhosted.org/packages/f0/28/869a7a279400f8b06dd237266fdd7220bc5f7c975348fea5d1e6909588e9/asyncpg-0.30.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb622c94db4e13137c4c7f98834185049cc50ee01d8f657ef898b6407c7b9c50", size = 625764, upload-time = "2024-10-20T00:29:25.882Z" }, { url = "https://files.pythonhosted.org/packages/4c/0e/f5d708add0d0b97446c402db7e8dd4c4183c13edaabe8a8500b411e7b495/asyncpg-0.30.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5e0511ad3dec5f6b4f7a9e063591d407eee66b88c14e2ea636f187da1dcfff6a", size = 674506, upload-time = "2024-10-20T00:29:27.988Z" }, { url = "https://files.pythonhosted.org/packages/6a/a0/67ec9a75cb24a1d99f97b8437c8d56da40e6f6bd23b04e2f4ea5d5ad82ac/asyncpg-0.30.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:915aeb9f79316b43c3207363af12d0e6fd10776641a7de8a01212afd95bdf0ed", size = 645922, upload-time = "2024-10-20T00:29:29.391Z" }, { url = "https://files.pythonhosted.org/packages/5c/d9/a7584f24174bd86ff1053b14bb841f9e714380c672f61c906eb01d8ec433/asyncpg-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c198a00cce9506fcd0bf219a799f38ac7a237745e1d27f0e1f66d3707c84a5a", size = 3079565, upload-time = "2024-10-20T00:29:30.832Z" }, { url = "https://files.pythonhosted.org/packages/a0/d7/a4c0f9660e333114bdb04d1a9ac70db690dd4ae003f34f691139a5cbdae3/asyncpg-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3326e6d7381799e9735ca2ec9fd7be4d5fef5dcbc3cb555d8a463d8460607956", size = 3109962, upload-time = "2024-10-20T00:29:33.114Z" }, { url = "https://files.pythonhosted.org/packages/3c/21/199fd16b5a981b1575923cbb5d9cf916fdc936b377e0423099f209e7e73d/asyncpg-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:51da377487e249e35bd0859661f6ee2b81db11ad1f4fc036194bc9cb2ead5056", size = 3064791, upload-time = "2024-10-20T00:29:34.677Z" }, { url = "https://files.pythonhosted.org/packages/77/52/0004809b3427534a0c9139c08c87b515f1c77a8376a50ae29f001e53962f/asyncpg-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bc6d84136f9c4d24d358f3b02be4b6ba358abd09f80737d1ac7c444f36108454", size = 3188696, upload-time = "2024-10-20T00:29:36.389Z" }, - { url = "https://files.pythonhosted.org/packages/52/cb/fbad941cd466117be58b774a3f1cc9ecc659af625f028b163b1e646a55fe/asyncpg-0.30.0-cp311-cp311-win32.whl", hash = "sha256:574156480df14f64c2d76450a3f3aaaf26105869cad3865041156b38459e935d", size = 567358, upload-time = "2024-10-20T00:29:37.915Z" }, - { url = "https://files.pythonhosted.org/packages/3c/0a/0a32307cf166d50e1ad120d9b81a33a948a1a5463ebfa5a96cc5606c0863/asyncpg-0.30.0-cp311-cp311-win_amd64.whl", hash = "sha256:3356637f0bd830407b5597317b3cb3571387ae52ddc3bca6233682be88bbbc1f", size = 629375, upload-time = "2024-10-20T00:29:39.987Z" }, { url = "https://files.pythonhosted.org/packages/4b/64/9d3e887bb7b01535fdbc45fbd5f0a8447539833b97ee69ecdbb7a79d0cb4/asyncpg-0.30.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c902a60b52e506d38d7e80e0dd5399f657220f24635fee368117b8b5fce1142e", size = 673162, upload-time = "2024-10-20T00:29:41.88Z" }, { url = "https://files.pythonhosted.org/packages/6e/eb/8b236663f06984f212a087b3e849731f917ab80f84450e943900e8ca4052/asyncpg-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aca1548e43bbb9f0f627a04666fedaca23db0a31a84136ad1f868cb15deb6e3a", size = 637025, upload-time = "2024-10-20T00:29:43.352Z" }, { url = "https://files.pythonhosted.org/packages/cc/57/2dc240bb263d58786cfaa60920779af6e8d32da63ab9ffc09f8312bd7a14/asyncpg-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c2a2ef565400234a633da0eafdce27e843836256d40705d83ab7ec42074efb3", size = 3496243, upload-time = "2024-10-20T00:29:44.922Z" }, { url = "https://files.pythonhosted.org/packages/f4/40/0ae9d061d278b10713ea9021ef6b703ec44698fe32178715a501ac696c6b/asyncpg-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1292b84ee06ac8a2ad8e51c7475aa309245874b61333d97411aab835c4a2f737", size = 3575059, upload-time = "2024-10-20T00:29:46.891Z" }, { url = "https://files.pythonhosted.org/packages/c3/75/d6b895a35a2c6506952247640178e5f768eeb28b2e20299b6a6f1d743ba0/asyncpg-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0f5712350388d0cd0615caec629ad53c81e506b1abaaf8d14c93f54b35e3595a", size = 3473596, upload-time = "2024-10-20T00:29:49.201Z" }, { url = "https://files.pythonhosted.org/packages/c8/e7/3693392d3e168ab0aebb2d361431375bd22ffc7b4a586a0fc060d519fae7/asyncpg-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:db9891e2d76e6f425746c5d2da01921e9a16b5a71a1c905b13f30e12a257c4af", size = 3641632, upload-time = "2024-10-20T00:29:50.768Z" }, - { url = "https://files.pythonhosted.org/packages/32/ea/15670cea95745bba3f0352341db55f506a820b21c619ee66b7d12ea7867d/asyncpg-0.30.0-cp312-cp312-win32.whl", hash = "sha256:68d71a1be3d83d0570049cd1654a9bdfe506e794ecc98ad0873304a9f35e411e", size = 560186, upload-time = "2024-10-20T00:29:52.394Z" }, - { url = "https://files.pythonhosted.org/packages/7e/6b/fe1fad5cee79ca5f5c27aed7bd95baee529c1bf8a387435c8ba4fe53d5c1/asyncpg-0.30.0-cp312-cp312-win_amd64.whl", hash = "sha256:9a0292c6af5c500523949155ec17b7fe01a00ace33b68a476d6b5059f9630305", size = 621064, upload-time = "2024-10-20T00:29:53.757Z" }, { url = "https://files.pythonhosted.org/packages/3a/22/e20602e1218dc07692acf70d5b902be820168d6282e69ef0d3cb920dc36f/asyncpg-0.30.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05b185ebb8083c8568ea8a40e896d5f7af4b8554b64d7719c0eaa1eb5a5c3a70", size = 670373, upload-time = "2024-10-20T00:29:55.165Z" }, { url = "https://files.pythonhosted.org/packages/3d/b3/0cf269a9d647852a95c06eb00b815d0b95a4eb4b55aa2d6ba680971733b9/asyncpg-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c47806b1a8cbb0a0db896f4cd34d89942effe353a5035c62734ab13b9f938da3", size = 634745, upload-time = "2024-10-20T00:29:57.14Z" }, { url = "https://files.pythonhosted.org/packages/8e/6d/a4f31bf358ce8491d2a31bfe0d7bcf25269e80481e49de4d8616c4295a34/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b6fde867a74e8c76c71e2f64f80c64c0f3163e687f1763cfaf21633ec24ec33", size = 3512103, upload-time = "2024-10-20T00:29:58.499Z" }, { url = "https://files.pythonhosted.org/packages/96/19/139227a6e67f407b9c386cb594d9628c6c78c9024f26df87c912fabd4368/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46973045b567972128a27d40001124fbc821c87a6cade040cfcd4fa8a30bcdc4", size = 3592471, upload-time = "2024-10-20T00:30:00.354Z" }, { url = "https://files.pythonhosted.org/packages/67/e4/ab3ca38f628f53f0fd28d3ff20edff1c975dd1cb22482e0061916b4b9a74/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9110df111cabc2ed81aad2f35394a00cadf4f2e0635603db6ebbd0fc896f46a4", size = 3496253, upload-time = "2024-10-20T00:30:02.794Z" }, { url = "https://files.pythonhosted.org/packages/ef/5f/0bf65511d4eeac3a1f41c54034a492515a707c6edbc642174ae79034d3ba/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04ff0785ae7eed6cc138e73fc67b8e51d54ee7a3ce9b63666ce55a0bf095f7ba", size = 3662720, upload-time = "2024-10-20T00:30:04.501Z" }, - { url = "https://files.pythonhosted.org/packages/e7/31/1513d5a6412b98052c3ed9158d783b1e09d0910f51fbe0e05f56cc370bc4/asyncpg-0.30.0-cp313-cp313-win32.whl", hash = "sha256:ae374585f51c2b444510cdf3595b97ece4f233fde739aa14b50e0d64e8a7a590", size = 560404, upload-time = "2024-10-20T00:30:06.537Z" }, - { url = "https://files.pythonhosted.org/packages/c8/a4/cec76b3389c4c5ff66301cd100fe88c318563ec8a520e0b2e792b5b84972/asyncpg-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:f59b430b8e27557c3fb9869222559f7417ced18688375825f8f12302c34e915e", size = 621623, upload-time = "2024-10-20T00:30:09.024Z" }, ] [[package]] @@ -733,7 +725,7 @@ adaptive-crawler = [ all = [ { name = "aiosqlite" }, { name = "apify-fingerprint-datapoints" }, - { name = "asyncpg" }, + { name = "asyncpg", marker = "python_full_version < '3.14' and sys_platform != 'win32'" }, { name = "beautifulsoup4", extra = ["lxml"] }, { name = "browserforge" }, { name = "cookiecutter" }, @@ -796,7 +788,7 @@ redis = [ { name = "redis", extra = ["hiredis"] }, ] sql-postgres = [ - { name = "asyncpg" }, + { name = "asyncpg", marker = "python_full_version < '3.14' and sys_platform != 'win32'" }, { name = "sqlalchemy", extra = ["asyncio"] }, ] sql-sqlite = [ @@ -835,7 +827,7 @@ requires-dist = [ { name = "apify-fingerprint-datapoints", marker = "extra == 'adaptive-crawler'", specifier = ">=0.0.2" }, { name = "apify-fingerprint-datapoints", marker = "extra == 'httpx'", specifier = ">=0.0.2" }, { name = "apify-fingerprint-datapoints", marker = "extra == 'playwright'", specifier = ">=0.0.2" }, - { name = "asyncpg", marker = "extra == 'sql-postgres'", specifier = ">=0.24.0" }, + { name = "asyncpg", marker = "python_full_version < '3.14' and sys_platform != 'win32' and extra == 'sql-postgres'", specifier = ">=0.24.0" }, { name = "beautifulsoup4", extras = ["lxml"], marker = "extra == 'beautifulsoup'", specifier = ">=4.12.0" }, { name = "browserforge", marker = "extra == 'adaptive-crawler'", specifier = ">=1.2.3" }, { name = "browserforge", marker = "extra == 'httpx'", specifier = ">=1.2.3" }, From 7e01f2139c12cecbcae46d8339bc0a0e2651571c Mon Sep 17 00:00:00 2001 From: Max Bohomolov Date: Thu, 13 Nov 2025 03:25:11 +0000 Subject: [PATCH 04/11] skip rq_client bloom in windows with python 3.14 --- tests/unit/storage_clients/_redis/test_redis_rq_client.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/unit/storage_clients/_redis/test_redis_rq_client.py b/tests/unit/storage_clients/_redis/test_redis_rq_client.py index 3f878ea981..e717632989 100644 --- a/tests/unit/storage_clients/_redis/test_redis_rq_client.py +++ b/tests/unit/storage_clients/_redis/test_redis_rq_client.py @@ -2,6 +2,7 @@ import asyncio import json +import sys from typing import TYPE_CHECKING import pytest @@ -25,6 +26,9 @@ async def rq_client( suppress_user_warning: None, # noqa: ARG001 ) -> AsyncGenerator[RedisRequestQueueClient, None]: """A fixture for a Redis RQ client.""" + if request.param == 'bloom' and sys.platform == 'win32' and sys.version_info >= (3, 14): + pytest.skip('Bloom filters not supported on Windows with Python 3.14 and fakeredis') + client = await RedisStorageClient(redis=redis_client, queue_dedup_strategy=request.param).create_rq_client( name='test_request_queue' ) From 4e6e209d6b7b88e220f7a0c4fd09a169b09e1b39 Mon Sep 17 00:00:00 2001 From: Max Bohomolov Date: Thu, 13 Nov 2025 13:48:49 +0000 Subject: [PATCH 05/11] add comment --- pyproject.toml | 2 +- uv.lock | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1fcdfcce54..3f06f5b0d6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ otel = [ ] sql_postgres = [ "sqlalchemy[asyncio]>=2.0.0,<3.0.0", - "asyncpg>=0.24.0; sys_platform != 'win32' and python_version < '3.14'" + "asyncpg>=0.24.0; python_version < '3.14'" # Asyncpg has not yet been released with support for Python 3.14. ] sql_sqlite = [ "sqlalchemy[asyncio]>=2.0.0,<3.0.0", diff --git a/uv.lock b/uv.lock index 855ca8f2f7..300c6a871b 100644 --- a/uv.lock +++ b/uv.lock @@ -122,24 +122,32 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/83/83/44bd393919c504ffe4a82d0aed8ea0e55eb1571a1dea6a4922b723f0a03b/asyncpg-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7255812ac85099a0e1ffb81b10dc477b9973345793776b128a23e60148dd1af", size = 2947526, upload-time = "2024-10-20T00:29:15.871Z" }, { url = "https://files.pythonhosted.org/packages/08/85/e23dd3a2b55536eb0ded80c457b0693352262dc70426ef4d4a6fc994fa51/asyncpg-0.30.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:578445f09f45d1ad7abddbff2a3c7f7c291738fdae0abffbeb737d3fc3ab8b75", size = 2895390, upload-time = "2024-10-20T00:29:19.346Z" }, { url = "https://files.pythonhosted.org/packages/9b/26/fa96c8f4877d47dc6c1864fef5500b446522365da3d3d0ee89a5cce71a3f/asyncpg-0.30.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c42f6bb65a277ce4d93f3fba46b91a265631c8df7250592dd4f11f8b0152150f", size = 3015630, upload-time = "2024-10-20T00:29:21.186Z" }, + { url = "https://files.pythonhosted.org/packages/34/00/814514eb9287614188a5179a8b6e588a3611ca47d41937af0f3a844b1b4b/asyncpg-0.30.0-cp310-cp310-win32.whl", hash = "sha256:aa403147d3e07a267ada2ae34dfc9324e67ccc4cdca35261c8c22792ba2b10cf", size = 568760, upload-time = "2024-10-20T00:29:22.769Z" }, + { url = "https://files.pythonhosted.org/packages/f0/28/869a7a279400f8b06dd237266fdd7220bc5f7c975348fea5d1e6909588e9/asyncpg-0.30.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb622c94db4e13137c4c7f98834185049cc50ee01d8f657ef898b6407c7b9c50", size = 625764, upload-time = "2024-10-20T00:29:25.882Z" }, { url = "https://files.pythonhosted.org/packages/4c/0e/f5d708add0d0b97446c402db7e8dd4c4183c13edaabe8a8500b411e7b495/asyncpg-0.30.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5e0511ad3dec5f6b4f7a9e063591d407eee66b88c14e2ea636f187da1dcfff6a", size = 674506, upload-time = "2024-10-20T00:29:27.988Z" }, { url = "https://files.pythonhosted.org/packages/6a/a0/67ec9a75cb24a1d99f97b8437c8d56da40e6f6bd23b04e2f4ea5d5ad82ac/asyncpg-0.30.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:915aeb9f79316b43c3207363af12d0e6fd10776641a7de8a01212afd95bdf0ed", size = 645922, upload-time = "2024-10-20T00:29:29.391Z" }, { url = "https://files.pythonhosted.org/packages/5c/d9/a7584f24174bd86ff1053b14bb841f9e714380c672f61c906eb01d8ec433/asyncpg-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c198a00cce9506fcd0bf219a799f38ac7a237745e1d27f0e1f66d3707c84a5a", size = 3079565, upload-time = "2024-10-20T00:29:30.832Z" }, { url = "https://files.pythonhosted.org/packages/a0/d7/a4c0f9660e333114bdb04d1a9ac70db690dd4ae003f34f691139a5cbdae3/asyncpg-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3326e6d7381799e9735ca2ec9fd7be4d5fef5dcbc3cb555d8a463d8460607956", size = 3109962, upload-time = "2024-10-20T00:29:33.114Z" }, { url = "https://files.pythonhosted.org/packages/3c/21/199fd16b5a981b1575923cbb5d9cf916fdc936b377e0423099f209e7e73d/asyncpg-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:51da377487e249e35bd0859661f6ee2b81db11ad1f4fc036194bc9cb2ead5056", size = 3064791, upload-time = "2024-10-20T00:29:34.677Z" }, { url = "https://files.pythonhosted.org/packages/77/52/0004809b3427534a0c9139c08c87b515f1c77a8376a50ae29f001e53962f/asyncpg-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bc6d84136f9c4d24d358f3b02be4b6ba358abd09f80737d1ac7c444f36108454", size = 3188696, upload-time = "2024-10-20T00:29:36.389Z" }, + { url = "https://files.pythonhosted.org/packages/52/cb/fbad941cd466117be58b774a3f1cc9ecc659af625f028b163b1e646a55fe/asyncpg-0.30.0-cp311-cp311-win32.whl", hash = "sha256:574156480df14f64c2d76450a3f3aaaf26105869cad3865041156b38459e935d", size = 567358, upload-time = "2024-10-20T00:29:37.915Z" }, + { url = "https://files.pythonhosted.org/packages/3c/0a/0a32307cf166d50e1ad120d9b81a33a948a1a5463ebfa5a96cc5606c0863/asyncpg-0.30.0-cp311-cp311-win_amd64.whl", hash = "sha256:3356637f0bd830407b5597317b3cb3571387ae52ddc3bca6233682be88bbbc1f", size = 629375, upload-time = "2024-10-20T00:29:39.987Z" }, { url = "https://files.pythonhosted.org/packages/4b/64/9d3e887bb7b01535fdbc45fbd5f0a8447539833b97ee69ecdbb7a79d0cb4/asyncpg-0.30.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c902a60b52e506d38d7e80e0dd5399f657220f24635fee368117b8b5fce1142e", size = 673162, upload-time = "2024-10-20T00:29:41.88Z" }, { url = "https://files.pythonhosted.org/packages/6e/eb/8b236663f06984f212a087b3e849731f917ab80f84450e943900e8ca4052/asyncpg-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aca1548e43bbb9f0f627a04666fedaca23db0a31a84136ad1f868cb15deb6e3a", size = 637025, upload-time = "2024-10-20T00:29:43.352Z" }, { url = "https://files.pythonhosted.org/packages/cc/57/2dc240bb263d58786cfaa60920779af6e8d32da63ab9ffc09f8312bd7a14/asyncpg-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c2a2ef565400234a633da0eafdce27e843836256d40705d83ab7ec42074efb3", size = 3496243, upload-time = "2024-10-20T00:29:44.922Z" }, { url = "https://files.pythonhosted.org/packages/f4/40/0ae9d061d278b10713ea9021ef6b703ec44698fe32178715a501ac696c6b/asyncpg-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1292b84ee06ac8a2ad8e51c7475aa309245874b61333d97411aab835c4a2f737", size = 3575059, upload-time = "2024-10-20T00:29:46.891Z" }, { url = "https://files.pythonhosted.org/packages/c3/75/d6b895a35a2c6506952247640178e5f768eeb28b2e20299b6a6f1d743ba0/asyncpg-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0f5712350388d0cd0615caec629ad53c81e506b1abaaf8d14c93f54b35e3595a", size = 3473596, upload-time = "2024-10-20T00:29:49.201Z" }, { url = "https://files.pythonhosted.org/packages/c8/e7/3693392d3e168ab0aebb2d361431375bd22ffc7b4a586a0fc060d519fae7/asyncpg-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:db9891e2d76e6f425746c5d2da01921e9a16b5a71a1c905b13f30e12a257c4af", size = 3641632, upload-time = "2024-10-20T00:29:50.768Z" }, + { url = "https://files.pythonhosted.org/packages/32/ea/15670cea95745bba3f0352341db55f506a820b21c619ee66b7d12ea7867d/asyncpg-0.30.0-cp312-cp312-win32.whl", hash = "sha256:68d71a1be3d83d0570049cd1654a9bdfe506e794ecc98ad0873304a9f35e411e", size = 560186, upload-time = "2024-10-20T00:29:52.394Z" }, + { url = "https://files.pythonhosted.org/packages/7e/6b/fe1fad5cee79ca5f5c27aed7bd95baee529c1bf8a387435c8ba4fe53d5c1/asyncpg-0.30.0-cp312-cp312-win_amd64.whl", hash = "sha256:9a0292c6af5c500523949155ec17b7fe01a00ace33b68a476d6b5059f9630305", size = 621064, upload-time = "2024-10-20T00:29:53.757Z" }, { url = "https://files.pythonhosted.org/packages/3a/22/e20602e1218dc07692acf70d5b902be820168d6282e69ef0d3cb920dc36f/asyncpg-0.30.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05b185ebb8083c8568ea8a40e896d5f7af4b8554b64d7719c0eaa1eb5a5c3a70", size = 670373, upload-time = "2024-10-20T00:29:55.165Z" }, { url = "https://files.pythonhosted.org/packages/3d/b3/0cf269a9d647852a95c06eb00b815d0b95a4eb4b55aa2d6ba680971733b9/asyncpg-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c47806b1a8cbb0a0db896f4cd34d89942effe353a5035c62734ab13b9f938da3", size = 634745, upload-time = "2024-10-20T00:29:57.14Z" }, { url = "https://files.pythonhosted.org/packages/8e/6d/a4f31bf358ce8491d2a31bfe0d7bcf25269e80481e49de4d8616c4295a34/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b6fde867a74e8c76c71e2f64f80c64c0f3163e687f1763cfaf21633ec24ec33", size = 3512103, upload-time = "2024-10-20T00:29:58.499Z" }, { url = "https://files.pythonhosted.org/packages/96/19/139227a6e67f407b9c386cb594d9628c6c78c9024f26df87c912fabd4368/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46973045b567972128a27d40001124fbc821c87a6cade040cfcd4fa8a30bcdc4", size = 3592471, upload-time = "2024-10-20T00:30:00.354Z" }, { url = "https://files.pythonhosted.org/packages/67/e4/ab3ca38f628f53f0fd28d3ff20edff1c975dd1cb22482e0061916b4b9a74/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9110df111cabc2ed81aad2f35394a00cadf4f2e0635603db6ebbd0fc896f46a4", size = 3496253, upload-time = "2024-10-20T00:30:02.794Z" }, { url = "https://files.pythonhosted.org/packages/ef/5f/0bf65511d4eeac3a1f41c54034a492515a707c6edbc642174ae79034d3ba/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04ff0785ae7eed6cc138e73fc67b8e51d54ee7a3ce9b63666ce55a0bf095f7ba", size = 3662720, upload-time = "2024-10-20T00:30:04.501Z" }, + { url = "https://files.pythonhosted.org/packages/e7/31/1513d5a6412b98052c3ed9158d783b1e09d0910f51fbe0e05f56cc370bc4/asyncpg-0.30.0-cp313-cp313-win32.whl", hash = "sha256:ae374585f51c2b444510cdf3595b97ece4f233fde739aa14b50e0d64e8a7a590", size = 560404, upload-time = "2024-10-20T00:30:06.537Z" }, + { url = "https://files.pythonhosted.org/packages/c8/a4/cec76b3389c4c5ff66301cd100fe88c318563ec8a520e0b2e792b5b84972/asyncpg-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:f59b430b8e27557c3fb9869222559f7417ced18688375825f8f12302c34e915e", size = 621623, upload-time = "2024-10-20T00:30:09.024Z" }, ] [[package]] @@ -725,7 +733,7 @@ adaptive-crawler = [ all = [ { name = "aiosqlite" }, { name = "apify-fingerprint-datapoints" }, - { name = "asyncpg", marker = "python_full_version < '3.14' and sys_platform != 'win32'" }, + { name = "asyncpg", marker = "python_full_version < '3.14'" }, { name = "beautifulsoup4", extra = ["lxml"] }, { name = "browserforge" }, { name = "cookiecutter" }, @@ -788,7 +796,7 @@ redis = [ { name = "redis", extra = ["hiredis"] }, ] sql-postgres = [ - { name = "asyncpg", marker = "python_full_version < '3.14' and sys_platform != 'win32'" }, + { name = "asyncpg", marker = "python_full_version < '3.14'" }, { name = "sqlalchemy", extra = ["asyncio"] }, ] sql-sqlite = [ @@ -827,7 +835,7 @@ requires-dist = [ { name = "apify-fingerprint-datapoints", marker = "extra == 'adaptive-crawler'", specifier = ">=0.0.2" }, { name = "apify-fingerprint-datapoints", marker = "extra == 'httpx'", specifier = ">=0.0.2" }, { name = "apify-fingerprint-datapoints", marker = "extra == 'playwright'", specifier = ">=0.0.2" }, - { name = "asyncpg", marker = "python_full_version < '3.14' and sys_platform != 'win32' and extra == 'sql-postgres'", specifier = ">=0.24.0" }, + { name = "asyncpg", marker = "python_full_version < '3.14' and extra == 'sql-postgres'", specifier = ">=0.24.0" }, { name = "beautifulsoup4", extras = ["lxml"], marker = "extra == 'beautifulsoup'", specifier = ">=4.12.0" }, { name = "browserforge", marker = "extra == 'adaptive-crawler'", specifier = ">=1.2.3" }, { name = "browserforge", marker = "extra == 'httpx'", specifier = ">=1.2.3" }, From d1097a552affe2553a7e3c9a5578d502935cc849 Mon Sep 17 00:00:00 2001 From: Max Bohomolov Date: Thu, 13 Nov 2025 14:25:15 +0000 Subject: [PATCH 06/11] Add raise error for `SqlStorageClient` for postgresql --- src/crawlee/storage_clients/_sql/_storage_client.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/crawlee/storage_clients/_sql/_storage_client.py b/src/crawlee/storage_clients/_sql/_storage_client.py index 57607d1f74..c1c6f70486 100644 --- a/src/crawlee/storage_clients/_sql/_storage_client.py +++ b/src/crawlee/storage_clients/_sql/_storage_client.py @@ -1,5 +1,6 @@ from __future__ import annotations +import sys import warnings from datetime import timedelta from pathlib import Path @@ -268,6 +269,13 @@ def _get_or_create_engine(self, configuration: Configuration) -> AsyncEngine: 'Unsupported database. Supported: sqlite, postgresql. Consider using a different database.' ) + if 'postgresql' in connection_string and sys.version_info >= (3, 14): + raise ValueError( + 'SqlStorageClient cannot use PostgreSQL with Python 3.14 ' + 'due to asyncpg compatibility limitations. ' + 'Please use Python 3.13 or earlier, or switch to SQLite.' + ) + self._engine = create_async_engine( connection_string, future=True, From 6c6cb8b597dcebea27094d8109e814ae8809b7c4 Mon Sep 17 00:00:00 2001 From: Max Bohomolov Date: Thu, 13 Nov 2025 14:39:42 +0000 Subject: [PATCH 07/11] test --- tests/unit/storage_clients/_redis/test_redis_rq_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/storage_clients/_redis/test_redis_rq_client.py b/tests/unit/storage_clients/_redis/test_redis_rq_client.py index e717632989..5750473cc6 100644 --- a/tests/unit/storage_clients/_redis/test_redis_rq_client.py +++ b/tests/unit/storage_clients/_redis/test_redis_rq_client.py @@ -26,7 +26,7 @@ async def rq_client( suppress_user_warning: None, # noqa: ARG001 ) -> AsyncGenerator[RedisRequestQueueClient, None]: """A fixture for a Redis RQ client.""" - if request.param == 'bloom' and sys.platform == 'win32' and sys.version_info >= (3, 14): + if request.param == 'bloom' and sys.version_info >= (3, 14): pytest.skip('Bloom filters not supported on Windows with Python 3.14 and fakeredis') client = await RedisStorageClient(redis=redis_client, queue_dedup_strategy=request.param).create_rq_client( From a82a82a73cc224570b03af65e7c2f4f3a1db6842 Mon Sep 17 00:00:00 2001 From: Max Bohomolov Date: Thu, 13 Nov 2025 15:18:55 +0000 Subject: [PATCH 08/11] test --- tests/unit/_utils/test_system.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/unit/_utils/test_system.py b/tests/unit/_utils/test_system.py index 3a27f4e1d0..4e147d9c80 100644 --- a/tests/unit/_utils/test_system.py +++ b/tests/unit/_utils/test_system.py @@ -1,7 +1,7 @@ from __future__ import annotations import sys -from multiprocessing import Barrier, Process, Value, set_start_method, synchronize +from multiprocessing import Barrier, Process, Value, synchronize from multiprocessing.shared_memory import SharedMemory from typing import TYPE_CHECKING @@ -38,7 +38,6 @@ def test_memory_estimation_does_not_overestimate_due_to_shared_memory() -> None: equal to additional_memory_size_estimate_per_unshared_memory_child where the additional shared memory is exactly the same as the unshared memory. """ - set_start_method('fork', force=True) estimated_memory_expectation = Value('b', False) # noqa: FBT003 # Common usage pattern for multiprocessing.Value def parent_process() -> None: From 5069045d061bbc6140fe8a1be0f0a89da2157e16 Mon Sep 17 00:00:00 2001 From: Max Bohomolov Date: Thu, 13 Nov 2025 16:00:06 +0000 Subject: [PATCH 09/11] use get_context --- tests/unit/_utils/test_system.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/unit/_utils/test_system.py b/tests/unit/_utils/test_system.py index 4e147d9c80..a9675af224 100644 --- a/tests/unit/_utils/test_system.py +++ b/tests/unit/_utils/test_system.py @@ -1,7 +1,7 @@ from __future__ import annotations import sys -from multiprocessing import Barrier, Process, Value, synchronize +from multiprocessing import get_context, synchronize from multiprocessing.shared_memory import SharedMemory from typing import TYPE_CHECKING @@ -38,7 +38,9 @@ def test_memory_estimation_does_not_overestimate_due_to_shared_memory() -> None: equal to additional_memory_size_estimate_per_unshared_memory_child where the additional shared memory is exactly the same as the unshared memory. """ - estimated_memory_expectation = Value('b', False) # noqa: FBT003 # Common usage pattern for multiprocessing.Value + + ctx = get_context('fork') + estimated_memory_expectation = ctx.Value('b', False) # noqa: FBT003 # Common usage pattern for multiprocessing.Value def parent_process() -> None: extra_memory_size = 1024 * 1024 * 100 # 100 MB @@ -70,8 +72,8 @@ def get_additional_memory_estimation_while_running_processes( *, target: Callable, count: int = 1, use_shared_memory: bool = False ) -> float: processes = [] - ready = Barrier(parties=count + 1) - measured = Barrier(parties=count + 1) + ready = ctx.Barrier(parties=count + 1) + measured = ctx.Barrier(parties=count + 1) shared_memory: None | SharedMemory = None memory_before = get_memory_info().current_size @@ -83,7 +85,7 @@ def get_additional_memory_estimation_while_running_processes( extra_args = [] for _ in range(count): - p = Process(target=target, args=[ready, measured, *extra_args]) + p = ctx.Process(target=target, args=[ready, measured, *extra_args]) p.start() processes.append(p) @@ -129,7 +131,7 @@ def get_additional_memory_estimation_while_running_processes( f'{memory_estimation_difference_ratio=}' ) - process = Process(target=parent_process) + process = ctx.Process(target=parent_process) process.start() process.join() From d55ffe361756f7eb08d91d828e1eeb4f1ed820af Mon Sep 17 00:00:00 2001 From: Max Bohomolov Date: Thu, 13 Nov 2025 16:50:53 +0000 Subject: [PATCH 10/11] limit redis tests only for windows --- tests/unit/storage_clients/_redis/test_redis_rq_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/storage_clients/_redis/test_redis_rq_client.py b/tests/unit/storage_clients/_redis/test_redis_rq_client.py index 5750473cc6..e717632989 100644 --- a/tests/unit/storage_clients/_redis/test_redis_rq_client.py +++ b/tests/unit/storage_clients/_redis/test_redis_rq_client.py @@ -26,7 +26,7 @@ async def rq_client( suppress_user_warning: None, # noqa: ARG001 ) -> AsyncGenerator[RedisRequestQueueClient, None]: """A fixture for a Redis RQ client.""" - if request.param == 'bloom' and sys.version_info >= (3, 14): + if request.param == 'bloom' and sys.platform == 'win32' and sys.version_info >= (3, 14): pytest.skip('Bloom filters not supported on Windows with Python 3.14 and fakeredis') client = await RedisStorageClient(redis=redis_client, queue_dedup_strategy=request.param).create_rq_client( From 5d441f6fa84f96bf6ec7283089b0b0d74d8009b7 Mon Sep 17 00:00:00 2001 From: Max Bohomolov Date: Thu, 13 Nov 2025 21:51:38 +0000 Subject: [PATCH 11/11] add TODO --- pyproject.toml | 2 +- src/crawlee/storage_clients/_sql/_storage_client.py | 1 + tests/unit/storage_clients/_redis/test_redis_rq_client.py | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3f06f5b0d6..f0c58e9719 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ otel = [ ] sql_postgres = [ "sqlalchemy[asyncio]>=2.0.0,<3.0.0", - "asyncpg>=0.24.0; python_version < '3.14'" # Asyncpg has not yet been released with support for Python 3.14. + "asyncpg>=0.24.0; python_version < '3.14'" # TODO: https://github.com/apify/crawlee-python/issues/1555 ] sql_sqlite = [ "sqlalchemy[asyncio]>=2.0.0,<3.0.0", diff --git a/src/crawlee/storage_clients/_sql/_storage_client.py b/src/crawlee/storage_clients/_sql/_storage_client.py index c1c6f70486..d324a17a86 100644 --- a/src/crawlee/storage_clients/_sql/_storage_client.py +++ b/src/crawlee/storage_clients/_sql/_storage_client.py @@ -269,6 +269,7 @@ def _get_or_create_engine(self, configuration: Configuration) -> AsyncEngine: 'Unsupported database. Supported: sqlite, postgresql. Consider using a different database.' ) + # TODO: https://github.com/apify/crawlee-python/issues/1555 if 'postgresql' in connection_string and sys.version_info >= (3, 14): raise ValueError( 'SqlStorageClient cannot use PostgreSQL with Python 3.14 ' diff --git a/tests/unit/storage_clients/_redis/test_redis_rq_client.py b/tests/unit/storage_clients/_redis/test_redis_rq_client.py index e717632989..c343c18e33 100644 --- a/tests/unit/storage_clients/_redis/test_redis_rq_client.py +++ b/tests/unit/storage_clients/_redis/test_redis_rq_client.py @@ -26,6 +26,7 @@ async def rq_client( suppress_user_warning: None, # noqa: ARG001 ) -> AsyncGenerator[RedisRequestQueueClient, None]: """A fixture for a Redis RQ client.""" + # TODO: https://github.com/apify/crawlee-python/issues/1554 if request.param == 'bloom' and sys.platform == 'win32' and sys.version_info >= (3, 14): pytest.skip('Bloom filters not supported on Windows with Python 3.14 and fakeredis')