From 278a1375f10e3d1cf1ea70c11f7d3d5fa00c39d8 Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Wed, 30 Jul 2025 09:21:47 +0200 Subject: [PATCH 01/26] Add `macos` executor for unit tests --- .github/workflows/run_code_checks.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/run_code_checks.yaml b/.github/workflows/run_code_checks.yaml index 9bd2924f2a..44c2f062b8 100644 --- a/.github/workflows/run_code_checks.yaml +++ b/.github/workflows/run_code_checks.yaml @@ -36,6 +36,7 @@ jobs: 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"]' + os: '["ubuntu-latest", "windows-latest", "macos-latest"]' docs_check: name: Docs check From 985d06835f94e3d8ed27774f638d5b8c9577adeb Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Wed, 30 Jul 2025 14:08:38 +0200 Subject: [PATCH 02/26] Update `uv.lock` to include latest `impit` --- uv.lock | 455 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 237 insertions(+), 218 deletions(-) diff --git a/uv.lock b/uv.lock index 386ed49db2..f6e1c5e4c1 100644 --- a/uv.lock +++ b/uv.lock @@ -42,7 +42,7 @@ wheels = [ [[package]] name = "apify-client" -version = "1.12.0" +version = "1.12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "apify-shared" }, @@ -50,9 +50,9 @@ dependencies = [ { name = "httpx" }, { name = "more-itertools" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/73/94/93bc6eca322e642a9f879b0c77005a83ea3977389f6462e1a6a784574d0a/apify_client-1.12.0.tar.gz", hash = "sha256:6b711be930d746a828a456b809abe882cf9e851e9571e5d8307591726e753ea7", size = 346892, upload-time = "2025-06-26T14:50:16.783Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ce/a6/621fdca657a7fb44c3ee4369e5b337224137e4d464459cd66f9c219a6906/apify_client-1.12.1.tar.gz", hash = "sha256:395e99fec7679fe66462dccddba3c0e146836e8298501bb73ac96fe979dc0695", size = 352663, upload-time = "2025-07-30T09:07:06.509Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/93/f1e509e4b1c090fdd2f507caf3e1455067f4ca6d4cbbaf32fbf4b7a2139f/apify_client-1.12.0-py3-none-any.whl", hash = "sha256:be24c4a069af4d9b362452ae4d973142187633bbb296f0f6a85021cb4b0bb611", size = 82810, upload-time = "2025-06-26T14:50:15.288Z" }, + { url = "https://files.pythonhosted.org/packages/6e/c2/c7a1568aec801aa84bbaf93ab390b6bd57e850be30443365370ca3a9ccdc/apify_client-1.12.1-py3-none-any.whl", hash = "sha256:0b331677697dfa1038d17154284fc0bad1b18ba52ab792beb53711af81eac30a", size = 83218, upload-time = "2025-07-30T09:07:04.513Z" }, ] [[package]] @@ -484,87 +484,87 @@ wheels = [ [[package]] name = "coverage" -version = "7.10.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6d/8f/6ac7fbb29e35645065f7be835bfe3e0cce567f80390de2f3db65d83cb5e3/coverage-7.10.0.tar.gz", hash = "sha256:2768885aef484b5dcde56262cbdfba559b770bfc46994fe9485dc3614c7a5867", size = 819816, upload-time = "2025-07-24T16:53:00.896Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5d/f6/b2366476b1f48134757f2a42aaf00e7ce8e734eea5f3cf022df113116174/coverage-7.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cbd823f7ea5286c26406ad9e54268544d82f3d1cadb6d4f3b85e9877f0cab1ef", size = 214813, upload-time = "2025-07-24T16:50:18.937Z" }, - { url = "https://files.pythonhosted.org/packages/19/d1/7e26bb4c41ed1b9aca4550187ca42557d79c70d318414a703d814858eacb/coverage-7.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ab3f7a5dbaab937df0b9e9e8ec6eab235ba9a6f29d71fd3b24335affaed886cc", size = 215206, upload-time = "2025-07-24T16:50:21.788Z" }, - { url = "https://files.pythonhosted.org/packages/df/71/d5ae128557c8d0ce0156eb1e980e5c6e6f7e54ef3e998c87ab4b3679ff45/coverage-7.10.0-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:8c63aaf850523d8cbe3f5f1a5c78f689b223797bef902635f2493ab43498f36c", size = 242171, upload-time = "2025-07-24T16:50:23.483Z" }, - { url = "https://files.pythonhosted.org/packages/af/87/d586a627e3b61cfe631ebcf3d8a38bf9085142800d2ac434bc20f3699880/coverage-7.10.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4c3133ce3fa84023f7c6921c4dca711be0b658784c5a51a797168229eae26172", size = 243431, upload-time = "2025-07-24T16:50:24.913Z" }, - { url = "https://files.pythonhosted.org/packages/55/cc/ff5c6f4f99a987ebd18a3350194377c7cefee9ddd6e532ede83a0a1f332c/coverage-7.10.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3747d1d0af85b17d3a156cd30e4bbacf893815e846dc6c07050e9769da2b138e", size = 245288, upload-time = "2025-07-24T16:50:26.673Z" }, - { url = "https://files.pythonhosted.org/packages/94/d9/2758e73d7fe496c04dd715af8bb8856354a1ad4cc11553d9096c4b35dc86/coverage-7.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:241923b350437f6a7cb343d9df72998305ef940c3c40009f06e05029a047677c", size = 243235, upload-time = "2025-07-24T16:50:28.505Z" }, - { url = "https://files.pythonhosted.org/packages/9c/9b/3c273dde651d83484992d7e7bcd9cd84a363f01026caf69716390bd79e0d/coverage-7.10.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:13e82e499309307104d58ac66f9eed237f7aaceab4325416645be34064d9a2be", size = 241909, upload-time = "2025-07-24T16:50:30.38Z" }, - { url = "https://files.pythonhosted.org/packages/5b/7c/006d9f66035c4d414ea642d990854a30c23145551315bd0b38100daee168/coverage-7.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bf73cdde4f6c9cd4457b00bf1696236796ac3a241f859a55e0f84a4c58326a7f", size = 242202, upload-time = "2025-07-24T16:50:32.199Z" }, - { url = "https://files.pythonhosted.org/packages/8a/42/80d8747f77c63593a2114c7299df52f7568168e4fd882d7d5ebe8181564f/coverage-7.10.0-cp310-cp310-win32.whl", hash = "sha256:2396e13275b37870a3345f58bce8b15a7e0a985771d13a4b16ce9129954e07d6", size = 217311, upload-time = "2025-07-24T16:50:33.598Z" }, - { url = "https://files.pythonhosted.org/packages/e3/8b/fe04c3851e5d290524f563a8a564c7e5dcd6b5ca35ed689ce662346de230/coverage-7.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:9d45c7c71fb3d2da92ab893602e3f28f2d1560cec765a27e1824a6e0f7e92cfd", size = 218199, upload-time = "2025-07-24T16:50:36.751Z" }, - { url = "https://files.pythonhosted.org/packages/f5/5d/0d1ee021439e3b8b1e86ba92465f5a8d8e15b0222dcdd705606ef089f4fe/coverage-7.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4abc01843581a6f9dd72d4d15761861190973a2305416639435ef509288f7a04", size = 214934, upload-time = "2025-07-24T16:50:38.173Z" }, - { url = "https://files.pythonhosted.org/packages/f2/b2/1e0727327e473aa1a68ca1c9922818a06061d05d44e0c5330109d091b525/coverage-7.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2093297773111d7d748fe4a99b68747e57994531fb5c57bbe439af17c11c169", size = 215320, upload-time = "2025-07-24T16:50:39.617Z" }, - { url = "https://files.pythonhosted.org/packages/84/17/d231e37236863ae3bed7c51615af6b6fc89639c88adf35766d2880dcd7c7/coverage-7.10.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:58240e27815bf105bd975c2fd42e700839f93d5aad034ef976411193ca32dbfd", size = 245321, upload-time = "2025-07-24T16:50:41.544Z" }, - { url = "https://files.pythonhosted.org/packages/95/77/a285aba35bf6ec12c466474931410ef0e6fa85542169009443868e98820a/coverage-7.10.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d019eac999b40ad48521ea057958b07a9f549c0c6d257a20e5c7c4ba91af8d1c", size = 247155, upload-time = "2025-07-24T16:50:43.358Z" }, - { url = "https://files.pythonhosted.org/packages/7b/82/50512eafdd5938a7aa1550014e37fa1c2ca85516bfd85ffeb2f03eff052a/coverage-7.10.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:35e0a1f5454bc80faf4ceab10d1d48f025f92046c9c0f3bec2e1a9dda55137f8", size = 249320, upload-time = "2025-07-24T16:50:44.98Z" }, - { url = "https://files.pythonhosted.org/packages/de/7b/0ec1dc75c8f4d940d03d477b1e07269b4804dcab74ad1e294d40310aba47/coverage-7.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a93dd7759c416dd1cc754123b926d065055cb9a33b6699e64a1e5bdfae1ff459", size = 247047, upload-time = "2025-07-24T16:50:46.482Z" }, - { url = "https://files.pythonhosted.org/packages/d9/5b/40f9b78ae98c2f511a2b062660906e126aadcd35870b9190a4f10f2820ae/coverage-7.10.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7b3d737266048368a6ffd68f1ecd662c54de56535c82eb8f98a55ac216a72cbd", size = 245078, upload-time = "2025-07-24T16:50:47.904Z" }, - { url = "https://files.pythonhosted.org/packages/d6/f6/672c2a728e77846be7fcc4baaa003e0df86a2174aeb8921d132c14c333d4/coverage-7.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:93227c2707cb0effd9163cd0d8f0d9ab628982f7a3e915d6d64c7107867b9a07", size = 245686, upload-time = "2025-07-24T16:50:49.461Z" }, - { url = "https://files.pythonhosted.org/packages/a1/f3/fa078f0bfae7f0e6b14c426f9cb095f4809314d926c89b9a2641fb4ca482/coverage-7.10.0-cp311-cp311-win32.whl", hash = "sha256:69270af3014ab3058ad6108c6d0e218166f568b5a7a070dc3d62c0a63aca1c4d", size = 217350, upload-time = "2025-07-24T16:50:50.884Z" }, - { url = "https://files.pythonhosted.org/packages/1a/40/eefc3ebb9e458e3dc5db00e6b838969375577a09a8a39986d79cfa283175/coverage-7.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:43c16bbb661a7b4dafac0ab69e44d6dbcc6a64c4d93aefd89edc6f8911b6ab4a", size = 218235, upload-time = "2025-07-24T16:50:52.369Z" }, - { url = "https://files.pythonhosted.org/packages/e5/b8/3b53890c3ad52279eaea594a86bceaf04fcc0aed16856ff81531f75735f4/coverage-7.10.0-cp311-cp311-win_arm64.whl", hash = "sha256:14e7c23fcb74ed808efb4eb48fcd25a759f0e20f685f83266d1df174860e4733", size = 216668, upload-time = "2025-07-24T16:50:53.937Z" }, - { url = "https://files.pythonhosted.org/packages/b6/b4/7b419bb368c9f0b88889cb24805164f6e5550d7183fb59524f6173e0cf0b/coverage-7.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a2adcfdaf3b4d69b0c64ad024fe9dd6996782b52790fb6033d90f36f39e287df", size = 215124, upload-time = "2025-07-24T16:50:55.46Z" }, - { url = "https://files.pythonhosted.org/packages/f4/15/d862a806734c7e50fd5350cef18e22832ba3cdad282ca5660d6fd49def92/coverage-7.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2d7b27c2c0840e8eeff3f1963782bd9d3bc767488d2e67a31de18d724327f9f6", size = 215364, upload-time = "2025-07-24T16:50:57.849Z" }, - { url = "https://files.pythonhosted.org/packages/a6/93/4671ca5b2f3650c961a01252cbad96cb41f7c0c2b85c6062f27740a66b06/coverage-7.10.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0ed50429786e935517570b08576a661fd79032e6060985ab492b9d39ba8e66ee", size = 246369, upload-time = "2025-07-24T16:50:59.505Z" }, - { url = "https://files.pythonhosted.org/packages/64/79/2ca676c712d0540df0d7957a4266232980b60858a7a654846af1878cfde0/coverage-7.10.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7171c139ab6571d70460ecf788b1dcaf376bfc75a42e1946b8c031d062bbbad4", size = 248798, upload-time = "2025-07-24T16:51:01.105Z" }, - { url = "https://files.pythonhosted.org/packages/82/c5/67e000b03ba5291f915ddd6ba7c3333e4fdee9ba003b914c8f8f2d966dfe/coverage-7.10.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a726aac7e6e406e403cdee4c443a13aed3ea3d67d856414c5beacac2e70c04e", size = 250260, upload-time = "2025-07-24T16:51:02.761Z" }, - { url = "https://files.pythonhosted.org/packages/9d/76/196783c425b5633db5c789b02a023858377bd73e4db4c805c2503cc42bbf/coverage-7.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2886257481a14e953e96861a00c0fe7151117a523f0470a51e392f00640bba03", size = 248171, upload-time = "2025-07-24T16:51:04.651Z" }, - { url = "https://files.pythonhosted.org/packages/83/1f/bf86c75f42de3641b4bbeab9712ec2815a3a8f5939768077245a492fad9f/coverage-7.10.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:536578b79521e59c385a2e0a14a5dc2a8edd58761a966d79368413e339fc9535", size = 246368, upload-time = "2025-07-24T16:51:06.16Z" }, - { url = "https://files.pythonhosted.org/packages/2d/95/bfc9a3abef0b160404438e82ec778a0f38660c66a4b0ed94d0417d4d2290/coverage-7.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77fae95558f7804a9ceefabf3c38ad41af1da92b39781b87197c6440dcaaa967", size = 247578, upload-time = "2025-07-24T16:51:07.632Z" }, - { url = "https://files.pythonhosted.org/packages/c6/7e/4fb2a284d56fe2a3ba0c76806923014854a64e503dc8ce21e5a2e6497eea/coverage-7.10.0-cp312-cp312-win32.whl", hash = "sha256:97803e14736493eb029558e1502fe507bd6a08af277a5c8eeccf05c3e970cb84", size = 217521, upload-time = "2025-07-24T16:51:09.56Z" }, - { url = "https://files.pythonhosted.org/packages/f7/30/3ab51058b75e9931fc48594d79888396cf009910fabebe12a6a636ab7f9e/coverage-7.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:4c73ab554e54ffd38d114d6bc4a7115fb0c840cf6d8622211bee3da26e4bd25d", size = 218308, upload-time = "2025-07-24T16:51:11.115Z" }, - { url = "https://files.pythonhosted.org/packages/b0/34/2adc74fd132eaa1873b1688acb906b477216074ed8a37e90426eca6d2900/coverage-7.10.0-cp312-cp312-win_arm64.whl", hash = "sha256:3ae95d5a9aedab853641026b71b2ddd01983a0a7e9bf870a20ef3c8f5d904699", size = 216706, upload-time = "2025-07-24T16:51:12.632Z" }, - { url = "https://files.pythonhosted.org/packages/fc/a7/a47f64718c2229b7860a334edd4e6ff41ec8513f3d3f4246284610344392/coverage-7.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d883fee92b9245c0120fa25b5d36de71ccd4cfc29735906a448271e935d8d86d", size = 215143, upload-time = "2025-07-24T16:51:14.105Z" }, - { url = "https://files.pythonhosted.org/packages/ea/86/14d76a409e9ffab10d5aece73ac159dbd102fc56627e203413bfc6d53b24/coverage-7.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c87e59e88268d30e33d3665ede4fbb77b513981a2df0059e7c106ca3de537586", size = 215401, upload-time = "2025-07-24T16:51:15.978Z" }, - { url = "https://files.pythonhosted.org/packages/f4/b3/fb5c28148a19035a3877fac4e40b044a4c97b24658c980bcf7dff18bfab8/coverage-7.10.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f669d969f669a11d6ceee0b733e491d9a50573eb92a71ffab13b15f3aa2665d4", size = 245949, upload-time = "2025-07-24T16:51:17.628Z" }, - { url = "https://files.pythonhosted.org/packages/6d/95/357559ecfe73970d2023845797361e6c2e6c2c05f970073fff186fe19dd7/coverage-7.10.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9582bd6c6771300a847d328c1c4204e751dbc339a9e249eecdc48cada41f72e6", size = 248295, upload-time = "2025-07-24T16:51:19.46Z" }, - { url = "https://files.pythonhosted.org/packages/7e/58/bac5bc43085712af201f76a24733895331c475e5ddda88ac36c1332a65e6/coverage-7.10.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:91f97e9637dc7977842776fdb7ad142075d6fa40bc1b91cb73685265e0d31d32", size = 249733, upload-time = "2025-07-24T16:51:21.518Z" }, - { url = "https://files.pythonhosted.org/packages/b2/db/104b713b3b74752ee365346677fb104765923982ae7bd93b95ca41fe256b/coverage-7.10.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ae4fa92b6601a62367c6c9967ad32ad4e28a89af54b6bb37d740946b0e0534dd", size = 247943, upload-time = "2025-07-24T16:51:23.194Z" }, - { url = "https://files.pythonhosted.org/packages/32/4f/bef25c797c9496cf31ae9cfa93ce96b4414cacf13688e4a6000982772fd5/coverage-7.10.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:3a5cc8b97473e7b3623dd17a42d2194a2b49de8afecf8d7d03c8987237a9552c", size = 245914, upload-time = "2025-07-24T16:51:24.766Z" }, - { url = "https://files.pythonhosted.org/packages/36/6b/b3efa0b506dbb9a37830d6dc862438fe3ad2833c5f889152bce24d9577cf/coverage-7.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dc1cbb7f623250e047c32bd7aa1bb62ebc62608d5004d74df095e1059141ac88", size = 247296, upload-time = "2025-07-24T16:51:26.361Z" }, - { url = "https://files.pythonhosted.org/packages/1f/aa/95a845266aeacab4c57b08e0f4e0e2899b07809a18fd0c1ddef2ac2c9138/coverage-7.10.0-cp313-cp313-win32.whl", hash = "sha256:1380cc5666d778e77f1587cd88cc317158111f44d54c0dd3975f0936993284e0", size = 217566, upload-time = "2025-07-24T16:51:28.961Z" }, - { url = "https://files.pythonhosted.org/packages/a0/d1/27b6e5073a8026b9e0f4224f1ac53217ce589a4cdab1bee878f23bff64f0/coverage-7.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:bf03cf176af098ee578b754a03add4690b82bdfe070adfb5d192d0b1cd15cf82", size = 218337, upload-time = "2025-07-24T16:51:31.45Z" }, - { url = "https://files.pythonhosted.org/packages/c7/06/0e3ba498b11e2245fd96bd7e8dcdf90e1dd36d57f49f308aa650ff0561b8/coverage-7.10.0-cp313-cp313-win_arm64.whl", hash = "sha256:8041c78cd145088116db2329b2fb6e89dc338116c962fbe654b7e9f5d72ab957", size = 216740, upload-time = "2025-07-24T16:51:33.317Z" }, - { url = "https://files.pythonhosted.org/packages/44/8b/11529debbe3e6b39ef6e7c8912554724adc6dc10adbb617a855ecfd387eb/coverage-7.10.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:37cc2c06052771f48651160c080a86431884db9cd62ba622cab71049b90a95b3", size = 215866, upload-time = "2025-07-24T16:51:35.339Z" }, - { url = "https://files.pythonhosted.org/packages/9c/6d/d8981310879e395f39af66536665b75135b1bc88dd21c7764e3340e9ce69/coverage-7.10.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:91f37270b16178b05fa107d85713d29bf21606e37b652d38646eef5f2dfbd458", size = 216083, upload-time = "2025-07-24T16:51:36.932Z" }, - { url = "https://files.pythonhosted.org/packages/c3/84/93295402de002de8b8c953bf6a1f19687174c4db7d44c1e85ffc153a772d/coverage-7.10.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f9b0b0168864d09bcb9a3837548f75121645c4cfd0efce0eb994c221955c5b10", size = 257320, upload-time = "2025-07-24T16:51:38.734Z" }, - { url = "https://files.pythonhosted.org/packages/02/5c/d0540db4869954dac0f69ad709adcd51f3a73ab11fcc9435ee76c518944a/coverage-7.10.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:df0be435d3b616e7d3ee3f9ebbc0d784a213986fe5dff9c6f1042ee7cfd30157", size = 259182, upload-time = "2025-07-24T16:51:40.463Z" }, - { url = "https://files.pythonhosted.org/packages/59/b2/d7d57a41a15ca4b47290862efd6b596d0a185bfd26f15d04db9f238aa56c/coverage-7.10.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:35e9aba1c4434b837b1d567a533feba5ce205e8e91179c97974b28a14c23d3a0", size = 261322, upload-time = "2025-07-24T16:51:42.44Z" }, - { url = "https://files.pythonhosted.org/packages/16/92/fd828ae411b3da63673305617b6fbeccc09feb7dfe397d164f55a65cd880/coverage-7.10.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a0b0c481e74dfad631bdc2c883e57d8b058e5c90ba8ef087600995daf7bbec18", size = 258914, upload-time = "2025-07-24T16:51:44.115Z" }, - { url = "https://files.pythonhosted.org/packages/28/49/4aa5f5464b2e1215640c0400c5b007e7f5cdade8bf39c55c33b02f3a8c7f/coverage-7.10.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8aec1b7c8922808a433c13cd44ace6fceac0609f4587773f6c8217a06102674b", size = 257051, upload-time = "2025-07-24T16:51:45.75Z" }, - { url = "https://files.pythonhosted.org/packages/1e/5a/ded2346098c7f48ff6e135b5005b97de4cd9daec5c39adb4ecf3a60967da/coverage-7.10.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:04ec59ceb3a594af0927f2e0d810e1221212abd9a2e6b5b917769ff48760b460", size = 257869, upload-time = "2025-07-24T16:51:47.41Z" }, - { url = "https://files.pythonhosted.org/packages/46/66/e06cedb8fc7d1c96630b2f549b8cdc084e2623dcc70c900cb3b705a36a60/coverage-7.10.0-cp313-cp313t-win32.whl", hash = "sha256:b6871e62d29646eb9b3f5f92def59e7575daea1587db21f99e2b19561187abda", size = 218243, upload-time = "2025-07-24T16:51:49.136Z" }, - { url = "https://files.pythonhosted.org/packages/e7/1e/e84dd5ff35ed066bd6150e5c26fe0061ded2c59c209fd4f18db0650766c0/coverage-7.10.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff99cff2be44f78920b76803f782e91ffb46ccc7fa89eccccc0da3ca94285b64", size = 219334, upload-time = "2025-07-24T16:51:50.789Z" }, - { url = "https://files.pythonhosted.org/packages/b7/e0/b7b60b5dbc4e88eac0a0e9d5b4762409a59b29bf4e772b3509c8543ccaba/coverage-7.10.0-cp313-cp313t-win_arm64.whl", hash = "sha256:3246b63501348fe47299d12c47a27cfc221cfbffa1c2d857bcc8151323a4ae4f", size = 217196, upload-time = "2025-07-24T16:51:52.599Z" }, - { url = "https://files.pythonhosted.org/packages/15/c1/597b4fa7d6c0861d4916c4fe5c45bf30c11b31a3b07fedffed23dec5f765/coverage-7.10.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:1f628d91f941a375b4503cb486148dbeeffb48e17bc080e0f0adfee729361574", size = 215139, upload-time = "2025-07-24T16:51:54.381Z" }, - { url = "https://files.pythonhosted.org/packages/18/47/07973dcad0161355cf01ff0023ab34466b735deb460a178f37163d7c800e/coverage-7.10.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3a0e101d5af952d233557e445f42ebace20b06b4ceb615581595ced5386caa78", size = 215419, upload-time = "2025-07-24T16:51:56.341Z" }, - { url = "https://files.pythonhosted.org/packages/f6/f8/c65127782da312084ef909c1531226c869bfe22dac8b92d9c609d8150131/coverage-7.10.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:ec4c1abbcc53f9f650acb14ea71725d88246a9e14ed42f8dd1b4e1b694e9d842", size = 245917, upload-time = "2025-07-24T16:51:58.045Z" }, - { url = "https://files.pythonhosted.org/packages/05/97/a7f2fe79b6ae759ccc8740608cf9686ae406cc5e5591947ebbf1d679a325/coverage-7.10.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9c95f3a7f041b4cc68a8e3fecfa6366170c13ac773841049f1cd19c8650094e0", size = 248225, upload-time = "2025-07-24T16:51:59.745Z" }, - { url = "https://files.pythonhosted.org/packages/7f/d3/d2e1496d7ac3340356c5de582e08e14b02933e254924f79d18e9749269d8/coverage-7.10.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a2cd597b69c16d24e310611f2ed6fcfb8f09429316038c03a57e7b4f5345244", size = 249844, upload-time = "2025-07-24T16:52:01.799Z" }, - { url = "https://files.pythonhosted.org/packages/e5/7e/e26d966c9cae62500e5924107974ede2e985f7d119d10ed44d102998e509/coverage-7.10.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:5e18591906a40c2b3609196c9879136aa4a47c5405052ca6b065ab10cb0b71d0", size = 247871, upload-time = "2025-07-24T16:52:03.797Z" }, - { url = "https://files.pythonhosted.org/packages/59/95/6a372a292dfb9d6e2cc019fc50878f7a6a5fbe704604018d7c5c1dbffb2d/coverage-7.10.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:485c55744252ed3f300cc1a0f5f365e684a0f2651a7aed301f7a67125906b80e", size = 245714, upload-time = "2025-07-24T16:52:05.966Z" }, - { url = "https://files.pythonhosted.org/packages/02/7f/63da22b7bc4e82e2c1df7755223291fc94fb01942cfe75e19f2bed96129e/coverage-7.10.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4dabea1516e5b0e9577282b149c8015e4dceeb606da66fb8d9d75932d5799bf5", size = 247131, upload-time = "2025-07-24T16:52:07.661Z" }, - { url = "https://files.pythonhosted.org/packages/3d/af/883272555e34872879f48daea4207489cb36df249e3069e6a8a664dc6ba6/coverage-7.10.0-cp314-cp314-win32.whl", hash = "sha256:ac455f0537af22333fdc23b824cff81110dff2d47300bb2490f947b7c9a16017", size = 217804, upload-time = "2025-07-24T16:52:09.328Z" }, - { url = "https://files.pythonhosted.org/packages/90/f6/7afc3439994b7f7311d858438d49eef8b06eadbf2322502d921a110fae1e/coverage-7.10.0-cp314-cp314-win_amd64.whl", hash = "sha256:b3c94b532f52f95f36fbfde3e178510a4d04eea640b484b2fe8f1491338dc653", size = 218596, upload-time = "2025-07-24T16:52:11.038Z" }, - { url = "https://files.pythonhosted.org/packages/0b/99/7c715cfa155609ee3e71bc81b4d1265e1a9b79ad00cc3d19917ea736cbac/coverage-7.10.0-cp314-cp314-win_arm64.whl", hash = "sha256:2f807f2c3a9da99c80dfa73f09ef5fc3bd21e70c73ba1c538f23396a3a772252", size = 216960, upload-time = "2025-07-24T16:52:12.77Z" }, - { url = "https://files.pythonhosted.org/packages/59/18/5cb476346d3842f2e42cd92614a91921ebad38aa97aba63f2aab51919e35/coverage-7.10.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:0a889ef25215990f65073c32cadf37483363a6a22914186dedc15a6b1a597d50", size = 215881, upload-time = "2025-07-24T16:52:14.492Z" }, - { url = "https://files.pythonhosted.org/packages/80/1b/c066d6836f4c1940a8df14894a5ec99db362838fdd9eee9fb7efe0e561d2/coverage-7.10.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:39c638ecf3123805bacbf71aff8091e93af490c676fca10ab4e442375076e483", size = 216087, upload-time = "2025-07-24T16:52:16.216Z" }, - { url = "https://files.pythonhosted.org/packages/1d/57/f0996fd468e70d4d24d69eba10ecc2b913c2e85d9f3c1bb2075ad7554c05/coverage-7.10.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f2f2c0df0cbcf7dffa14f88a99c530cdef3f4fcfe935fa4f95d28be2e7ebc570", size = 257408, upload-time = "2025-07-24T16:52:18.136Z" }, - { url = "https://files.pythonhosted.org/packages/36/78/c9f308b2b986cc685d4964a3b829b053817a07d7ba14ff124cf06154402e/coverage-7.10.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:048d19a5d641a2296745ab59f34a27b89a08c48d6d432685f22aac0ec1ea447f", size = 259373, upload-time = "2025-07-24T16:52:20.923Z" }, - { url = "https://files.pythonhosted.org/packages/99/13/192827b71da71255d3554cb7dc289bce561cb281bda27e1b0dd19d88e47d/coverage-7.10.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1209b65d302d7a762004be37ab9396cbd8c99525ed572bdf455477e3a9449e06", size = 261495, upload-time = "2025-07-24T16:52:23.018Z" }, - { url = "https://files.pythonhosted.org/packages/0d/5c/cf4694353405abbb440a94468df8e5c4dbf884635da1f056b43be7284d28/coverage-7.10.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e44aa79a36a7a0aec6ea109905a4a7c28552d90f34e5941b36217ae9556657d5", size = 258970, upload-time = "2025-07-24T16:52:25.685Z" }, - { url = "https://files.pythonhosted.org/packages/c7/83/fb45dac65c42eff6ce4153fe51b9f2a9fdc832ce57b7902ab9ff216c3faa/coverage-7.10.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:96124be864b89395770c9a14652afcddbcdafb99466f53a9281c51d1466fb741", size = 257046, upload-time = "2025-07-24T16:52:27.778Z" }, - { url = "https://files.pythonhosted.org/packages/60/95/577dc757c01f493a1951157475dd44561c82084387f12635974fb62e848c/coverage-7.10.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:aad222e841f94b42bd1d6be71737fade66943853f0807cf87887c88f70883a2a", size = 257946, upload-time = "2025-07-24T16:52:29.931Z" }, - { url = "https://files.pythonhosted.org/packages/da/5a/14b1be12e3a71fcf4031464ae285dab7df0939976236d0462c4c5382d317/coverage-7.10.0-cp314-cp314t-win32.whl", hash = "sha256:0eed5354d28caa5c8ad60e07e938f253e4b2810ea7dd56784339b6ce98b6f104", size = 218602, upload-time = "2025-07-24T16:52:32.074Z" }, - { url = "https://files.pythonhosted.org/packages/a0/8d/c32890c0f4f7f71b8d4a1074ef8e9ef28e9b9c2f9fd0e2896f2cc32593bf/coverage-7.10.0-cp314-cp314t-win_amd64.whl", hash = "sha256:3da35f9980058acb960b2644527cc3911f1e00f94d309d704b309fa984029109", size = 219720, upload-time = "2025-07-24T16:52:34.745Z" }, - { url = "https://files.pythonhosted.org/packages/22/f7/e5cc13338aa5e2780b6226fb50e9bd8f3f88da85a4b2951447b4b51109a4/coverage-7.10.0-cp314-cp314t-win_arm64.whl", hash = "sha256:cb9e138dfa8a4b5c52c92a537651e2ca4f2ca48d8cb1bc01a2cbe7a5773c2426", size = 217374, upload-time = "2025-07-24T16:52:36.974Z" }, - { url = "https://files.pythonhosted.org/packages/09/df/7c34bada8ace39f688b3bd5bc411459a20a3204ccb0984c90169a80a9366/coverage-7.10.0-py3-none-any.whl", hash = "sha256:310a786330bb0463775c21d68e26e79973839b66d29e065c5787122b8dd4489f", size = 206777, upload-time = "2025-07-24T16:52:59.009Z" }, +version = "7.10.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/87/0e/66dbd4c6a7f0758a8d18044c048779ba21fb94856e1edcf764bd5403e710/coverage-7.10.1.tar.gz", hash = "sha256:ae2b4856f29ddfe827106794f3589949a57da6f0d38ab01e24ec35107979ba57", size = 819938, upload-time = "2025-07-27T14:13:39.045Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/e7/0f4e35a15361337529df88151bddcac8e8f6d6fd01da94a4b7588901c2fe/coverage-7.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1c86eb388bbd609d15560e7cc0eb936c102b6f43f31cf3e58b4fd9afe28e1372", size = 214627, upload-time = "2025-07-27T14:11:01.211Z" }, + { url = "https://files.pythonhosted.org/packages/e0/fd/17872e762c408362072c936dbf3ca28c67c609a1f5af434b1355edcb7e12/coverage-7.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6b4ba0f488c1bdb6bd9ba81da50715a372119785458831c73428a8566253b86b", size = 215015, upload-time = "2025-07-27T14:11:03.988Z" }, + { url = "https://files.pythonhosted.org/packages/54/50/c9d445ba38ee5f685f03876c0f8223469e2e46c5d3599594dca972b470c8/coverage-7.10.1-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:083442ecf97d434f0cb3b3e3676584443182653da08b42e965326ba12d6b5f2a", size = 241995, upload-time = "2025-07-27T14:11:05.983Z" }, + { url = "https://files.pythonhosted.org/packages/cc/83/4ae6e0f60376af33de543368394d21b9ac370dc86434039062ef171eebf8/coverage-7.10.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c1a40c486041006b135759f59189385da7c66d239bad897c994e18fd1d0c128f", size = 243253, upload-time = "2025-07-27T14:11:07.424Z" }, + { url = "https://files.pythonhosted.org/packages/49/90/17a4d9ac7171be364ce8c0bb2b6da05e618ebfe1f11238ad4f26c99f5467/coverage-7.10.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3beb76e20b28046989300c4ea81bf690df84ee98ade4dc0bbbf774a28eb98440", size = 245110, upload-time = "2025-07-27T14:11:09.152Z" }, + { url = "https://files.pythonhosted.org/packages/e1/f7/edc3f485d536ed417f3af2b4969582bcb5fab456241721825fa09354161e/coverage-7.10.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bc265a7945e8d08da28999ad02b544963f813a00f3ed0a7a0ce4165fd77629f8", size = 243056, upload-time = "2025-07-27T14:11:10.586Z" }, + { url = "https://files.pythonhosted.org/packages/58/2c/c4c316a57718556b8d0cc8304437741c31b54a62934e7c8c551a7915c2f4/coverage-7.10.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:47c91f32ba4ac46f1e224a7ebf3f98b4b24335bad16137737fe71a5961a0665c", size = 241731, upload-time = "2025-07-27T14:11:12.145Z" }, + { url = "https://files.pythonhosted.org/packages/f7/93/c78e144c6f086043d0d7d9237c5b880e71ac672ed2712c6f8cca5544481f/coverage-7.10.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1a108dd78ed185020f66f131c60078f3fae3f61646c28c8bb4edd3fa121fc7fc", size = 242023, upload-time = "2025-07-27T14:11:13.573Z" }, + { url = "https://files.pythonhosted.org/packages/8f/e1/34e8505ca81fc144a612e1cc79fadd4a78f42e96723875f4e9f1f470437e/coverage-7.10.1-cp310-cp310-win32.whl", hash = "sha256:7092cc82382e634075cc0255b0b69cb7cada7c1f249070ace6a95cb0f13548ef", size = 217130, upload-time = "2025-07-27T14:11:15.11Z" }, + { url = "https://files.pythonhosted.org/packages/75/2b/82adfce6edffc13d804aee414e64c0469044234af9296e75f6d13f92f6a2/coverage-7.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:ac0c5bba938879c2fc0bc6c1b47311b5ad1212a9dcb8b40fe2c8110239b7faed", size = 218015, upload-time = "2025-07-27T14:11:16.836Z" }, + { url = "https://files.pythonhosted.org/packages/20/8e/ef088112bd1b26e2aa931ee186992b3e42c222c64f33e381432c8ee52aae/coverage-7.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b45e2f9d5b0b5c1977cb4feb5f594be60eb121106f8900348e29331f553a726f", size = 214747, upload-time = "2025-07-27T14:11:18.217Z" }, + { url = "https://files.pythonhosted.org/packages/2d/76/a1e46f3c6e0897758eb43af88bb3c763cb005f4950769f7b553e22aa5f89/coverage-7.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a7a4d74cb0f5e3334f9aa26af7016ddb94fb4bfa11b4a573d8e98ecba8c34f1", size = 215128, upload-time = "2025-07-27T14:11:19.706Z" }, + { url = "https://files.pythonhosted.org/packages/78/4d/903bafb371a8c887826ecc30d3977b65dfad0e1e66aa61b7e173de0828b0/coverage-7.10.1-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d4b0aab55ad60ead26159ff12b538c85fbab731a5e3411c642b46c3525863437", size = 245140, upload-time = "2025-07-27T14:11:21.261Z" }, + { url = "https://files.pythonhosted.org/packages/55/f1/1f8f09536f38394a8698dd08a0e9608a512eacee1d3b771e2d06397f77bf/coverage-7.10.1-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:dcc93488c9ebd229be6ee1f0d9aad90da97b33ad7e2912f5495804d78a3cd6b7", size = 246977, upload-time = "2025-07-27T14:11:23.15Z" }, + { url = "https://files.pythonhosted.org/packages/57/cc/ed6bbc5a3bdb36ae1bca900bbbfdcb23b260ef2767a7b2dab38b92f61adf/coverage-7.10.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa309df995d020f3438407081b51ff527171cca6772b33cf8f85344b8b4b8770", size = 249140, upload-time = "2025-07-27T14:11:24.743Z" }, + { url = "https://files.pythonhosted.org/packages/10/f5/e881ade2d8e291b60fa1d93d6d736107e940144d80d21a0d4999cff3642f/coverage-7.10.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cfb8b9d8855c8608f9747602a48ab525b1d320ecf0113994f6df23160af68262", size = 246869, upload-time = "2025-07-27T14:11:26.156Z" }, + { url = "https://files.pythonhosted.org/packages/53/b9/6a5665cb8996e3cd341d184bb11e2a8edf01d8dadcf44eb1e742186cf243/coverage-7.10.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:320d86da829b012982b414c7cdda65f5d358d63f764e0e4e54b33097646f39a3", size = 244899, upload-time = "2025-07-27T14:11:27.622Z" }, + { url = "https://files.pythonhosted.org/packages/27/11/24156776709c4e25bf8a33d6bb2ece9a9067186ddac19990f6560a7f8130/coverage-7.10.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dc60ddd483c556590da1d9482a4518292eec36dd0e1e8496966759a1f282bcd0", size = 245507, upload-time = "2025-07-27T14:11:29.544Z" }, + { url = "https://files.pythonhosted.org/packages/43/db/a6f0340b7d6802a79928659c9a32bc778ea420e87a61b568d68ac36d45a8/coverage-7.10.1-cp311-cp311-win32.whl", hash = "sha256:4fcfe294f95b44e4754da5b58be750396f2b1caca8f9a0e78588e3ef85f8b8be", size = 217167, upload-time = "2025-07-27T14:11:31.349Z" }, + { url = "https://files.pythonhosted.org/packages/f5/6f/1990eb4fd05cea4cfabdf1d587a997ac5f9a8bee883443a1d519a2a848c9/coverage-7.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:efa23166da3fe2915f8ab452dde40319ac84dc357f635737174a08dbd912980c", size = 218054, upload-time = "2025-07-27T14:11:33.202Z" }, + { url = "https://files.pythonhosted.org/packages/b4/4d/5e061d6020251b20e9b4303bb0b7900083a1a384ec4e5db326336c1c4abd/coverage-7.10.1-cp311-cp311-win_arm64.whl", hash = "sha256:d12b15a8c3759e2bb580ffa423ae54be4f184cf23beffcbd641f4fe6e1584293", size = 216483, upload-time = "2025-07-27T14:11:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/a5/3f/b051feeb292400bd22d071fdf933b3ad389a8cef5c80c7866ed0c7414b9e/coverage-7.10.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6b7dc7f0a75a7eaa4584e5843c873c561b12602439d2351ee28c7478186c4da4", size = 214934, upload-time = "2025-07-27T14:11:36.096Z" }, + { url = "https://files.pythonhosted.org/packages/f8/e4/a61b27d5c4c2d185bdfb0bfe9d15ab4ac4f0073032665544507429ae60eb/coverage-7.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:607f82389f0ecafc565813aa201a5cade04f897603750028dd660fb01797265e", size = 215173, upload-time = "2025-07-27T14:11:38.005Z" }, + { url = "https://files.pythonhosted.org/packages/8a/01/40a6ee05b60d02d0bc53742ad4966e39dccd450aafb48c535a64390a3552/coverage-7.10.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f7da31a1ba31f1c1d4d5044b7c5813878adae1f3af8f4052d679cc493c7328f4", size = 246190, upload-time = "2025-07-27T14:11:39.887Z" }, + { url = "https://files.pythonhosted.org/packages/11/ef/a28d64d702eb583c377255047281305dc5a5cfbfb0ee36e721f78255adb6/coverage-7.10.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:51fe93f3fe4f5d8483d51072fddc65e717a175490804e1942c975a68e04bf97a", size = 248618, upload-time = "2025-07-27T14:11:41.841Z" }, + { url = "https://files.pythonhosted.org/packages/6a/ad/73d018bb0c8317725370c79d69b5c6e0257df84a3b9b781bda27a438a3be/coverage-7.10.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3e59d00830da411a1feef6ac828b90bbf74c9b6a8e87b8ca37964925bba76dbe", size = 250081, upload-time = "2025-07-27T14:11:43.705Z" }, + { url = "https://files.pythonhosted.org/packages/2d/dd/496adfbbb4503ebca5d5b2de8bed5ec00c0a76558ffc5b834fd404166bc9/coverage-7.10.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:924563481c27941229cb4e16eefacc35da28563e80791b3ddc5597b062a5c386", size = 247990, upload-time = "2025-07-27T14:11:45.244Z" }, + { url = "https://files.pythonhosted.org/packages/18/3c/a9331a7982facfac0d98a4a87b36ae666fe4257d0f00961a3a9ef73e015d/coverage-7.10.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ca79146ee421b259f8131f153102220b84d1a5e6fb9c8aed13b3badfd1796de6", size = 246191, upload-time = "2025-07-27T14:11:47.093Z" }, + { url = "https://files.pythonhosted.org/packages/62/0c/75345895013b83f7afe92ec595e15a9a525ede17491677ceebb2ba5c3d85/coverage-7.10.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2b225a06d227f23f386fdc0eab471506d9e644be699424814acc7d114595495f", size = 247400, upload-time = "2025-07-27T14:11:48.643Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a9/98b268cfc5619ef9df1d5d34fee408ecb1542d9fd43d467e5c2f28668cd4/coverage-7.10.1-cp312-cp312-win32.whl", hash = "sha256:5ba9a8770effec5baaaab1567be916c87d8eea0c9ad11253722d86874d885eca", size = 217338, upload-time = "2025-07-27T14:11:50.258Z" }, + { url = "https://files.pythonhosted.org/packages/fe/31/22a5440e4d1451f253c5cd69fdcead65e92ef08cd4ec237b8756dc0b20a7/coverage-7.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:9eb245a8d8dd0ad73b4062135a251ec55086fbc2c42e0eb9725a9b553fba18a3", size = 218125, upload-time = "2025-07-27T14:11:52.034Z" }, + { url = "https://files.pythonhosted.org/packages/d6/2b/40d9f0ce7ee839f08a43c5bfc9d05cec28aaa7c9785837247f96cbe490b9/coverage-7.10.1-cp312-cp312-win_arm64.whl", hash = "sha256:7718060dd4434cc719803a5e526838a5d66e4efa5dc46d2b25c21965a9c6fcc4", size = 216523, upload-time = "2025-07-27T14:11:53.965Z" }, + { url = "https://files.pythonhosted.org/packages/ef/72/135ff5fef09b1ffe78dbe6fcf1e16b2e564cd35faeacf3d63d60d887f12d/coverage-7.10.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ebb08d0867c5a25dffa4823377292a0ffd7aaafb218b5d4e2e106378b1061e39", size = 214960, upload-time = "2025-07-27T14:11:55.959Z" }, + { url = "https://files.pythonhosted.org/packages/b1/aa/73a5d1a6fc08ca709a8177825616aa95ee6bf34d522517c2595484a3e6c9/coverage-7.10.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f32a95a83c2e17422f67af922a89422cd24c6fa94041f083dd0bb4f6057d0bc7", size = 215220, upload-time = "2025-07-27T14:11:57.899Z" }, + { url = "https://files.pythonhosted.org/packages/8d/40/3124fdd45ed3772a42fc73ca41c091699b38a2c3bd4f9cb564162378e8b6/coverage-7.10.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c4c746d11c8aba4b9f58ca8bfc6fbfd0da4efe7960ae5540d1a1b13655ee8892", size = 245772, upload-time = "2025-07-27T14:12:00.422Z" }, + { url = "https://files.pythonhosted.org/packages/42/62/a77b254822efa8c12ad59e8039f2bc3df56dc162ebda55e1943e35ba31a5/coverage-7.10.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7f39edd52c23e5c7ed94e0e4bf088928029edf86ef10b95413e5ea670c5e92d7", size = 248116, upload-time = "2025-07-27T14:12:03.099Z" }, + { url = "https://files.pythonhosted.org/packages/1d/01/8101f062f472a3a6205b458d18ef0444a63ae5d36a8a5ed5dd0f6167f4db/coverage-7.10.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ab6e19b684981d0cd968906e293d5628e89faacb27977c92f3600b201926b994", size = 249554, upload-time = "2025-07-27T14:12:04.668Z" }, + { url = "https://files.pythonhosted.org/packages/8f/7b/e51bc61573e71ff7275a4f167aecbd16cb010aefdf54bcd8b0a133391263/coverage-7.10.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5121d8cf0eacb16133501455d216bb5f99899ae2f52d394fe45d59229e6611d0", size = 247766, upload-time = "2025-07-27T14:12:06.234Z" }, + { url = "https://files.pythonhosted.org/packages/4b/71/1c96d66a51d4204a9d6d12df53c4071d87e110941a2a1fe94693192262f5/coverage-7.10.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:df1c742ca6f46a6f6cbcaef9ac694dc2cb1260d30a6a2f5c68c5f5bcfee1cfd7", size = 245735, upload-time = "2025-07-27T14:12:08.305Z" }, + { url = "https://files.pythonhosted.org/packages/13/d5/efbc2ac4d35ae2f22ef6df2ca084c60e13bd9378be68655e3268c80349ab/coverage-7.10.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:40f9a38676f9c073bf4b9194707aa1eb97dca0e22cc3766d83879d72500132c7", size = 247118, upload-time = "2025-07-27T14:12:09.903Z" }, + { url = "https://files.pythonhosted.org/packages/d1/22/073848352bec28ca65f2b6816b892fcf9a31abbef07b868487ad15dd55f1/coverage-7.10.1-cp313-cp313-win32.whl", hash = "sha256:2348631f049e884839553b9974f0821d39241c6ffb01a418efce434f7eba0fe7", size = 217381, upload-time = "2025-07-27T14:12:11.535Z" }, + { url = "https://files.pythonhosted.org/packages/b7/df/df6a0ff33b042f000089bd11b6bb034bab073e2ab64a56e78ed882cba55d/coverage-7.10.1-cp313-cp313-win_amd64.whl", hash = "sha256:4072b31361b0d6d23f750c524f694e1a417c1220a30d3ef02741eed28520c48e", size = 218152, upload-time = "2025-07-27T14:12:13.182Z" }, + { url = "https://files.pythonhosted.org/packages/30/e3/5085ca849a40ed6b47cdb8f65471c2f754e19390b5a12fa8abd25cbfaa8f/coverage-7.10.1-cp313-cp313-win_arm64.whl", hash = "sha256:3e31dfb8271937cab9425f19259b1b1d1f556790e98eb266009e7a61d337b6d4", size = 216559, upload-time = "2025-07-27T14:12:14.807Z" }, + { url = "https://files.pythonhosted.org/packages/cc/93/58714efbfdeb547909feaabe1d67b2bdd59f0597060271b9c548d5efb529/coverage-7.10.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:1c4f679c6b573a5257af6012f167a45be4c749c9925fd44d5178fd641ad8bf72", size = 215677, upload-time = "2025-07-27T14:12:16.68Z" }, + { url = "https://files.pythonhosted.org/packages/c0/0c/18eaa5897e7e8cb3f8c45e563e23e8a85686b4585e29d53cacb6bc9cb340/coverage-7.10.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:871ebe8143da284bd77b84a9136200bd638be253618765d21a1fce71006d94af", size = 215899, upload-time = "2025-07-27T14:12:18.758Z" }, + { url = "https://files.pythonhosted.org/packages/84/c1/9d1affacc3c75b5a184c140377701bbf14fc94619367f07a269cd9e4fed6/coverage-7.10.1-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:998c4751dabf7d29b30594af416e4bf5091f11f92a8d88eb1512c7ba136d1ed7", size = 257140, upload-time = "2025-07-27T14:12:20.357Z" }, + { url = "https://files.pythonhosted.org/packages/3d/0f/339bc6b8fa968c346df346068cca1f24bdea2ddfa93bb3dc2e7749730962/coverage-7.10.1-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:780f750a25e7749d0af6b3631759c2c14f45de209f3faaa2398312d1c7a22759", size = 259005, upload-time = "2025-07-27T14:12:22.007Z" }, + { url = "https://files.pythonhosted.org/packages/c8/22/89390864b92ea7c909079939b71baba7e5b42a76bf327c1d615bd829ba57/coverage-7.10.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:590bdba9445df4763bdbebc928d8182f094c1f3947a8dc0fc82ef014dbdd8324", size = 261143, upload-time = "2025-07-27T14:12:23.746Z" }, + { url = "https://files.pythonhosted.org/packages/2c/56/3d04d89017c0c41c7a71bd69b29699d919b6bbf2649b8b2091240b97dd6a/coverage-7.10.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b2df80cb6a2af86d300e70acb82e9b79dab2c1e6971e44b78dbfc1a1e736b53", size = 258735, upload-time = "2025-07-27T14:12:25.73Z" }, + { url = "https://files.pythonhosted.org/packages/cb/40/312252c8afa5ca781063a09d931f4b9409dc91526cd0b5a2b84143ffafa2/coverage-7.10.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:d6a558c2725bfb6337bf57c1cd366c13798bfd3bfc9e3dd1f4a6f6fc95a4605f", size = 256871, upload-time = "2025-07-27T14:12:27.767Z" }, + { url = "https://files.pythonhosted.org/packages/1f/2b/564947d5dede068215aaddb9e05638aeac079685101462218229ddea9113/coverage-7.10.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e6150d167f32f2a54690e572e0a4c90296fb000a18e9b26ab81a6489e24e78dd", size = 257692, upload-time = "2025-07-27T14:12:29.347Z" }, + { url = "https://files.pythonhosted.org/packages/93/1b/c8a867ade85cb26d802aea2209b9c2c80613b9c122baa8c8ecea6799648f/coverage-7.10.1-cp313-cp313t-win32.whl", hash = "sha256:d946a0c067aa88be4a593aad1236493313bafaa27e2a2080bfe88db827972f3c", size = 218059, upload-time = "2025-07-27T14:12:31.076Z" }, + { url = "https://files.pythonhosted.org/packages/a1/fe/cd4ab40570ae83a516bf5e754ea4388aeedd48e660e40c50b7713ed4f930/coverage-7.10.1-cp313-cp313t-win_amd64.whl", hash = "sha256:e37c72eaccdd5ed1130c67a92ad38f5b2af66eeff7b0abe29534225db2ef7b18", size = 219150, upload-time = "2025-07-27T14:12:32.746Z" }, + { url = "https://files.pythonhosted.org/packages/8d/16/6e5ed5854be6d70d0c39e9cb9dd2449f2c8c34455534c32c1a508c7dbdb5/coverage-7.10.1-cp313-cp313t-win_arm64.whl", hash = "sha256:89ec0ffc215c590c732918c95cd02b55c7d0f569d76b90bb1a5e78aa340618e4", size = 217014, upload-time = "2025-07-27T14:12:34.406Z" }, + { url = "https://files.pythonhosted.org/packages/54/8e/6d0bfe9c3d7121cf936c5f8b03e8c3da1484fb801703127dba20fb8bd3c7/coverage-7.10.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:166d89c57e877e93d8827dac32cedae6b0277ca684c6511497311249f35a280c", size = 214951, upload-time = "2025-07-27T14:12:36.069Z" }, + { url = "https://files.pythonhosted.org/packages/f2/29/e3e51a8c653cf2174c60532aafeb5065cea0911403fa144c9abe39790308/coverage-7.10.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:bed4a2341b33cd1a7d9ffc47df4a78ee61d3416d43b4adc9e18b7d266650b83e", size = 215229, upload-time = "2025-07-27T14:12:37.759Z" }, + { url = "https://files.pythonhosted.org/packages/e0/59/3c972080b2fa18b6c4510201f6d4dc87159d450627d062cd9ad051134062/coverage-7.10.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:ddca1e4f5f4c67980533df01430184c19b5359900e080248bbf4ed6789584d8b", size = 245738, upload-time = "2025-07-27T14:12:39.453Z" }, + { url = "https://files.pythonhosted.org/packages/2e/04/fc0d99d3f809452654e958e1788454f6e27b34e43f8f8598191c8ad13537/coverage-7.10.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:37b69226001d8b7de7126cad7366b0778d36777e4d788c66991455ba817c5b41", size = 248045, upload-time = "2025-07-27T14:12:41.387Z" }, + { url = "https://files.pythonhosted.org/packages/5e/2e/afcbf599e77e0dfbf4c97197747250d13d397d27e185b93987d9eaac053d/coverage-7.10.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b2f22102197bcb1722691296f9e589f02b616f874e54a209284dd7b9294b0b7f", size = 249666, upload-time = "2025-07-27T14:12:43.056Z" }, + { url = "https://files.pythonhosted.org/packages/6e/ae/bc47f7f8ecb7a06cbae2bf86a6fa20f479dd902bc80f57cff7730438059d/coverage-7.10.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1e0c768b0f9ac5839dac5cf88992a4bb459e488ee8a1f8489af4cb33b1af00f1", size = 247692, upload-time = "2025-07-27T14:12:44.83Z" }, + { url = "https://files.pythonhosted.org/packages/b6/26/cbfa3092d31ccba8ba7647e4d25753263e818b4547eba446b113d7d1efdf/coverage-7.10.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:991196702d5e0b120a8fef2664e1b9c333a81d36d5f6bcf6b225c0cf8b0451a2", size = 245536, upload-time = "2025-07-27T14:12:46.527Z" }, + { url = "https://files.pythonhosted.org/packages/56/77/9c68e92500e6a1c83d024a70eadcc9a173f21aadd73c4675fe64c9c43fdf/coverage-7.10.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ae8e59e5f4fd85d6ad34c2bb9d74037b5b11be072b8b7e9986beb11f957573d4", size = 246954, upload-time = "2025-07-27T14:12:49.279Z" }, + { url = "https://files.pythonhosted.org/packages/7f/a5/ba96671c5a669672aacd9877a5987c8551501b602827b4e84256da2a30a7/coverage-7.10.1-cp314-cp314-win32.whl", hash = "sha256:042125c89cf74a074984002e165d61fe0e31c7bd40ebb4bbebf07939b5924613", size = 217616, upload-time = "2025-07-27T14:12:51.214Z" }, + { url = "https://files.pythonhosted.org/packages/e7/3c/e1e1eb95fc1585f15a410208c4795db24a948e04d9bde818fe4eb893bc85/coverage-7.10.1-cp314-cp314-win_amd64.whl", hash = "sha256:a22c3bfe09f7a530e2c94c87ff7af867259c91bef87ed2089cd69b783af7b84e", size = 218412, upload-time = "2025-07-27T14:12:53.429Z" }, + { url = "https://files.pythonhosted.org/packages/b0/85/7e1e5be2cb966cba95566ba702b13a572ca744fbb3779df9888213762d67/coverage-7.10.1-cp314-cp314-win_arm64.whl", hash = "sha256:ee6be07af68d9c4fca4027c70cea0c31a0f1bc9cb464ff3c84a1f916bf82e652", size = 216776, upload-time = "2025-07-27T14:12:55.482Z" }, + { url = "https://files.pythonhosted.org/packages/62/0f/5bb8f29923141cca8560fe2217679caf4e0db643872c1945ac7d8748c2a7/coverage-7.10.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d24fb3c0c8ff0d517c5ca5de7cf3994a4cd559cde0315201511dbfa7ab528894", size = 215698, upload-time = "2025-07-27T14:12:57.225Z" }, + { url = "https://files.pythonhosted.org/packages/80/29/547038ffa4e8e4d9e82f7dfc6d152f75fcdc0af146913f0ba03875211f03/coverage-7.10.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1217a54cfd79be20512a67ca81c7da3f2163f51bbfd188aab91054df012154f5", size = 215902, upload-time = "2025-07-27T14:12:59.071Z" }, + { url = "https://files.pythonhosted.org/packages/e1/8a/7aaa8fbfaed900147987a424e112af2e7790e1ac9cd92601e5bd4e1ba60a/coverage-7.10.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:51f30da7a52c009667e02f125737229d7d8044ad84b79db454308033a7808ab2", size = 257230, upload-time = "2025-07-27T14:13:01.248Z" }, + { url = "https://files.pythonhosted.org/packages/e5/1d/c252b5ffac44294e23a0d79dd5acf51749b39795ccc898faeabf7bee903f/coverage-7.10.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ed3718c757c82d920f1c94089066225ca2ad7f00bb904cb72b1c39ebdd906ccb", size = 259194, upload-time = "2025-07-27T14:13:03.247Z" }, + { url = "https://files.pythonhosted.org/packages/16/ad/6c8d9f83d08f3bac2e7507534d0c48d1a4f52c18e6f94919d364edbdfa8f/coverage-7.10.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cc452481e124a819ced0c25412ea2e144269ef2f2534b862d9f6a9dae4bda17b", size = 261316, upload-time = "2025-07-27T14:13:04.957Z" }, + { url = "https://files.pythonhosted.org/packages/d6/4e/f9bbf3a36c061e2e0e0f78369c006d66416561a33d2bee63345aee8ee65e/coverage-7.10.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9d6f494c307e5cb9b1e052ec1a471060f1dea092c8116e642e7a23e79d9388ea", size = 258794, upload-time = "2025-07-27T14:13:06.715Z" }, + { url = "https://files.pythonhosted.org/packages/87/82/e600bbe78eb2cb0541751d03cef9314bcd0897e8eea156219c39b685f869/coverage-7.10.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:fc0e46d86905ddd16b85991f1f4919028092b4e511689bbdaff0876bd8aab3dd", size = 256869, upload-time = "2025-07-27T14:13:08.933Z" }, + { url = "https://files.pythonhosted.org/packages/ce/5d/2fc9a9236c5268f68ac011d97cd3a5ad16cc420535369bedbda659fdd9b7/coverage-7.10.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:80b9ccd82e30038b61fc9a692a8dc4801504689651b281ed9109f10cc9fe8b4d", size = 257765, upload-time = "2025-07-27T14:13:10.778Z" }, + { url = "https://files.pythonhosted.org/packages/8a/05/b4e00b2bd48a2dc8e1c7d2aea7455f40af2e36484ab2ef06deb85883e9fe/coverage-7.10.1-cp314-cp314t-win32.whl", hash = "sha256:e58991a2b213417285ec866d3cd32db17a6a88061a985dbb7e8e8f13af429c47", size = 218420, upload-time = "2025-07-27T14:13:12.882Z" }, + { url = "https://files.pythonhosted.org/packages/77/fb/d21d05f33ea27ece327422240e69654b5932b0b29e7fbc40fbab3cf199bf/coverage-7.10.1-cp314-cp314t-win_amd64.whl", hash = "sha256:e88dd71e4ecbc49d9d57d064117462c43f40a21a1383507811cf834a4a620651", size = 219536, upload-time = "2025-07-27T14:13:14.718Z" }, + { url = "https://files.pythonhosted.org/packages/a6/68/7fea94b141281ed8be3d1d5c4319a97f2befc3e487ce33657fc64db2c45e/coverage-7.10.1-cp314-cp314t-win_arm64.whl", hash = "sha256:1aadfb06a30c62c2eb82322171fe1f7c288c80ca4156d46af0ca039052814bab", size = 217190, upload-time = "2025-07-27T14:13:16.85Z" }, + { url = "https://files.pythonhosted.org/packages/0f/64/922899cff2c0fd3496be83fa8b81230f5a8d82a2ad30f98370b133c2c83b/coverage-7.10.1-py3-none-any.whl", hash = "sha256:fa2a258aa6bf188eb9a8948f7102a83da7c430a0dce918dbd8b60ef8fcb772d7", size = 206597, upload-time = "2025-07-27T14:13:37.221Z" }, ] [package.optional-dependencies] @@ -910,7 +910,7 @@ name = "exceptiongroup" version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } wheels = [ @@ -1195,42 +1195,43 @@ wheels = [ [[package]] name = "impit" -version = "0.4.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/30/0d/33b186a32006e3424375dd7e5ced75d54da8d6cace1b63bee6298983ae06/impit-0.4.2.tar.gz", hash = "sha256:d2619498fb229f08a3963f38709c340c4b6258e155f3161b4bc4b53c1beb2d0e", size = 87901, upload-time = "2025-07-23T16:09:43.338Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8f/e6/26032cde08e0f2225a7f3b388e844e1b9af1a2b1239091cb02a348402d74/impit-0.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:447f6339322496cf29216fd31e4a8350b4cdfd3ab097d264bc5672efd16133a5", size = 6071612, upload-time = "2025-07-23T16:08:38.67Z" }, - { url = "https://files.pythonhosted.org/packages/e2/12/9ba599d0e3bd5dee7813996ebd9a0450378bc0c1ab371103be4d945202ee/impit-0.4.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a0cb45bb3e53b03008ce9ba8bf432522530d1d9f3ca5c2d4ffedfa48eec5efdf", size = 6363081, upload-time = "2025-07-23T16:08:40.712Z" }, - { url = "https://files.pythonhosted.org/packages/78/5c/0abe388e397c96e118d9644e93de1ba7354cc63c8de5c928e3ba954a5a7b/impit-0.4.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fade6c12facafbea526649e21d3c50311709771093334c7dfc37973d17d932ee", size = 6219879, upload-time = "2025-07-23T16:08:42.454Z" }, - { url = "https://files.pythonhosted.org/packages/f1/88/5db4a87977d365b0fc5ab937b66ec951fda1250aa9eb11c09cfacb6df191/impit-0.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:128b0c468460ec744f01a38a232db46f72e18d0b61a793c76198deedfd85f88d", size = 3876795, upload-time = "2025-07-23T16:08:44.315Z" }, - { url = "https://files.pythonhosted.org/packages/6e/be/1c9908d73835d0b01fff54e307ca82ce727cfa5039e2f3d1944a7ae9f6d0/impit-0.4.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a6eb2a5e90d580e7d0b70bfe27717c07ff0573a28ef0305a8250ca8da21671d8", size = 3840532, upload-time = "2025-07-23T16:08:45.702Z" }, - { url = "https://files.pythonhosted.org/packages/4f/d3/9fa513fc5833ff0e6cdfcb5a5a713e33e8281f761fc86efe51e7e65838f9/impit-0.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8f54f1bb6b900f61ee78e90f1a90a7e56c133f5746c68a86dffeb8742e813e21", size = 3667827, upload-time = "2025-07-23T16:08:47.08Z" }, - { url = "https://files.pythonhosted.org/packages/b9/45/c17ec45ebe9a2b3cbd7830b326553dc16223e9d3636bb9e5e9cb88fea0ba/impit-0.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b07b895631d273734b13480d27053278693affb33997f8416be666eafcdaa01", size = 6071717, upload-time = "2025-07-23T16:08:48.521Z" }, - { url = "https://files.pythonhosted.org/packages/f7/79/3e23b85e901c4016af1e0f607f9c29de035d94231fdedc14f4c978a02fa3/impit-0.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7166633f4bfd45aab1b29a45988ff7b9a5da8f0d81437eb80caf33f889813432", size = 6362986, upload-time = "2025-07-23T16:08:50.177Z" }, - { url = "https://files.pythonhosted.org/packages/61/10/e497380e1d315915ad32803aaa874ca2175730cd1a4c70669f40e5d22993/impit-0.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b57235562904102c69783fa2eb69975c3dfbdf44bfbd6976bcd9e0a428b2187d", size = 6219308, upload-time = "2025-07-23T16:08:52.183Z" }, - { url = "https://files.pythonhosted.org/packages/b3/91/67bdb5faf9b4cbb608e464e178029697261de25fdb615a3120fa15bc81df/impit-0.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:a1224583f8e53087a2c3b773979add78e0f308ff7ef05e86a0f1780902258da2", size = 3876712, upload-time = "2025-07-23T16:08:53.966Z" }, - { url = "https://files.pythonhosted.org/packages/a8/10/62b119310a3be3d255428703fb611133449dcd839c2d3ed32c5aefc1e8a5/impit-0.4.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:d74a43be353c7f674a108a87cb4d2288659998eb8a75fdc1fe70d1d512a4a77d", size = 3840140, upload-time = "2025-07-23T16:08:55.413Z" }, - { url = "https://files.pythonhosted.org/packages/d1/11/ad7c81fbdeb272d26cfe3202aa296294135f5e3dbd5ab1fe37f517d95e21/impit-0.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ab984b59d0b6bd37f579c876b099e552c9310903b566a961885ee2a5b54c44ca", size = 3666471, upload-time = "2025-07-23T16:08:57.1Z" }, - { url = "https://files.pythonhosted.org/packages/de/d1/c4c3cefd061b89d6bfe33967205b2840f4d495bd909cd0bf24b47db8f03e/impit-0.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5090fae8fd6697af4f7a7868214c8acc44ae4d5c75ab00b962c2073156b67750", size = 6071055, upload-time = "2025-07-23T16:08:58.608Z" }, - { url = "https://files.pythonhosted.org/packages/41/25/575c864ae99b6aa672045628c12657ab3d8fe2a9120585395087110aacbc/impit-0.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9cc73f0e1d147140c40260d6c94d9c0781aa1132a834a209953822c350ced518", size = 6361762, upload-time = "2025-07-23T16:09:00.432Z" }, - { url = "https://files.pythonhosted.org/packages/45/4d/62d6f45f0b5121864d2a5ba8e86b9ee8bdadf70dd24f9af5238b551cc0aa/impit-0.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5654a27146d413c5476cc400fdba175fe01d86851fcfd7fd9786e1349579ca52", size = 6218027, upload-time = "2025-07-23T16:09:02.274Z" }, - { url = "https://files.pythonhosted.org/packages/ea/7a/bb0cc08f914b83c14ff6980253beddc439b7cea27b3bb23d27df222a4a09/impit-0.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:e67e54418775747355ef7bb8f5d4159cd963fe25502415e18c8b73f996c1aa45", size = 3876170, upload-time = "2025-07-23T16:09:03.767Z" }, - { url = "https://files.pythonhosted.org/packages/ec/94/0178ba2186a88bb9c808a3a54d1bf025d28cbbbaedd6ec02996a9930b64d/impit-0.4.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:55ef993b9bf8567d3a71144023b7407ab413df714b95231bbbbec1b5fe701290", size = 3839896, upload-time = "2025-07-23T16:09:05.172Z" }, - { url = "https://files.pythonhosted.org/packages/26/eb/51045ffe41c5a9a111102c0fc6d60c03221a624341f5ee73f2c8450d4f19/impit-0.4.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e3fb7d77a105cf0a0b2fb00f394570c828807eb1f5336fcfc304974c9e4973b9", size = 3666416, upload-time = "2025-07-23T16:09:06.678Z" }, - { url = "https://files.pythonhosted.org/packages/b6/95/b00b43931c34c942eb5788be2be7b1f7c6d85378aeff9c92b10337136425/impit-0.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de6bd6c35005580e79e3e9588566aff497d251857fda724dbe882c9b94941420", size = 6070862, upload-time = "2025-07-23T16:09:08.185Z" }, - { url = "https://files.pythonhosted.org/packages/dc/89/6ac00dc34e771011f29e9094f272966d93555ef4db12be1b216563748095/impit-0.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3cf949a2fa2aa973ad5f4c1880027475b3fb79c315372161a797a93d8614d279", size = 6361773, upload-time = "2025-07-23T16:09:09.672Z" }, - { url = "https://files.pythonhosted.org/packages/3d/d3/66d9b9e4d060d6468ed421e62b1b86305f00d0d5fca004ba40d47ffbd1e4/impit-0.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:96687b61c46b33cba0944bd760580f1b50745d77cf0419bca80c4a09f659c567", size = 6217984, upload-time = "2025-07-23T16:09:11.139Z" }, - { url = "https://files.pythonhosted.org/packages/0e/2b/51d80700dd71ec3714dddde30199c3e08f60de36c5528d4ae18421c80220/impit-0.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:e414fc0b1f8384888be702ef1ee5adb91d428bb78c38f566e615caa803fa9c46", size = 3875930, upload-time = "2025-07-23T16:09:12.605Z" }, - { url = "https://files.pythonhosted.org/packages/b0/8f/e1c2b7e2b019792ae0ae430618e5273f7dfee2a67c8851dbb9cafd4ec5fe/impit-0.4.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:7d0b7070b985149ac0a2ea8dd8b1b7ed7f0f6b6599ce183aff4439ba9c4049de", size = 6361816, upload-time = "2025-07-23T16:09:14.04Z" }, - { url = "https://files.pythonhosted.org/packages/ed/f6/c817f2feeab4e90feac16476394d2cc6b30d079b5498759fa2f53f1f5e6a/impit-0.4.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:17db3a0c92a2f750a45c4f0cf37c3fb401db7240207f15337cf64585b20dadeb", size = 6219526, upload-time = "2025-07-23T16:09:16.196Z" }, - { url = "https://files.pythonhosted.org/packages/07/05/ff7d78470f1a7b94e347cc67621980eb9fc1b1e8b5f6f9d5470977b129cd/impit-0.4.2-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2eaec94883464cd714db02380583eb5bd18dadd25d9f6825fcc367409b01d5d", size = 6071038, upload-time = "2025-07-23T16:09:17.699Z" }, - { url = "https://files.pythonhosted.org/packages/b9/c3/d1355e08bb95e3effaeb7f5fbe993d233d55ee6ede5636207b489d19b090/impit-0.4.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:22ffe82c73a7e432ac502e45672a9e8613cbc72ede648eb531465afd433febdd", size = 3840502, upload-time = "2025-07-23T16:09:25.994Z" }, - { url = "https://files.pythonhosted.org/packages/35/a2/785a7234c9e2004b3e867c4f45a647bbaef9a5ce0aaada42475605da2c4a/impit-0.4.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a614a54408d9efdeb107385a46c8cd9d09ac2426e6fffc8e58bf89dbd8988332", size = 6072831, upload-time = "2025-07-23T16:09:27.424Z" }, - { url = "https://files.pythonhosted.org/packages/43/4c/beba3d85144aaaf8706c5736c1bdb7b4ecb06573116eafc38344c0f3bb99/impit-0.4.2-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:665ad424005596d03e92fc4d6532e2dd062d97ef1fc846fd8a6458577d64c7f4", size = 6362991, upload-time = "2025-07-23T16:09:29.168Z" }, - { url = "https://files.pythonhosted.org/packages/1b/a5/2cb0e4913d411db8939489b236feafef435a89c31531cd140c0496f0b7b9/impit-0.4.2-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6a44d45f890f2298cd320c9bff5d3e31507eedb6418a8980a3a3ee3ae525ae6c", size = 6221003, upload-time = "2025-07-23T16:09:31.099Z" }, - { url = "https://files.pythonhosted.org/packages/cf/64/ad68608c6dbb91bdf078104483b711c374507a17b2ee9719146c22a53874/impit-0.4.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55cff777af9fc9aa66651753440d3df80799db1f4ad0e43498cd1434953f0657", size = 6072680, upload-time = "2025-07-23T16:09:32.794Z" }, - { url = "https://files.pythonhosted.org/packages/98/83/d730c0b55eb7e7a35e0966987900cf36430dcc5461f94b4c6d8b254eb29c/impit-0.4.2-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:28df5a3434e8ef2e087fd6eafbe18f5bf8225405f541e9c97b9b614bbcb6191a", size = 6363100, upload-time = "2025-07-23T16:09:34.383Z" }, - { url = "https://files.pythonhosted.org/packages/9b/d8/527be637993ef3aeabc0396d1c5f0f63d58b01fce55f13beda4946cdcc28/impit-0.4.2-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:e996552535951706719a08311af4cef3ebbbfe1fa0cdac3c9a6cb7652293883f", size = 6220800, upload-time = "2025-07-23T16:09:36.701Z" }, +version = "0.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/84/82/da7f6ebec2ae2e4071c7f97d5d09710ec205eb7a5660674bf2b0e43969ad/impit-0.5.0.tar.gz", hash = "sha256:c1f27d046fcf53b1ad9f63897a666a4f32eb53763245b4c2047c826991675ba5", size = 87921, upload-time = "2025-07-30T11:51:42.266Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ac/07/717c47aae5be96bb9d622c26a676a3f88e6ba6846c0b590b9e1f15dcaac6/impit-0.5.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:bb2a8befe3b5bd2d32b116f9a76b41699a1ecc64e53e9643adb98837bba0c32e", size = 3840719, upload-time = "2025-07-30T11:50:30.974Z" }, + { url = "https://files.pythonhosted.org/packages/d3/56/20843b4e913c691b69f8a86483c64d1b0c84c17a20588b53acffffa67616/impit-0.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f9bcd170ad3b53ea0d2c585efc7f2f23b7942c7e9b41a505d4bdc4a928580f6", size = 3667648, upload-time = "2025-07-30T11:50:33.062Z" }, + { url = "https://files.pythonhosted.org/packages/5c/f5/d77627559764f759c0eef1189ec6b7d62fea71889b84b41dd8359c31835f/impit-0.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9bba63905ebcc625b63cdc6adce0bc8c80c95ad500b3fd02b8bb622fbb718beb", size = 6071606, upload-time = "2025-07-30T11:50:34.568Z" }, + { url = "https://files.pythonhosted.org/packages/a8/d1/6206195b8af11151eb4fe77e98113f4ec507ee70c2873e6a1f50620048f5/impit-0.5.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9b6fd9898d5983f353d806fab528e95305736b0eb67da5fb32ce0fade31cc80f", size = 6363184, upload-time = "2025-07-30T11:50:36.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/5f/682015b7f2017ef3d823d42ae66d614a948d74597b457030e129501f216f/impit-0.5.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:186c20ff24a2431b66674d405a3b8357e66553ce1de518568b136a2cd4aa0d39", size = 6223813, upload-time = "2025-07-30T11:50:38.367Z" }, + { url = "https://files.pythonhosted.org/packages/e8/51/3937cfc7357a1f70146bd4c61e012f219cfb86126f75cb8a6c3320c452a1/impit-0.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:095a003e6f88302f12720704cd2835435a9752b5b033d5263f6be5ee8880d434", size = 3876828, upload-time = "2025-07-30T11:50:40.216Z" }, + { url = "https://files.pythonhosted.org/packages/3a/e7/86ee335462a58590739ef44d851aeaffc131608582bbbb4b2b6dd6677eda/impit-0.5.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:cbee5603b7d8da6a3f5f6fccba7f9c2b04813943db293b6fc6fff63d3e86686b", size = 3840617, upload-time = "2025-07-30T11:50:41.735Z" }, + { url = "https://files.pythonhosted.org/packages/df/e4/64b4f55fca0e63f03289c83beffe08b396a0c32015ef2fc28b8a8c09146f/impit-0.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c516f5bceb1757633c6291411fe8e255f81c7432f259da41e6408654b81dca6f", size = 3667696, upload-time = "2025-07-30T11:50:43.551Z" }, + { url = "https://files.pythonhosted.org/packages/e1/75/7186b5ce0e10c7a3995fb814a8e12772911180baf1ee7a4db55d558c1b02/impit-0.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e4516f5d9c48aa9278f227c9a902e79f4636f35398921998899071a1abc08f9", size = 6071710, upload-time = "2025-07-30T11:50:45.095Z" }, + { url = "https://files.pythonhosted.org/packages/dc/ec/a0b2a60e16de567be1403a6025f6daf8f40dc29629f1a2e5c828469fb987/impit-0.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d06287ba0bf51abc16e0bd763a727e03f419accd263c34ded3e10be93c971ceb", size = 6362938, upload-time = "2025-07-30T11:50:46.917Z" }, + { url = "https://files.pythonhosted.org/packages/e0/a5/e9b16dda32008bd2e6a93dba1d82ddad6abacddd4b0c79792c03f244d16e/impit-0.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:19d5e75d2e0c6a69c59cdfdc88da7fd9a72c23684fc88439240294740f2b7515", size = 6219401, upload-time = "2025-07-30T11:50:48.441Z" }, + { url = "https://files.pythonhosted.org/packages/08/13/875fb538d16f39eef8dc9c634a4ae352a49a2a106b2b7cfdde67cd67212e/impit-0.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:f265c72c5aa8557244f80a230bfd548ea992db0b86323c672a87f379ad716957", size = 3876742, upload-time = "2025-07-30T11:50:49.863Z" }, + { url = "https://files.pythonhosted.org/packages/22/b0/8b9406eab662743a57e57066411b38b60f4f6dca91c954b64adc695ec3b6/impit-0.5.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ad1337dc93a4bb5e4075975f3234a7c85caf4ec6973a79b77cdfeb0087382238", size = 3840111, upload-time = "2025-07-30T11:50:51.318Z" }, + { url = "https://files.pythonhosted.org/packages/1c/ad/9385cb1d04eed2531d0df0a4902064a7d6fb3857abed1a86489f0e723834/impit-0.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc40983a60a7ee5eca8bbc8a9dfc0dc7865b94d26e8c86e3d550d06b1bebf3d7", size = 3666505, upload-time = "2025-07-30T11:50:53.101Z" }, + { url = "https://files.pythonhosted.org/packages/9d/08/dcd9a585f4f6b633dac11f295ef705974deeb98176e8c793350e777c8561/impit-0.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:527ace267d17254500695a0b177e7cfbfd842a860e3047cc93fe09fe009b33a6", size = 6071126, upload-time = "2025-07-30T11:50:54.666Z" }, + { url = "https://files.pythonhosted.org/packages/2f/c6/fbc7c826456220dd30888002d04d687163502f181baaf9d5165d45d8e221/impit-0.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:caa5f2c827d979a1d8e2badddac33c0f36b62646d29cb078090474c706097843", size = 6361672, upload-time = "2025-07-30T11:50:56.164Z" }, + { url = "https://files.pythonhosted.org/packages/90/2f/9db57fe1cd6b6cc7e2bac30e6f749d94ba8d3ff9108c0d2f72735fc68dc6/impit-0.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f3f07c460492a852e1081bc447dba59a63d2ea45abe82a1cbac745a402e2c9c3", size = 6218078, upload-time = "2025-07-30T11:50:57.773Z" }, + { url = "https://files.pythonhosted.org/packages/f1/8f/2a6c06951ff52552a8a061a67ebdebc70c4719531072afd55a17227cc7b9/impit-0.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:8dd7432d673bd6bf42a15d7919a9457c0cfd0eb0832fe2582298366d98fcc4ae", size = 3876072, upload-time = "2025-07-30T11:50:59.69Z" }, + { url = "https://files.pythonhosted.org/packages/fe/ac/0e34d5760573a719ef92249757b9dd1436687ca88d7b29a959886ea0f116/impit-0.5.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:b38197943efe692aa77f18883e3022fa1fcd240da2f3b3ba5dee10b7bdf5e835", size = 3839934, upload-time = "2025-07-30T11:51:01.185Z" }, + { url = "https://files.pythonhosted.org/packages/3a/7a/3321a75bb82750f5f4e04c003b8179d9c3ff751e16705a2b227417d4c2e5/impit-0.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d923a236011da447211714e34d015e178611b7997f3401ab5f432ee66d5f7b69", size = 3666384, upload-time = "2025-07-30T11:51:02.685Z" }, + { url = "https://files.pythonhosted.org/packages/da/cc/762ce64c7a6d1603111aacae151712c98f35ca20ea671b760005f42998fe/impit-0.5.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45e2e4daeecf85f80d4d5b287d83ce06c690ef4ef1c178ebae2265d05e54ab7d", size = 6070912, upload-time = "2025-07-30T11:51:04.188Z" }, + { url = "https://files.pythonhosted.org/packages/81/95/e86e0a01da31e76a6c2beca2bd4506fc93cb33c46dede1a47c9e3e6c15bc/impit-0.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6c7069ad70671e4b3129eb9f3fe3f50658aafc7f0de50b45fce4b0768008237c", size = 6361875, upload-time = "2025-07-30T11:51:05.741Z" }, + { url = "https://files.pythonhosted.org/packages/ee/e6/9ba2c7c111cf3265c657f53de3fb498db6586c13fd262b59913429d468fc/impit-0.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b656f0e7c1707c2124ea836b29a7d3d475117537184f12314b61ed74dccc6004", size = 6217892, upload-time = "2025-07-30T11:51:07.706Z" }, + { url = "https://files.pythonhosted.org/packages/cd/8d/5d31b830d0f142126cfbe3402eeb573261011334c7596d18a05a8b054741/impit-0.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:dcdb4b2235284912e0fe66b4e6d924609e360d95f9c9dd9bfeb252fcd183ef74", size = 3875933, upload-time = "2025-07-30T11:51:09.606Z" }, + { url = "https://files.pythonhosted.org/packages/22/e8/0def9b6b2ef540274ae5ceeb6fff5a51334411c1a578d2f3e1b9b6d6f62f/impit-0.5.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:fcd5b9a51a24b5cd5708b7ae52c0a65162132dce46799f7e051e319f7f3ac5c9", size = 6361971, upload-time = "2025-07-30T11:51:11.46Z" }, + { url = "https://files.pythonhosted.org/packages/6a/6f/c597c55e745b6793c171e699c9d24466aa5586b4cfac37d839c423669586/impit-0.5.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:b6a8afd89ea056ad1657b3242b3331859e3b87bf1b8b913d8ca5ac12259776c9", size = 6219369, upload-time = "2025-07-30T11:51:13.994Z" }, + { url = "https://files.pythonhosted.org/packages/95/c3/3d983e2327e68459c52ac2f8ac5b91885dbdd8601d96b43a2a3a7c2399a1/impit-0.5.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08a756e64a44197591d1f41b682baded2f4cc891946c03e5af21078186779cb2", size = 6071007, upload-time = "2025-07-30T11:51:16.669Z" }, + { url = "https://files.pythonhosted.org/packages/0e/91/98c4aa4d8036e6eb94d26015d6693c491667fda3ffd0cebe367a4039c8a3/impit-0.5.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be03977267b81708bdc54e98186f18138b65af6e8a8f0859f9483ee39b292208", size = 6072884, upload-time = "2025-07-30T11:51:27.402Z" }, + { url = "https://files.pythonhosted.org/packages/a9/a4/aa4338f95f4d63bfe5dc4d40c5e83b400188926f496769a2da34e211c039/impit-0.5.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:ebd100ed3a1d2017003e5f4323ef9ccb1bef7f68a3c70eace44dc80258ba61b1", size = 6363121, upload-time = "2025-07-30T11:51:29.254Z" }, + { url = "https://files.pythonhosted.org/packages/70/ba/0b6ff62fdccb66eb13cc058b69a1df08017f8318ae5adf813fad7cdc42a3/impit-0.5.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:8ee9f944ffdd039665f282be6ccec9a0ccd2e204a574f498d1bdd91f51dc4c93", size = 6220904, upload-time = "2025-07-30T11:51:30.706Z" }, + { url = "https://files.pythonhosted.org/packages/fa/6d/4b280ea4ad6b3b2731efa5aeef2c85c8c26d8408f591e1d3e2d3748b38eb/impit-0.5.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bcf04de0e970beccf95f71e1535bc7585a65b24eb7cdbbb7d6f13f9eb4533e3", size = 6072722, upload-time = "2025-07-30T11:51:32.321Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f1/8887e407d6330e9c3c98886466db78256a0b27246b6ef14e5418c965442f/impit-0.5.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:a2ca6a988ded989d5331787dbca1539eefdcee202a38c188ec04525f4cb708d4", size = 6363170, upload-time = "2025-07-30T11:51:33.815Z" }, + { url = "https://files.pythonhosted.org/packages/03/73/6318d23468759f473c3f438d701e0efae3feb9fc1865b56d2a201a22e61f/impit-0.5.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:62a7942295ea8656fdb881a47a0e6b16edfb0e2d4dd07ad0b6f8d928efc1db66", size = 6220787, upload-time = "2025-07-30T11:51:36.663Z" }, ] [[package]] @@ -1822,29 +1823,29 @@ wheels = [ [[package]] name = "opentelemetry-api" -version = "1.35.0" +version = "1.36.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "importlib-metadata" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/99/c9/4509bfca6bb43220ce7f863c9f791e0d5001c2ec2b5867d48586008b3d96/opentelemetry_api-1.35.0.tar.gz", hash = "sha256:a111b959bcfa5b4d7dffc2fbd6a241aa72dd78dd8e79b5b1662bda896c5d2ffe", size = 64778, upload-time = "2025-07-11T12:23:28.804Z" } +sdist = { url = "https://files.pythonhosted.org/packages/27/d2/c782c88b8afbf961d6972428821c302bd1e9e7bc361352172f0ca31296e2/opentelemetry_api-1.36.0.tar.gz", hash = "sha256:9a72572b9c416d004d492cbc6e61962c0501eaf945ece9b5a0f56597d8348aa0", size = 64780, upload-time = "2025-07-29T15:12:06.02Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1d/5a/3f8d078dbf55d18442f6a2ecedf6786d81d7245844b2b20ce2b8ad6f0307/opentelemetry_api-1.35.0-py3-none-any.whl", hash = "sha256:c4ea7e258a244858daf18474625e9cc0149b8ee354f37843415771a40c25ee06", size = 65566, upload-time = "2025-07-11T12:23:07.944Z" }, + { url = "https://files.pythonhosted.org/packages/bb/ee/6b08dde0a022c463b88f55ae81149584b125a42183407dc1045c486cc870/opentelemetry_api-1.36.0-py3-none-any.whl", hash = "sha256:02f20bcacf666e1333b6b1f04e647dc1d5111f86b8e510238fcc56d7762cda8c", size = 65564, upload-time = "2025-07-29T15:11:47.998Z" }, ] [[package]] name = "opentelemetry-distro" -version = "0.56b0" +version = "0.57b0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-api" }, { name = "opentelemetry-instrumentation" }, { name = "opentelemetry-sdk" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/78/59/cee0f566bb271818ae78460a334d52494487f615bb600f685a8211d35a60/opentelemetry_distro-0.56b0.tar.gz", hash = "sha256:87b82e2c53a4d617b9faaa7960395f73ed158bfebec790923abac0796974fe2d", size = 2582, upload-time = "2025-07-11T12:26:17.761Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fa/43/ce73692f61dded23c696d8df9d6c591f07fe9fc118a4ca026faa471ecf1a/opentelemetry_distro-0.57b0.tar.gz", hash = "sha256:b9f69d4636cf2b6b986e9737d6f3f8fade802f8d0d97bf4003a0e43144885a23", size = 2581, upload-time = "2025-07-29T15:42:43.118Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c6/e6/9acc96f6b2ab14146e9bb7f79cfae702da58592be1dc9b7053d5b5b85d37/opentelemetry_distro-0.56b0-py3-none-any.whl", hash = "sha256:9a9f8da1b0f2397d9b26de95e62c65eed2a162fe9435c57050f22132cd917752", size = 3345, upload-time = "2025-07-11T12:25:18.152Z" }, + { url = "https://files.pythonhosted.org/packages/ad/3b/9871e54c7b32fd859efd94e560a5e6689bff33207c1741f3152e25e55652/opentelemetry_distro-0.57b0-py3-none-any.whl", hash = "sha256:cd216037ae815c9478bb7b683e2e6d9e623eda368cafd73858f7ef6685931e66", size = 3343, upload-time = "2025-07-29T15:41:38.11Z" }, ] [package.optional-dependencies] @@ -1854,32 +1855,32 @@ otlp = [ [[package]] name = "opentelemetry-exporter-otlp" -version = "1.35.0" +version = "1.36.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-exporter-otlp-proto-grpc" }, { name = "opentelemetry-exporter-otlp-proto-http" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2e/2e/63718faa67b17f449a7fb7efdc7125a408cbe5d8c0bb35f423f2776d60b5/opentelemetry_exporter_otlp-1.35.0.tar.gz", hash = "sha256:f94feff09b3524df867c7876b79c96cef20068106cb5efe55340e8d08192c8a4", size = 6142, upload-time = "2025-07-11T12:23:30.128Z" } +sdist = { url = "https://files.pythonhosted.org/packages/95/7f/d31294ac28d567a14aefd855756bab79fed69c5a75df712f228f10c47e04/opentelemetry_exporter_otlp-1.36.0.tar.gz", hash = "sha256:72f166ea5a8923ac42889337f903e93af57db8893de200369b07401e98e4e06b", size = 6144, upload-time = "2025-07-29T15:12:07.153Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cf/db/2da28358d3101ca936c1643becbb4ebd69e9e48acf27f153d735a4813c6b/opentelemetry_exporter_otlp-1.35.0-py3-none-any.whl", hash = "sha256:8e6bb9025f6238db7d69bba7ee37c77e4858d0a1ff22a9e126f7c9e017e83afe", size = 7016, upload-time = "2025-07-11T12:23:10.679Z" }, + { url = "https://files.pythonhosted.org/packages/a0/a2/8966111a285124f3d6156a663ddf2aeddd52843c1a3d6b56cbd9b6c3fd0e/opentelemetry_exporter_otlp-1.36.0-py3-none-any.whl", hash = "sha256:de93b7c45bcc78296998775d52add7c63729e83ef2cd6560730a6b336d7f6494", size = 7018, upload-time = "2025-07-29T15:11:50.498Z" }, ] [[package]] name = "opentelemetry-exporter-otlp-proto-common" -version = "1.35.0" +version = "1.36.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-proto" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/56/d1/887f860529cba7fc3aba2f6a3597fefec010a17bd1b126810724707d9b51/opentelemetry_exporter_otlp_proto_common-1.35.0.tar.gz", hash = "sha256:6f6d8c39f629b9fa5c79ce19a2829dbd93034f8ac51243cdf40ed2196f00d7eb", size = 20299, upload-time = "2025-07-11T12:23:31.046Z" } +sdist = { url = "https://files.pythonhosted.org/packages/34/da/7747e57eb341c59886052d733072bc878424bf20f1d8cf203d508bbece5b/opentelemetry_exporter_otlp_proto_common-1.36.0.tar.gz", hash = "sha256:6c496ccbcbe26b04653cecadd92f73659b814c6e3579af157d8716e5f9f25cbf", size = 20302, upload-time = "2025-07-29T15:12:07.71Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/2c/e31dd3c719bff87fa77391eb7f38b1430d22868c52312cba8aad60f280e5/opentelemetry_exporter_otlp_proto_common-1.35.0-py3-none-any.whl", hash = "sha256:863465de697ae81279ede660f3918680b4480ef5f69dcdac04f30722ed7b74cc", size = 18349, upload-time = "2025-07-11T12:23:11.713Z" }, + { url = "https://files.pythonhosted.org/packages/d0/ed/22290dca7db78eb32e0101738366b5bbda00d0407f00feffb9bf8c3fdf87/opentelemetry_exporter_otlp_proto_common-1.36.0-py3-none-any.whl", hash = "sha256:0fc002a6ed63eac235ada9aa7056e5492e9a71728214a61745f6ad04b923f840", size = 18349, upload-time = "2025-07-29T15:11:51.327Z" }, ] [[package]] name = "opentelemetry-exporter-otlp-proto-grpc" -version = "1.35.0" +version = "1.36.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "googleapis-common-protos" }, @@ -1890,14 +1891,14 @@ dependencies = [ { name = "opentelemetry-sdk" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/20/de/222e4f2f8cd39250991f84d76b661534aef457cafc6a3eb3fcd513627698/opentelemetry_exporter_otlp_proto_grpc-1.35.0.tar.gz", hash = "sha256:ac4c2c3aa5674642db0df0091ab43ec08bbd91a9be469c8d9b18923eb742b9cc", size = 23794, upload-time = "2025-07-11T12:23:31.662Z" } +sdist = { url = "https://files.pythonhosted.org/packages/72/6f/6c1b0bdd0446e5532294d1d41bf11fbaea39c8a2423a4cdfe4fe6b708127/opentelemetry_exporter_otlp_proto_grpc-1.36.0.tar.gz", hash = "sha256:b281afbf7036b325b3588b5b6c8bb175069e3978d1bd24071f4a59d04c1e5bbf", size = 23822, upload-time = "2025-07-29T15:12:08.292Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/a6/3f60a77279e6a3dc21fc076dcb51be159a633b0bba5cba9fb804062a9332/opentelemetry_exporter_otlp_proto_grpc-1.35.0-py3-none-any.whl", hash = "sha256:ee31203eb3e50c7967b8fa71db366cc355099aca4e3726e489b248cdb2fd5a62", size = 18846, upload-time = "2025-07-11T12:23:12.957Z" }, + { url = "https://files.pythonhosted.org/packages/0c/67/5f6bd188d66d0fd8e81e681bbf5822e53eb150034e2611dd2b935d3ab61a/opentelemetry_exporter_otlp_proto_grpc-1.36.0-py3-none-any.whl", hash = "sha256:734e841fc6a5d6f30e7be4d8053adb703c70ca80c562ae24e8083a28fadef211", size = 18828, upload-time = "2025-07-29T15:11:52.235Z" }, ] [[package]] name = "opentelemetry-exporter-otlp-proto-http" -version = "1.35.0" +version = "1.36.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "googleapis-common-protos" }, @@ -1908,14 +1909,14 @@ dependencies = [ { name = "requests" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/88/7f/7bdc06e84266a5b4b0fefd9790b3859804bf7682ce2daabcba2e22fdb3b2/opentelemetry_exporter_otlp_proto_http-1.35.0.tar.gz", hash = "sha256:cf940147f91b450ef5f66e9980d40eb187582eed399fa851f4a7a45bb880de79", size = 15908, upload-time = "2025-07-11T12:23:32.335Z" } +sdist = { url = "https://files.pythonhosted.org/packages/25/85/6632e7e5700ba1ce5b8a065315f92c1e6d787ccc4fb2bdab15139eaefc82/opentelemetry_exporter_otlp_proto_http-1.36.0.tar.gz", hash = "sha256:dd3637f72f774b9fc9608ab1ac479f8b44d09b6fb5b2f3df68a24ad1da7d356e", size = 16213, upload-time = "2025-07-29T15:12:08.932Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d4/71/f118cd90dc26797077931dd598bde5e0cc652519db166593f962f8fcd022/opentelemetry_exporter_otlp_proto_http-1.35.0-py3-none-any.whl", hash = "sha256:9a001e3df3c7f160fb31056a28ed7faa2de7df68877ae909516102ae36a54e1d", size = 18589, upload-time = "2025-07-11T12:23:13.906Z" }, + { url = "https://files.pythonhosted.org/packages/7f/41/a680d38b34f8f5ddbd78ed9f0042e1cc712d58ec7531924d71cb1e6c629d/opentelemetry_exporter_otlp_proto_http-1.36.0-py3-none-any.whl", hash = "sha256:3d769f68e2267e7abe4527f70deb6f598f40be3ea34c6adc35789bea94a32902", size = 18752, upload-time = "2025-07-29T15:11:53.164Z" }, ] [[package]] name = "opentelemetry-instrumentation" -version = "0.56b0" +version = "0.57b0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-api" }, @@ -1923,14 +1924,14 @@ dependencies = [ { name = "packaging" }, { name = "wrapt" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bb/14/964e90f524655aed5c699190dad8dd9a05ed0f5fa334b4b33532237c2b51/opentelemetry_instrumentation-0.56b0.tar.gz", hash = "sha256:d2dbb3021188ca0ec8c5606349ee9a2919239627e8341d4d37f1d21ec3291d11", size = 28551, upload-time = "2025-07-11T12:26:19.305Z" } +sdist = { url = "https://files.pythonhosted.org/packages/12/37/cf17cf28f945a3aca5a038cfbb45ee01317d4f7f3a0e5209920883fe9b08/opentelemetry_instrumentation-0.57b0.tar.gz", hash = "sha256:f2a30135ba77cdea2b0e1df272f4163c154e978f57214795d72f40befd4fcf05", size = 30807, upload-time = "2025-07-29T15:42:44.746Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/26/aa/2328f27200b8e51640d4d7ff5343ba6a81ab7d2650a9f574db016aae4adf/opentelemetry_instrumentation-0.56b0-py3-none-any.whl", hash = "sha256:948967f7c8f5bdc6e43512ba74c9ae14acb48eb72a35b61afe8db9909f743be3", size = 31105, upload-time = "2025-07-11T12:25:22.788Z" }, + { url = "https://files.pythonhosted.org/packages/d0/6f/f20cd1542959f43fb26a5bf9bb18cd81a1ea0700e8870c8f369bd07f5c65/opentelemetry_instrumentation-0.57b0-py3-none-any.whl", hash = "sha256:9109280f44882e07cec2850db28210b90600ae9110b42824d196de357cbddf7e", size = 32460, upload-time = "2025-07-29T15:41:40.883Z" }, ] [[package]] name = "opentelemetry-instrumentation-httpx" -version = "0.56b0" +version = "0.57b0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-api" }, @@ -1939,57 +1940,57 @@ dependencies = [ { name = "opentelemetry-util-http" }, { name = "wrapt" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8b/93/784623262776d90aa07e5cc08f58e1d476ed4b208127c1718db4b57b78c8/opentelemetry_instrumentation_httpx-0.56b0.tar.gz", hash = "sha256:d93c7a0e0ce5cc2170f7cc0d26f19167bc8314b7d2a5204afdf84000d5ca8647", size = 19510, upload-time = "2025-07-11T12:26:37.492Z" } +sdist = { url = "https://files.pythonhosted.org/packages/01/28/65fea8b8e7f19502a8af1229c62384f9211c1480f5dee1776841810d6551/opentelemetry_instrumentation_httpx-0.57b0.tar.gz", hash = "sha256:ea5669cdb17185f8d247c2dbf756ae5b95b53110ca4d58424f2be5cc7223dbdd", size = 19511, upload-time = "2025-07-29T15:43:00.575Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b4/0e/fe2f38e0170a22a44b26e9a8f555ac23b2fcf09f89264d718800ec1d5954/opentelemetry_instrumentation_httpx-0.56b0-py3-none-any.whl", hash = "sha256:34d9558413d695ea69fe002efa07c00aa859a8aa4930815726e5813d5f002e1d", size = 15113, upload-time = "2025-07-11T12:25:45.671Z" }, + { url = "https://files.pythonhosted.org/packages/bd/24/e59b319a5c6a41c6b4230f5e25651edbeb3a8d248afa1b411fd07cc3f9bf/opentelemetry_instrumentation_httpx-0.57b0-py3-none-any.whl", hash = "sha256:729fef97624016d3e5b03b71f51c9a1a2f7480b023373186d643fbed7496712a", size = 15111, upload-time = "2025-07-29T15:42:06.501Z" }, ] [[package]] name = "opentelemetry-proto" -version = "1.35.0" +version = "1.36.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/dc/a2/7366e32d9a2bccbb8614942dbea2cf93c209610385ea966cb050334f8df7/opentelemetry_proto-1.35.0.tar.gz", hash = "sha256:532497341bd3e1c074def7c5b00172601b28bb83b48afc41a4b779f26eb4ee05", size = 46151, upload-time = "2025-07-11T12:23:38.797Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fd/02/f6556142301d136e3b7e95ab8ea6a5d9dc28d879a99f3dd673b5f97dca06/opentelemetry_proto-1.36.0.tar.gz", hash = "sha256:0f10b3c72f74c91e0764a5ec88fd8f1c368ea5d9c64639fb455e2854ef87dd2f", size = 46152, upload-time = "2025-07-29T15:12:15.717Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/00/a7/3f05de580da7e8a8b8dff041d3d07a20bf3bb62d3bcc027f8fd669a73ff4/opentelemetry_proto-1.35.0-py3-none-any.whl", hash = "sha256:98fffa803164499f562718384e703be8d7dfbe680192279a0429cb150a2f8809", size = 72536, upload-time = "2025-07-11T12:23:23.247Z" }, + { url = "https://files.pythonhosted.org/packages/b3/57/3361e06136225be8180e879199caea520f38026f8071366241ac458beb8d/opentelemetry_proto-1.36.0-py3-none-any.whl", hash = "sha256:151b3bf73a09f94afc658497cf77d45a565606f62ce0c17acb08cd9937ca206e", size = 72537, upload-time = "2025-07-29T15:12:02.243Z" }, ] [[package]] name = "opentelemetry-sdk" -version = "1.35.0" +version = "1.36.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-api" }, { name = "opentelemetry-semantic-conventions" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9a/cf/1eb2ed2ce55e0a9aa95b3007f26f55c7943aeef0a783bb006bdd92b3299e/opentelemetry_sdk-1.35.0.tar.gz", hash = "sha256:2a400b415ab68aaa6f04e8a6a9f6552908fb3090ae2ff78d6ae0c597ac581954", size = 160871, upload-time = "2025-07-11T12:23:39.566Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/85/8567a966b85a2d3f971c4d42f781c305b2b91c043724fa08fd37d158e9dc/opentelemetry_sdk-1.36.0.tar.gz", hash = "sha256:19c8c81599f51b71670661ff7495c905d8fdf6976e41622d5245b791b06fa581", size = 162557, upload-time = "2025-07-29T15:12:16.76Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/01/4f/8e32b757ef3b660511b638ab52d1ed9259b666bdeeceba51a082ce3aea95/opentelemetry_sdk-1.35.0-py3-none-any.whl", hash = "sha256:223d9e5f5678518f4842311bb73966e0b6db5d1e0b74e35074c052cd2487f800", size = 119379, upload-time = "2025-07-11T12:23:24.521Z" }, + { url = "https://files.pythonhosted.org/packages/0b/59/7bed362ad1137ba5886dac8439e84cd2df6d087be7c09574ece47ae9b22c/opentelemetry_sdk-1.36.0-py3-none-any.whl", hash = "sha256:19fe048b42e98c5c1ffe85b569b7073576ad4ce0bcb6e9b4c6a39e890a6c45fb", size = 119995, upload-time = "2025-07-29T15:12:03.181Z" }, ] [[package]] name = "opentelemetry-semantic-conventions" -version = "0.56b0" +version = "0.57b0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-api" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/32/8e/214fa817f63b9f068519463d8ab46afd5d03b98930c39394a37ae3e741d0/opentelemetry_semantic_conventions-0.56b0.tar.gz", hash = "sha256:c114c2eacc8ff6d3908cb328c811eaf64e6d68623840be9224dc829c4fd6c2ea", size = 124221, upload-time = "2025-07-11T12:23:40.71Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/31/67dfa252ee88476a29200b0255bda8dfc2cf07b56ad66dc9a6221f7dc787/opentelemetry_semantic_conventions-0.57b0.tar.gz", hash = "sha256:609a4a79c7891b4620d64c7aac6898f872d790d75f22019913a660756f27ff32", size = 124225, upload-time = "2025-07-29T15:12:17.873Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/3f/e80c1b017066a9d999efffe88d1cce66116dcf5cb7f80c41040a83b6e03b/opentelemetry_semantic_conventions-0.56b0-py3-none-any.whl", hash = "sha256:df44492868fd6b482511cc43a942e7194be64e94945f572db24df2e279a001a2", size = 201625, upload-time = "2025-07-11T12:23:25.63Z" }, + { url = "https://files.pythonhosted.org/packages/05/75/7d591371c6c39c73de5ce5da5a2cc7b72d1d1cd3f8f4638f553c01c37b11/opentelemetry_semantic_conventions-0.57b0-py3-none-any.whl", hash = "sha256:757f7e76293294f124c827e514c2a3144f191ef175b069ce8d1211e1e38e9e78", size = 201627, upload-time = "2025-07-29T15:12:04.174Z" }, ] [[package]] name = "opentelemetry-util-http" -version = "0.56b0" +version = "0.57b0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ce/c5/80c603e44071d172d4e9c909b13e3d9924b90b08a581eff78a8daf77686e/opentelemetry_util_http-0.56b0.tar.gz", hash = "sha256:9a0c8573a68e3242a2d3e5840476088e63714e6d3e25f67127945ab0c7143074", size = 9404, upload-time = "2025-07-11T12:26:55.365Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9b/1b/6229c45445e08e798fa825f5376f6d6a4211d29052a4088eed6d577fa653/opentelemetry_util_http-0.57b0.tar.gz", hash = "sha256:f7417595ead0eb42ed1863ec9b2f839fc740368cd7bbbfc1d0a47bc1ab0aba11", size = 9405, upload-time = "2025-07-29T15:43:19.916Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/05/ca/20763fba2af06e73f0e666e46a32b5cdb9d2d75dcb5fd221f50c818cae43/opentelemetry_util_http-0.56b0-py3-none-any.whl", hash = "sha256:e26dd8c7f71da6806f1e65ac7cde189d389b8f152506146968f59b7a607dc8cf", size = 7645, upload-time = "2025-07-11T12:26:16.106Z" }, + { url = "https://files.pythonhosted.org/packages/0b/a6/b98d508d189b9c208f5978d0906141747d7e6df7c7cafec03657ed1ed559/opentelemetry_util_http-0.57b0-py3-none-any.whl", hash = "sha256:e54c0df5543951e471c3d694f85474977cd5765a3b7654398c83bab3d2ffb8e9", size = 7643, upload-time = "2025-07-29T15:42:41.744Z" }, ] [[package]] @@ -2593,27 +2594,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.12.5" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/30/cd/01015eb5034605fd98d829c5839ec2c6b4582b479707f7c1c2af861e8258/ruff-0.12.5.tar.gz", hash = "sha256:b209db6102b66f13625940b7f8c7d0f18e20039bb7f6101fbdac935c9612057e", size = 5170722, upload-time = "2025-07-24T13:26:37.456Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d4/de/ad2f68f0798ff15dd8c0bcc2889558970d9a685b3249565a937cd820ad34/ruff-0.12.5-py3-none-linux_armv6l.whl", hash = "sha256:1de2c887e9dec6cb31fcb9948299de5b2db38144e66403b9660c9548a67abd92", size = 11819133, upload-time = "2025-07-24T13:25:56.369Z" }, - { url = "https://files.pythonhosted.org/packages/f8/fc/c6b65cd0e7fbe60f17e7ad619dca796aa49fbca34bb9bea5f8faf1ec2643/ruff-0.12.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:d1ab65e7d8152f519e7dea4de892317c9da7a108da1c56b6a3c1d5e7cf4c5e9a", size = 12501114, upload-time = "2025-07-24T13:25:59.471Z" }, - { url = "https://files.pythonhosted.org/packages/c5/de/c6bec1dce5ead9f9e6a946ea15e8d698c35f19edc508289d70a577921b30/ruff-0.12.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:962775ed5b27c7aa3fdc0d8f4d4433deae7659ef99ea20f783d666e77338b8cf", size = 11716873, upload-time = "2025-07-24T13:26:01.496Z" }, - { url = "https://files.pythonhosted.org/packages/a1/16/cf372d2ebe91e4eb5b82a2275c3acfa879e0566a7ac94d331ea37b765ac8/ruff-0.12.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:73b4cae449597e7195a49eb1cdca89fd9fbb16140c7579899e87f4c85bf82f73", size = 11958829, upload-time = "2025-07-24T13:26:03.721Z" }, - { url = "https://files.pythonhosted.org/packages/25/bf/cd07e8f6a3a6ec746c62556b4c4b79eeb9b0328b362bb8431b7b8afd3856/ruff-0.12.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b13489c3dc50de5e2d40110c0cce371e00186b880842e245186ca862bf9a1ac", size = 11626619, upload-time = "2025-07-24T13:26:06.118Z" }, - { url = "https://files.pythonhosted.org/packages/d8/c9/c2ccb3b8cbb5661ffda6925f81a13edbb786e623876141b04919d1128370/ruff-0.12.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1504fea81461cf4841778b3ef0a078757602a3b3ea4b008feb1308cb3f23e08", size = 13221894, upload-time = "2025-07-24T13:26:08.292Z" }, - { url = "https://files.pythonhosted.org/packages/6b/58/68a5be2c8e5590ecdad922b2bcd5583af19ba648f7648f95c51c3c1eca81/ruff-0.12.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c7da4129016ae26c32dfcbd5b671fe652b5ab7fc40095d80dcff78175e7eddd4", size = 14163909, upload-time = "2025-07-24T13:26:10.474Z" }, - { url = "https://files.pythonhosted.org/packages/bd/d1/ef6b19622009ba8386fdb792c0743f709cf917b0b2f1400589cbe4739a33/ruff-0.12.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ca972c80f7ebcfd8af75a0f18b17c42d9f1ef203d163669150453f50ca98ab7b", size = 13583652, upload-time = "2025-07-24T13:26:13.381Z" }, - { url = "https://files.pythonhosted.org/packages/62/e3/1c98c566fe6809a0c83751d825a03727f242cdbe0d142c9e292725585521/ruff-0.12.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8dbbf9f25dfb501f4237ae7501d6364b76a01341c6f1b2cd6764fe449124bb2a", size = 12700451, upload-time = "2025-07-24T13:26:15.488Z" }, - { url = "https://files.pythonhosted.org/packages/24/ff/96058f6506aac0fbc0d0fc0d60b0d0bd746240a0594657a2d94ad28033ba/ruff-0.12.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c47dea6ae39421851685141ba9734767f960113d51e83fd7bb9958d5be8763a", size = 12937465, upload-time = "2025-07-24T13:26:17.808Z" }, - { url = "https://files.pythonhosted.org/packages/eb/d3/68bc5e7ab96c94b3589d1789f2dd6dd4b27b263310019529ac9be1e8f31b/ruff-0.12.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c5076aa0e61e30f848846f0265c873c249d4b558105b221be1828f9f79903dc5", size = 11771136, upload-time = "2025-07-24T13:26:20.422Z" }, - { url = "https://files.pythonhosted.org/packages/52/75/7356af30a14584981cabfefcf6106dea98cec9a7af4acb5daaf4b114845f/ruff-0.12.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a5a4c7830dadd3d8c39b1cc85386e2c1e62344f20766be6f173c22fb5f72f293", size = 11601644, upload-time = "2025-07-24T13:26:22.928Z" }, - { url = "https://files.pythonhosted.org/packages/c2/67/91c71d27205871737cae11025ee2b098f512104e26ffd8656fd93d0ada0a/ruff-0.12.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:46699f73c2b5b137b9dc0fc1a190b43e35b008b398c6066ea1350cce6326adcb", size = 12478068, upload-time = "2025-07-24T13:26:26.134Z" }, - { url = "https://files.pythonhosted.org/packages/34/04/b6b00383cf2f48e8e78e14eb258942fdf2a9bf0287fbf5cdd398b749193a/ruff-0.12.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5a655a0a0d396f0f072faafc18ebd59adde8ca85fb848dc1b0d9f024b9c4d3bb", size = 12991537, upload-time = "2025-07-24T13:26:28.533Z" }, - { url = "https://files.pythonhosted.org/packages/3e/b9/053d6445dc7544fb6594785056d8ece61daae7214859ada4a152ad56b6e0/ruff-0.12.5-py3-none-win32.whl", hash = "sha256:dfeb2627c459b0b78ca2bbdc38dd11cc9a0a88bf91db982058b26ce41714ffa9", size = 11751575, upload-time = "2025-07-24T13:26:30.835Z" }, - { url = "https://files.pythonhosted.org/packages/bc/0f/ab16e8259493137598b9149734fec2e06fdeda9837e6f634f5c4e35916da/ruff-0.12.5-py3-none-win_amd64.whl", hash = "sha256:ae0d90cf5f49466c954991b9d8b953bd093c32c27608e409ae3564c63c5306a5", size = 12882273, upload-time = "2025-07-24T13:26:32.929Z" }, - { url = "https://files.pythonhosted.org/packages/00/db/c376b0661c24cf770cb8815268190668ec1330eba8374a126ceef8c72d55/ruff-0.12.5-py3-none-win_arm64.whl", hash = "sha256:48cdbfc633de2c5c37d9f090ba3b352d1576b0015bfc3bc98eaf230275b7e805", size = 11951564, upload-time = "2025-07-24T13:26:34.994Z" }, +version = "0.12.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/81/0bd3594fa0f690466e41bd033bdcdf86cba8288345ac77ad4afbe5ec743a/ruff-0.12.7.tar.gz", hash = "sha256:1fc3193f238bc2d7968772c82831a4ff69252f673be371fb49663f0068b7ec71", size = 5197814, upload-time = "2025-07-29T22:32:35.877Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/d2/6cb35e9c85e7a91e8d22ab32ae07ac39cc34a71f1009a6f9e4a2a019e602/ruff-0.12.7-py3-none-linux_armv6l.whl", hash = "sha256:76e4f31529899b8c434c3c1dede98c4483b89590e15fb49f2d46183801565303", size = 11852189, upload-time = "2025-07-29T22:31:41.281Z" }, + { url = "https://files.pythonhosted.org/packages/63/5b/a4136b9921aa84638f1a6be7fb086f8cad0fde538ba76bda3682f2599a2f/ruff-0.12.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:789b7a03e72507c54fb3ba6209e4bb36517b90f1a3569ea17084e3fd295500fb", size = 12519389, upload-time = "2025-07-29T22:31:54.265Z" }, + { url = "https://files.pythonhosted.org/packages/a8/c9/3e24a8472484269b6b1821794141f879c54645a111ded4b6f58f9ab0705f/ruff-0.12.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:2e1c2a3b8626339bb6369116e7030a4cf194ea48f49b64bb505732a7fce4f4e3", size = 11743384, upload-time = "2025-07-29T22:31:59.575Z" }, + { url = "https://files.pythonhosted.org/packages/26/7c/458dd25deeb3452c43eaee853c0b17a1e84169f8021a26d500ead77964fd/ruff-0.12.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32dec41817623d388e645612ec70d5757a6d9c035f3744a52c7b195a57e03860", size = 11943759, upload-time = "2025-07-29T22:32:01.95Z" }, + { url = "https://files.pythonhosted.org/packages/7f/8b/658798472ef260ca050e400ab96ef7e85c366c39cf3dfbef4d0a46a528b6/ruff-0.12.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47ef751f722053a5df5fa48d412dbb54d41ab9b17875c6840a58ec63ff0c247c", size = 11654028, upload-time = "2025-07-29T22:32:04.367Z" }, + { url = "https://files.pythonhosted.org/packages/a8/86/9c2336f13b2a3326d06d39178fd3448dcc7025f82514d1b15816fe42bfe8/ruff-0.12.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a828a5fc25a3efd3e1ff7b241fd392686c9386f20e5ac90aa9234a5faa12c423", size = 13225209, upload-time = "2025-07-29T22:32:06.952Z" }, + { url = "https://files.pythonhosted.org/packages/76/69/df73f65f53d6c463b19b6b312fd2391dc36425d926ec237a7ed028a90fc1/ruff-0.12.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5726f59b171111fa6a69d82aef48f00b56598b03a22f0f4170664ff4d8298efb", size = 14182353, upload-time = "2025-07-29T22:32:10.053Z" }, + { url = "https://files.pythonhosted.org/packages/58/1e/de6cda406d99fea84b66811c189b5ea139814b98125b052424b55d28a41c/ruff-0.12.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:74e6f5c04c4dd4aba223f4fe6e7104f79e0eebf7d307e4f9b18c18362124bccd", size = 13631555, upload-time = "2025-07-29T22:32:12.644Z" }, + { url = "https://files.pythonhosted.org/packages/6f/ae/625d46d5164a6cc9261945a5e89df24457dc8262539ace3ac36c40f0b51e/ruff-0.12.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d0bfe4e77fba61bf2ccadf8cf005d6133e3ce08793bbe870dd1c734f2699a3e", size = 12667556, upload-time = "2025-07-29T22:32:15.312Z" }, + { url = "https://files.pythonhosted.org/packages/55/bf/9cb1ea5e3066779e42ade8d0cd3d3b0582a5720a814ae1586f85014656b6/ruff-0.12.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06bfb01e1623bf7f59ea749a841da56f8f653d641bfd046edee32ede7ff6c606", size = 12939784, upload-time = "2025-07-29T22:32:17.69Z" }, + { url = "https://files.pythonhosted.org/packages/55/7f/7ead2663be5627c04be83754c4f3096603bf5e99ed856c7cd29618c691bd/ruff-0.12.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e41df94a957d50083fd09b916d6e89e497246698c3f3d5c681c8b3e7b9bb4ac8", size = 11771356, upload-time = "2025-07-29T22:32:20.134Z" }, + { url = "https://files.pythonhosted.org/packages/17/40/a95352ea16edf78cd3a938085dccc55df692a4d8ba1b3af7accbe2c806b0/ruff-0.12.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4000623300563c709458d0ce170c3d0d788c23a058912f28bbadc6f905d67afa", size = 11612124, upload-time = "2025-07-29T22:32:22.645Z" }, + { url = "https://files.pythonhosted.org/packages/4d/74/633b04871c669e23b8917877e812376827c06df866e1677f15abfadc95cb/ruff-0.12.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:69ffe0e5f9b2cf2b8e289a3f8945b402a1b19eff24ec389f45f23c42a3dd6fb5", size = 12479945, upload-time = "2025-07-29T22:32:24.765Z" }, + { url = "https://files.pythonhosted.org/packages/be/34/c3ef2d7799c9778b835a76189c6f53c179d3bdebc8c65288c29032e03613/ruff-0.12.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a07a5c8ffa2611a52732bdc67bf88e243abd84fe2d7f6daef3826b59abbfeda4", size = 12998677, upload-time = "2025-07-29T22:32:27.022Z" }, + { url = "https://files.pythonhosted.org/packages/77/ab/aca2e756ad7b09b3d662a41773f3edcbd262872a4fc81f920dc1ffa44541/ruff-0.12.7-py3-none-win32.whl", hash = "sha256:c928f1b2ec59fb77dfdf70e0419408898b63998789cc98197e15f560b9e77f77", size = 11756687, upload-time = "2025-07-29T22:32:29.381Z" }, + { url = "https://files.pythonhosted.org/packages/b4/71/26d45a5042bc71db22ddd8252ca9d01e9ca454f230e2996bb04f16d72799/ruff-0.12.7-py3-none-win_amd64.whl", hash = "sha256:9c18f3d707ee9edf89da76131956aba1270c6348bfee8f6c647de841eac7194f", size = 12912365, upload-time = "2025-07-29T22:32:31.517Z" }, + { url = "https://files.pythonhosted.org/packages/4c/9b/0b8aa09817b63e78d94b4977f18b1fcaead3165a5ee49251c5d5c245bb2d/ruff-0.12.7-py3-none-win_arm64.whl", hash = "sha256:dfce05101dbd11833a0776716d5d1578641b7fddb537fe7fa956ab85d1769b69", size = 11982083, upload-time = "2025-07-29T22:32:33.881Z" }, ] [[package]] @@ -2637,7 +2638,7 @@ dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "numpy", version = "2.3.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "scipy", version = "1.16.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "scipy", version = "1.16.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "threadpoolctl" }, ] sdist = { url = "https://files.pythonhosted.org/packages/41/84/5f4af978fff619706b8961accac84780a6d298d82a8873446f72edb4ead0/scikit_learn-1.7.1.tar.gz", hash = "sha256:24b3f1e976a4665aa74ee0fcaac2b8fccc6ae77c8e07ab25da3ba6d3292b9802", size = 7190445, upload-time = "2025-07-18T08:01:54.5Z" } @@ -2730,7 +2731,7 @@ wheels = [ [[package]] name = "scipy" -version = "1.16.0" +version = "1.16.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.13'", @@ -2739,44 +2740,62 @@ resolution-markers = [ dependencies = [ { name = "numpy", version = "2.3.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/81/18/b06a83f0c5ee8cddbde5e3f3d0bb9b702abfa5136ef6d4620ff67df7eee5/scipy-1.16.0.tar.gz", hash = "sha256:b5ef54021e832869c8cfb03bc3bf20366cbcd426e02a58e8a58d7584dfbb8f62", size = 30581216, upload-time = "2025-06-22T16:27:55.782Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/f8/53fc4884df6b88afd5f5f00240bdc49fee2999c7eff3acf5953eb15bc6f8/scipy-1.16.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:deec06d831b8f6b5fb0b652433be6a09db29e996368ce5911faf673e78d20085", size = 36447362, upload-time = "2025-06-22T16:18:17.817Z" }, - { url = "https://files.pythonhosted.org/packages/c9/25/fad8aa228fa828705142a275fc593d701b1817c98361a2d6b526167d07bc/scipy-1.16.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:d30c0fe579bb901c61ab4bb7f3eeb7281f0d4c4a7b52dbf563c89da4fd2949be", size = 28547120, upload-time = "2025-06-22T16:18:24.117Z" }, - { url = "https://files.pythonhosted.org/packages/8d/be/d324ddf6b89fd1c32fecc307f04d095ce84abb52d2e88fab29d0cd8dc7a8/scipy-1.16.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:b2243561b45257f7391d0f49972fca90d46b79b8dbcb9b2cb0f9df928d370ad4", size = 20818922, upload-time = "2025-06-22T16:18:28.035Z" }, - { url = "https://files.pythonhosted.org/packages/cd/e0/cf3f39e399ac83fd0f3ba81ccc5438baba7cfe02176be0da55ff3396f126/scipy-1.16.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:e6d7dfc148135e9712d87c5f7e4f2ddc1304d1582cb3a7d698bbadedb61c7afd", size = 23409695, upload-time = "2025-06-22T16:18:32.497Z" }, - { url = "https://files.pythonhosted.org/packages/5b/61/d92714489c511d3ffd6830ac0eb7f74f243679119eed8b9048e56b9525a1/scipy-1.16.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:90452f6a9f3fe5a2cf3748e7be14f9cc7d9b124dce19667b54f5b429d680d539", size = 33444586, upload-time = "2025-06-22T16:18:37.992Z" }, - { url = "https://files.pythonhosted.org/packages/af/2c/40108915fd340c830aee332bb85a9160f99e90893e58008b659b9f3dddc0/scipy-1.16.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a2f0bf2f58031c8701a8b601df41701d2a7be17c7ffac0a4816aeba89c4cdac8", size = 35284126, upload-time = "2025-06-22T16:18:43.605Z" }, - { url = "https://files.pythonhosted.org/packages/d3/30/e9eb0ad3d0858df35d6c703cba0a7e16a18a56a9e6b211d861fc6f261c5f/scipy-1.16.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6c4abb4c11fc0b857474241b812ce69ffa6464b4bd8f4ecb786cf240367a36a7", size = 35608257, upload-time = "2025-06-22T16:18:49.09Z" }, - { url = "https://files.pythonhosted.org/packages/c8/ff/950ee3e0d612b375110d8cda211c1f787764b4c75e418a4b71f4a5b1e07f/scipy-1.16.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b370f8f6ac6ef99815b0d5c9f02e7ade77b33007d74802efc8316c8db98fd11e", size = 38040541, upload-time = "2025-06-22T16:18:55.077Z" }, - { url = "https://files.pythonhosted.org/packages/8b/c9/750d34788288d64ffbc94fdb4562f40f609d3f5ef27ab4f3a4ad00c9033e/scipy-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:a16ba90847249bedce8aa404a83fb8334b825ec4a8e742ce6012a7a5e639f95c", size = 38570814, upload-time = "2025-06-22T16:19:00.912Z" }, - { url = "https://files.pythonhosted.org/packages/01/c0/c943bc8d2bbd28123ad0f4f1eef62525fa1723e84d136b32965dcb6bad3a/scipy-1.16.0-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:7eb6bd33cef4afb9fa5f1fb25df8feeb1e52d94f21a44f1d17805b41b1da3180", size = 36459071, upload-time = "2025-06-22T16:19:06.605Z" }, - { url = "https://files.pythonhosted.org/packages/99/0d/270e2e9f1a4db6ffbf84c9a0b648499842046e4e0d9b2275d150711b3aba/scipy-1.16.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:1dbc8fdba23e4d80394ddfab7a56808e3e6489176d559c6c71935b11a2d59db1", size = 28490500, upload-time = "2025-06-22T16:19:11.775Z" }, - { url = "https://files.pythonhosted.org/packages/1c/22/01d7ddb07cff937d4326198ec8d10831367a708c3da72dfd9b7ceaf13028/scipy-1.16.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:7dcf42c380e1e3737b343dec21095c9a9ad3f9cbe06f9c05830b44b1786c9e90", size = 20762345, upload-time = "2025-06-22T16:19:15.813Z" }, - { url = "https://files.pythonhosted.org/packages/34/7f/87fd69856569ccdd2a5873fe5d7b5bbf2ad9289d7311d6a3605ebde3a94b/scipy-1.16.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:26ec28675f4a9d41587266084c626b02899db373717d9312fa96ab17ca1ae94d", size = 23418563, upload-time = "2025-06-22T16:19:20.746Z" }, - { url = "https://files.pythonhosted.org/packages/f6/f1/e4f4324fef7f54160ab749efbab6a4bf43678a9eb2e9817ed71a0a2fd8de/scipy-1.16.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:952358b7e58bd3197cfbd2f2f2ba829f258404bdf5db59514b515a8fe7a36c52", size = 33203951, upload-time = "2025-06-22T16:19:25.813Z" }, - { url = "https://files.pythonhosted.org/packages/6d/f0/b6ac354a956384fd8abee2debbb624648125b298f2c4a7b4f0d6248048a5/scipy-1.16.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:03931b4e870c6fef5b5c0970d52c9f6ddd8c8d3e934a98f09308377eba6f3824", size = 35070225, upload-time = "2025-06-22T16:19:31.416Z" }, - { url = "https://files.pythonhosted.org/packages/e5/73/5cbe4a3fd4bc3e2d67ffad02c88b83edc88f381b73ab982f48f3df1a7790/scipy-1.16.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:512c4f4f85912767c351a0306824ccca6fd91307a9f4318efe8fdbd9d30562ef", size = 35389070, upload-time = "2025-06-22T16:19:37.387Z" }, - { url = "https://files.pythonhosted.org/packages/86/e8/a60da80ab9ed68b31ea5a9c6dfd3c2f199347429f229bf7f939a90d96383/scipy-1.16.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e69f798847e9add03d512eaf5081a9a5c9a98757d12e52e6186ed9681247a1ac", size = 37825287, upload-time = "2025-06-22T16:19:43.375Z" }, - { url = "https://files.pythonhosted.org/packages/ea/b5/29fece1a74c6a94247f8a6fb93f5b28b533338e9c34fdcc9cfe7a939a767/scipy-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:adf9b1999323ba335adc5d1dc7add4781cb5a4b0ef1e98b79768c05c796c4e49", size = 38431929, upload-time = "2025-06-22T16:19:49.385Z" }, - { url = "https://files.pythonhosted.org/packages/46/95/0746417bc24be0c2a7b7563946d61f670a3b491b76adede420e9d173841f/scipy-1.16.0-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:e9f414cbe9ca289a73e0cc92e33a6a791469b6619c240aa32ee18abdce8ab451", size = 36418162, upload-time = "2025-06-22T16:19:56.3Z" }, - { url = "https://files.pythonhosted.org/packages/19/5a/914355a74481b8e4bbccf67259bbde171348a3f160b67b4945fbc5f5c1e5/scipy-1.16.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:bbba55fb97ba3cdef9b1ee973f06b09d518c0c7c66a009c729c7d1592be1935e", size = 28465985, upload-time = "2025-06-22T16:20:01.238Z" }, - { url = "https://files.pythonhosted.org/packages/58/46/63477fc1246063855969cbefdcee8c648ba4b17f67370bd542ba56368d0b/scipy-1.16.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:58e0d4354eacb6004e7aa1cd350e5514bd0270acaa8d5b36c0627bb3bb486974", size = 20737961, upload-time = "2025-06-22T16:20:05.913Z" }, - { url = "https://files.pythonhosted.org/packages/93/86/0fbb5588b73555e40f9d3d6dde24ee6fac7d8e301a27f6f0cab9d8f66ff2/scipy-1.16.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:75b2094ec975c80efc273567436e16bb794660509c12c6a31eb5c195cbf4b6dc", size = 23377941, upload-time = "2025-06-22T16:20:10.668Z" }, - { url = "https://files.pythonhosted.org/packages/ca/80/a561f2bf4c2da89fa631b3cbf31d120e21ea95db71fd9ec00cb0247c7a93/scipy-1.16.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6b65d232157a380fdd11a560e7e21cde34fdb69d65c09cb87f6cc024ee376351", size = 33196703, upload-time = "2025-06-22T16:20:16.097Z" }, - { url = "https://files.pythonhosted.org/packages/11/6b/3443abcd0707d52e48eb315e33cc669a95e29fc102229919646f5a501171/scipy-1.16.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1d8747f7736accd39289943f7fe53a8333be7f15a82eea08e4afe47d79568c32", size = 35083410, upload-time = "2025-06-22T16:20:21.734Z" }, - { url = "https://files.pythonhosted.org/packages/20/ab/eb0fc00e1e48961f1bd69b7ad7e7266896fe5bad4ead91b5fc6b3561bba4/scipy-1.16.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eb9f147a1b8529bb7fec2a85cf4cf42bdfadf9e83535c309a11fdae598c88e8b", size = 35387829, upload-time = "2025-06-22T16:20:27.548Z" }, - { url = "https://files.pythonhosted.org/packages/57/9e/d6fc64e41fad5d481c029ee5a49eefc17f0b8071d636a02ceee44d4a0de2/scipy-1.16.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d2b83c37edbfa837a8923d19c749c1935ad3d41cf196006a24ed44dba2ec4358", size = 37841356, upload-time = "2025-06-22T16:20:35.112Z" }, - { url = "https://files.pythonhosted.org/packages/7c/a7/4c94bbe91f12126b8bf6709b2471900577b7373a4fd1f431f28ba6f81115/scipy-1.16.0-cp313-cp313-win_amd64.whl", hash = "sha256:79a3c13d43c95aa80b87328a46031cf52508cf5f4df2767602c984ed1d3c6bbe", size = 38403710, upload-time = "2025-06-22T16:21:54.473Z" }, - { url = "https://files.pythonhosted.org/packages/47/20/965da8497f6226e8fa90ad3447b82ed0e28d942532e92dd8b91b43f100d4/scipy-1.16.0-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:f91b87e1689f0370690e8470916fe1b2308e5b2061317ff76977c8f836452a47", size = 36813833, upload-time = "2025-06-22T16:20:43.925Z" }, - { url = "https://files.pythonhosted.org/packages/28/f4/197580c3dac2d234e948806e164601c2df6f0078ed9f5ad4a62685b7c331/scipy-1.16.0-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:88a6ca658fb94640079e7a50b2ad3b67e33ef0f40e70bdb7dc22017dae73ac08", size = 28974431, upload-time = "2025-06-22T16:20:51.302Z" }, - { url = "https://files.pythonhosted.org/packages/8a/fc/e18b8550048d9224426e76906694c60028dbdb65d28b1372b5503914b89d/scipy-1.16.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:ae902626972f1bd7e4e86f58fd72322d7f4ec7b0cfc17b15d4b7006efc385176", size = 21246454, upload-time = "2025-06-22T16:20:57.276Z" }, - { url = "https://files.pythonhosted.org/packages/8c/48/07b97d167e0d6a324bfd7484cd0c209cc27338b67e5deadae578cf48e809/scipy-1.16.0-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:8cb824c1fc75ef29893bc32b3ddd7b11cf9ab13c1127fe26413a05953b8c32ed", size = 23772979, upload-time = "2025-06-22T16:21:03.363Z" }, - { url = "https://files.pythonhosted.org/packages/4c/4f/9efbd3f70baf9582edf271db3002b7882c875ddd37dc97f0f675ad68679f/scipy-1.16.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:de2db7250ff6514366a9709c2cba35cb6d08498e961cba20d7cff98a7ee88938", size = 33341972, upload-time = "2025-06-22T16:21:11.14Z" }, - { url = "https://files.pythonhosted.org/packages/3f/dc/9e496a3c5dbe24e76ee24525155ab7f659c20180bab058ef2c5fa7d9119c/scipy-1.16.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e85800274edf4db8dd2e4e93034f92d1b05c9421220e7ded9988b16976f849c1", size = 35185476, upload-time = "2025-06-22T16:21:19.156Z" }, - { url = "https://files.pythonhosted.org/packages/ce/b3/21001cff985a122ba434c33f2c9d7d1dc3b669827e94f4fc4e1fe8b9dfd8/scipy-1.16.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4f720300a3024c237ace1cb11f9a84c38beb19616ba7c4cdcd771047a10a1706", size = 35570990, upload-time = "2025-06-22T16:21:27.797Z" }, - { url = "https://files.pythonhosted.org/packages/e5/d3/7ba42647d6709251cdf97043d0c107e0317e152fa2f76873b656b509ff55/scipy-1.16.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:aad603e9339ddb676409b104c48a027e9916ce0d2838830691f39552b38a352e", size = 37950262, upload-time = "2025-06-22T16:21:36.976Z" }, - { url = "https://files.pythonhosted.org/packages/eb/c4/231cac7a8385394ebbbb4f1ca662203e9d8c332825ab4f36ffc3ead09a42/scipy-1.16.0-cp313-cp313t-win_amd64.whl", hash = "sha256:f56296fefca67ba605fd74d12f7bd23636267731a72cb3947963e76b8c0a25db", size = 38515076, upload-time = "2025-06-22T16:21:45.694Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/f5/4a/b927028464795439faec8eaf0b03b011005c487bb2d07409f28bf30879c4/scipy-1.16.1.tar.gz", hash = "sha256:44c76f9e8b6e8e488a586190ab38016e4ed2f8a038af7cd3defa903c0a2238b3", size = 30580861, upload-time = "2025-07-27T16:33:30.834Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/91/812adc6f74409b461e3a5fa97f4f74c769016919203138a3bf6fc24ba4c5/scipy-1.16.1-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:c033fa32bab91dc98ca59d0cf23bb876454e2bb02cbe592d5023138778f70030", size = 36552519, upload-time = "2025-07-27T16:26:29.658Z" }, + { url = "https://files.pythonhosted.org/packages/47/18/8e355edcf3b71418d9e9f9acd2708cc3a6c27e8f98fde0ac34b8a0b45407/scipy-1.16.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:6e5c2f74e5df33479b5cd4e97a9104c511518fbd979aa9b8f6aec18b2e9ecae7", size = 28638010, upload-time = "2025-07-27T16:26:38.196Z" }, + { url = "https://files.pythonhosted.org/packages/d9/eb/e931853058607bdfbc11b86df19ae7a08686121c203483f62f1ecae5989c/scipy-1.16.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:0a55ffe0ba0f59666e90951971a884d1ff6f4ec3275a48f472cfb64175570f77", size = 20909790, upload-time = "2025-07-27T16:26:43.93Z" }, + { url = "https://files.pythonhosted.org/packages/45/0c/be83a271d6e96750cd0be2e000f35ff18880a46f05ce8b5d3465dc0f7a2a/scipy-1.16.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:f8a5d6cd147acecc2603fbd382fed6c46f474cccfcf69ea32582e033fb54dcfe", size = 23513352, upload-time = "2025-07-27T16:26:50.017Z" }, + { url = "https://files.pythonhosted.org/packages/7c/bf/fe6eb47e74f762f933cca962db7f2c7183acfdc4483bd1c3813cfe83e538/scipy-1.16.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cb18899127278058bcc09e7b9966d41a5a43740b5bb8dcba401bd983f82e885b", size = 33534643, upload-time = "2025-07-27T16:26:57.503Z" }, + { url = "https://files.pythonhosted.org/packages/bb/ba/63f402e74875486b87ec6506a4f93f6d8a0d94d10467280f3d9d7837ce3a/scipy-1.16.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:adccd93a2fa937a27aae826d33e3bfa5edf9aa672376a4852d23a7cd67a2e5b7", size = 35376776, upload-time = "2025-07-27T16:27:06.639Z" }, + { url = "https://files.pythonhosted.org/packages/c3/b4/04eb9d39ec26a1b939689102da23d505ea16cdae3dbb18ffc53d1f831044/scipy-1.16.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:18aca1646a29ee9a0625a1be5637fa798d4d81fdf426481f06d69af828f16958", size = 35698906, upload-time = "2025-07-27T16:27:14.943Z" }, + { url = "https://files.pythonhosted.org/packages/04/d6/bb5468da53321baeb001f6e4e0d9049eadd175a4a497709939128556e3ec/scipy-1.16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d85495cef541729a70cdddbbf3e6b903421bc1af3e8e3a9a72a06751f33b7c39", size = 38129275, upload-time = "2025-07-27T16:27:23.873Z" }, + { url = "https://files.pythonhosted.org/packages/c4/94/994369978509f227cba7dfb9e623254d0d5559506fe994aef4bea3ed469c/scipy-1.16.1-cp311-cp311-win_amd64.whl", hash = "sha256:226652fca853008119c03a8ce71ffe1b3f6d2844cc1686e8f9806edafae68596", size = 38644572, upload-time = "2025-07-27T16:27:32.637Z" }, + { url = "https://files.pythonhosted.org/packages/f8/d9/ec4864f5896232133f51382b54a08de91a9d1af7a76dfa372894026dfee2/scipy-1.16.1-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:81b433bbeaf35728dad619afc002db9b189e45eebe2cd676effe1fb93fef2b9c", size = 36575194, upload-time = "2025-07-27T16:27:41.321Z" }, + { url = "https://files.pythonhosted.org/packages/5c/6d/40e81ecfb688e9d25d34a847dca361982a6addf8e31f0957b1a54fbfa994/scipy-1.16.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:886cc81fdb4c6903a3bb0464047c25a6d1016fef77bb97949817d0c0d79f9e04", size = 28594590, upload-time = "2025-07-27T16:27:49.204Z" }, + { url = "https://files.pythonhosted.org/packages/0e/37/9f65178edfcc629377ce9a64fc09baebea18c80a9e57ae09a52edf84880b/scipy-1.16.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:15240c3aac087a522b4eaedb09f0ad061753c5eebf1ea430859e5bf8640d5919", size = 20866458, upload-time = "2025-07-27T16:27:54.98Z" }, + { url = "https://files.pythonhosted.org/packages/2c/7b/749a66766871ea4cb1d1ea10f27004db63023074c22abed51f22f09770e0/scipy-1.16.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:65f81a25805f3659b48126b5053d9e823d3215e4a63730b5e1671852a1705921", size = 23539318, upload-time = "2025-07-27T16:28:01.604Z" }, + { url = "https://files.pythonhosted.org/packages/c4/db/8d4afec60eb833a666434d4541a3151eedbf2494ea6d4d468cbe877f00cd/scipy-1.16.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6c62eea7f607f122069b9bad3f99489ddca1a5173bef8a0c75555d7488b6f725", size = 33292899, upload-time = "2025-07-27T16:28:09.147Z" }, + { url = "https://files.pythonhosted.org/packages/51/1e/79023ca3bbb13a015d7d2757ecca3b81293c663694c35d6541b4dca53e98/scipy-1.16.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f965bbf3235b01c776115ab18f092a95aa74c271a52577bcb0563e85738fd618", size = 35162637, upload-time = "2025-07-27T16:28:17.535Z" }, + { url = "https://files.pythonhosted.org/packages/b6/49/0648665f9c29fdaca4c679182eb972935b3b4f5ace41d323c32352f29816/scipy-1.16.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f006e323874ffd0b0b816d8c6a8e7f9a73d55ab3b8c3f72b752b226d0e3ac83d", size = 35490507, upload-time = "2025-07-27T16:28:25.705Z" }, + { url = "https://files.pythonhosted.org/packages/62/8f/66cbb9d6bbb18d8c658f774904f42a92078707a7c71e5347e8bf2f52bb89/scipy-1.16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e8fd15fc5085ab4cca74cb91fe0a4263b1f32e4420761ddae531ad60934c2119", size = 37923998, upload-time = "2025-07-27T16:28:34.339Z" }, + { url = "https://files.pythonhosted.org/packages/14/c3/61f273ae550fbf1667675701112e380881905e28448c080b23b5a181df7c/scipy-1.16.1-cp312-cp312-win_amd64.whl", hash = "sha256:f7b8013c6c066609577d910d1a2a077021727af07b6fab0ee22c2f901f22352a", size = 38508060, upload-time = "2025-07-27T16:28:43.242Z" }, + { url = "https://files.pythonhosted.org/packages/93/0b/b5c99382b839854a71ca9482c684e3472badc62620287cbbdab499b75ce6/scipy-1.16.1-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:5451606823a5e73dfa621a89948096c6528e2896e40b39248295d3a0138d594f", size = 36533717, upload-time = "2025-07-27T16:28:51.706Z" }, + { url = "https://files.pythonhosted.org/packages/eb/e5/69ab2771062c91e23e07c12e7d5033a6b9b80b0903ee709c3c36b3eb520c/scipy-1.16.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:89728678c5ca5abd610aee148c199ac1afb16e19844401ca97d43dc548a354eb", size = 28570009, upload-time = "2025-07-27T16:28:57.017Z" }, + { url = "https://files.pythonhosted.org/packages/f4/69/bd75dbfdd3cf524f4d753484d723594aed62cfaac510123e91a6686d520b/scipy-1.16.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e756d688cb03fd07de0fffad475649b03cb89bee696c98ce508b17c11a03f95c", size = 20841942, upload-time = "2025-07-27T16:29:01.152Z" }, + { url = "https://files.pythonhosted.org/packages/ea/74/add181c87663f178ba7d6144b370243a87af8476664d5435e57d599e6874/scipy-1.16.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5aa2687b9935da3ed89c5dbed5234576589dd28d0bf7cd237501ccfbdf1ad608", size = 23498507, upload-time = "2025-07-27T16:29:05.202Z" }, + { url = "https://files.pythonhosted.org/packages/1d/74/ece2e582a0d9550cee33e2e416cc96737dce423a994d12bbe59716f47ff1/scipy-1.16.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0851f6a1e537fe9399f35986897e395a1aa61c574b178c0d456be5b1a0f5ca1f", size = 33286040, upload-time = "2025-07-27T16:29:10.201Z" }, + { url = "https://files.pythonhosted.org/packages/e4/82/08e4076df538fb56caa1d489588d880ec7c52d8273a606bb54d660528f7c/scipy-1.16.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fedc2cbd1baed37474b1924c331b97bdff611d762c196fac1a9b71e67b813b1b", size = 35176096, upload-time = "2025-07-27T16:29:17.091Z" }, + { url = "https://files.pythonhosted.org/packages/fa/79/cd710aab8c921375711a8321c6be696e705a120e3011a643efbbcdeeabcc/scipy-1.16.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2ef500e72f9623a6735769e4b93e9dcb158d40752cdbb077f305487e3e2d1f45", size = 35490328, upload-time = "2025-07-27T16:29:22.928Z" }, + { url = "https://files.pythonhosted.org/packages/71/73/e9cc3d35ee4526d784520d4494a3e1ca969b071fb5ae5910c036a375ceec/scipy-1.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:978d8311674b05a8f7ff2ea6c6bce5d8b45a0cb09d4c5793e0318f448613ea65", size = 37939921, upload-time = "2025-07-27T16:29:29.108Z" }, + { url = "https://files.pythonhosted.org/packages/21/12/c0efd2941f01940119b5305c375ae5c0fcb7ec193f806bd8f158b73a1782/scipy-1.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:81929ed0fa7a5713fcdd8b2e6f73697d3b4c4816d090dd34ff937c20fa90e8ab", size = 38479462, upload-time = "2025-07-27T16:30:24.078Z" }, + { url = "https://files.pythonhosted.org/packages/7a/19/c3d08b675260046a991040e1ea5d65f91f40c7df1045fffff412dcfc6765/scipy-1.16.1-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:bcc12db731858abda693cecdb3bdc9e6d4bd200213f49d224fe22df82687bdd6", size = 36938832, upload-time = "2025-07-27T16:29:35.057Z" }, + { url = "https://files.pythonhosted.org/packages/81/f2/ce53db652c033a414a5b34598dba6b95f3d38153a2417c5a3883da429029/scipy-1.16.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:744d977daa4becb9fc59135e75c069f8d301a87d64f88f1e602a9ecf51e77b27", size = 29093084, upload-time = "2025-07-27T16:29:40.201Z" }, + { url = "https://files.pythonhosted.org/packages/a9/ae/7a10ff04a7dc15f9057d05b33737ade244e4bd195caa3f7cc04d77b9e214/scipy-1.16.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:dc54f76ac18073bcecffb98d93f03ed6b81a92ef91b5d3b135dcc81d55a724c7", size = 21365098, upload-time = "2025-07-27T16:29:44.295Z" }, + { url = "https://files.pythonhosted.org/packages/36/ac/029ff710959932ad3c2a98721b20b405f05f752f07344622fd61a47c5197/scipy-1.16.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:367d567ee9fc1e9e2047d31f39d9d6a7a04e0710c86e701e053f237d14a9b4f6", size = 23896858, upload-time = "2025-07-27T16:29:48.784Z" }, + { url = "https://files.pythonhosted.org/packages/71/13/d1ef77b6bd7898720e1f0b6b3743cb945f6c3cafa7718eaac8841035ab60/scipy-1.16.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4cf5785e44e19dcd32a0e4807555e1e9a9b8d475c6afff3d21c3c543a6aa84f4", size = 33438311, upload-time = "2025-07-27T16:29:54.164Z" }, + { url = "https://files.pythonhosted.org/packages/2d/e0/e64a6821ffbb00b4c5b05169f1c1fddb4800e9307efe3db3788995a82a2c/scipy-1.16.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3d0b80fb26d3e13a794c71d4b837e2a589d839fd574a6bbb4ee1288c213ad4a3", size = 35279542, upload-time = "2025-07-27T16:30:00.249Z" }, + { url = "https://files.pythonhosted.org/packages/57/59/0dc3c8b43e118f1e4ee2b798dcc96ac21bb20014e5f1f7a8e85cc0653bdb/scipy-1.16.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8503517c44c18d1030d666cb70aaac1cc8913608816e06742498833b128488b7", size = 35667665, upload-time = "2025-07-27T16:30:05.916Z" }, + { url = "https://files.pythonhosted.org/packages/45/5f/844ee26e34e2f3f9f8febb9343748e72daeaec64fe0c70e9bf1ff84ec955/scipy-1.16.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:30cc4bb81c41831ecfd6dc450baf48ffd80ef5aed0f5cf3ea775740e80f16ecc", size = 38045210, upload-time = "2025-07-27T16:30:11.655Z" }, + { url = "https://files.pythonhosted.org/packages/8d/d7/210f2b45290f444f1de64bc7353aa598ece9f0e90c384b4a156f9b1a5063/scipy-1.16.1-cp313-cp313t-win_amd64.whl", hash = "sha256:c24fa02f7ed23ae514460a22c57eca8f530dbfa50b1cfdbf4f37c05b5309cc39", size = 38593661, upload-time = "2025-07-27T16:30:17.825Z" }, + { url = "https://files.pythonhosted.org/packages/81/ea/84d481a5237ed223bd3d32d6e82d7a6a96e34756492666c260cef16011d1/scipy-1.16.1-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:796a5a9ad36fa3a782375db8f4241ab02a091308eb079746bc0f874c9b998318", size = 36525921, upload-time = "2025-07-27T16:30:30.081Z" }, + { url = "https://files.pythonhosted.org/packages/4e/9f/d9edbdeff9f3a664807ae3aea383e10afaa247e8e6255e6d2aa4515e8863/scipy-1.16.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:3ea0733a2ff73fd6fdc5fecca54ee9b459f4d74f00b99aced7d9a3adb43fb1cc", size = 28564152, upload-time = "2025-07-27T16:30:35.336Z" }, + { url = "https://files.pythonhosted.org/packages/3b/95/8125bcb1fe04bc267d103e76516243e8d5e11229e6b306bda1024a5423d1/scipy-1.16.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:85764fb15a2ad994e708258bb4ed8290d1305c62a4e1ef07c414356a24fcfbf8", size = 20836028, upload-time = "2025-07-27T16:30:39.421Z" }, + { url = "https://files.pythonhosted.org/packages/77/9c/bf92e215701fc70bbcd3d14d86337cf56a9b912a804b9c776a269524a9e9/scipy-1.16.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:ca66d980469cb623b1759bdd6e9fd97d4e33a9fad5b33771ced24d0cb24df67e", size = 23489666, upload-time = "2025-07-27T16:30:43.663Z" }, + { url = "https://files.pythonhosted.org/packages/5e/00/5e941d397d9adac41b02839011594620d54d99488d1be5be755c00cde9ee/scipy-1.16.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e7cc1ffcc230f568549fc56670bcf3df1884c30bd652c5da8138199c8c76dae0", size = 33358318, upload-time = "2025-07-27T16:30:48.982Z" }, + { url = "https://files.pythonhosted.org/packages/0e/87/8db3aa10dde6e3e8e7eb0133f24baa011377d543f5b19c71469cf2648026/scipy-1.16.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3ddfb1e8d0b540cb4ee9c53fc3dea3186f97711248fb94b4142a1b27178d8b4b", size = 35185724, upload-time = "2025-07-27T16:30:54.26Z" }, + { url = "https://files.pythonhosted.org/packages/89/b4/6ab9ae443216807622bcff02690262d8184078ea467efee2f8c93288a3b1/scipy-1.16.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4dc0e7be79e95d8ba3435d193e0d8ce372f47f774cffd882f88ea4e1e1ddc731", size = 35554335, upload-time = "2025-07-27T16:30:59.765Z" }, + { url = "https://files.pythonhosted.org/packages/9c/9a/d0e9dc03c5269a1afb60661118296a32ed5d2c24298af61b676c11e05e56/scipy-1.16.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f23634f9e5adb51b2a77766dac217063e764337fbc816aa8ad9aaebcd4397fd3", size = 37960310, upload-time = "2025-07-27T16:31:06.151Z" }, + { url = "https://files.pythonhosted.org/packages/5e/00/c8f3130a50521a7977874817ca89e0599b1b4ee8e938bad8ae798a0e1f0d/scipy-1.16.1-cp314-cp314-win_amd64.whl", hash = "sha256:57d75524cb1c5a374958a2eae3d84e1929bb971204cc9d52213fb8589183fc19", size = 39319239, upload-time = "2025-07-27T16:31:59.942Z" }, + { url = "https://files.pythonhosted.org/packages/f2/f2/1ca3eda54c3a7e4c92f6acef7db7b3a057deb135540d23aa6343ef8ad333/scipy-1.16.1-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:d8da7c3dd67bcd93f15618938f43ed0995982eb38973023d46d4646c4283ad65", size = 36939460, upload-time = "2025-07-27T16:31:11.865Z" }, + { url = "https://files.pythonhosted.org/packages/80/30/98c2840b293a132400c0940bb9e140171dcb8189588619048f42b2ce7b4f/scipy-1.16.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:cc1d2f2fd48ba1e0620554fe5bc44d3e8f5d4185c8c109c7fbdf5af2792cfad2", size = 29093322, upload-time = "2025-07-27T16:31:17.045Z" }, + { url = "https://files.pythonhosted.org/packages/c1/e6/1e6e006e850622cf2a039b62d1a6ddc4497d4851e58b68008526f04a9a00/scipy-1.16.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:21a611ced9275cb861bacadbada0b8c0623bc00b05b09eb97f23b370fc2ae56d", size = 21365329, upload-time = "2025-07-27T16:31:21.188Z" }, + { url = "https://files.pythonhosted.org/packages/8e/02/72a5aa5b820589dda9a25e329ca752842bfbbaf635e36bc7065a9b42216e/scipy-1.16.1-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:8dfbb25dffc4c3dd9371d8ab456ca81beeaf6f9e1c2119f179392f0dc1ab7695", size = 23897544, upload-time = "2025-07-27T16:31:25.408Z" }, + { url = "https://files.pythonhosted.org/packages/2b/dc/7122d806a6f9eb8a33532982234bed91f90272e990f414f2830cfe656e0b/scipy-1.16.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f0ebb7204f063fad87fc0a0e4ff4a2ff40b2a226e4ba1b7e34bf4b79bf97cd86", size = 33442112, upload-time = "2025-07-27T16:31:30.62Z" }, + { url = "https://files.pythonhosted.org/packages/24/39/e383af23564daa1021a5b3afbe0d8d6a68ec639b943661841f44ac92de85/scipy-1.16.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f1b9e5962656f2734c2b285a8745358ecb4e4efbadd00208c80a389227ec61ff", size = 35286594, upload-time = "2025-07-27T16:31:36.112Z" }, + { url = "https://files.pythonhosted.org/packages/95/47/1a0b0aff40c3056d955f38b0df5d178350c3d74734ec54f9c68d23910be5/scipy-1.16.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e1a106f8c023d57a2a903e771228bf5c5b27b5d692088f457acacd3b54511e4", size = 35665080, upload-time = "2025-07-27T16:31:42.025Z" }, + { url = "https://files.pythonhosted.org/packages/64/df/ce88803e9ed6e27fe9b9abefa157cf2c80e4fa527cf17ee14be41f790ad4/scipy-1.16.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:709559a1db68a9abc3b2c8672c4badf1614f3b440b3ab326d86a5c0491eafae3", size = 38050306, upload-time = "2025-07-27T16:31:48.109Z" }, + { url = "https://files.pythonhosted.org/packages/6e/6c/a76329897a7cae4937d403e623aa6aaea616a0bb5b36588f0b9d1c9a3739/scipy-1.16.1-cp314-cp314t-win_amd64.whl", hash = "sha256:c0c804d60492a0aad7f5b2bb1862f4548b990049e27e828391ff2bf6f7199998", size = 39427705, upload-time = "2025-07-27T16:31:53.96Z" }, ] [[package]] From 0ee161e96bc3908e1f784e85023fd77fa6b9d984 Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Tue, 12 Aug 2025 08:43:01 +0200 Subject: [PATCH 03/26] Increase test tolerance to pass the test on MacOS --- tests/unit/events/test_local_event_manager.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/unit/events/test_local_event_manager.py b/tests/unit/events/test_local_event_manager.py index 481c7da16b..5fe7c76540 100644 --- a/tests/unit/events/test_local_event_manager.py +++ b/tests/unit/events/test_local_event_manager.py @@ -2,7 +2,6 @@ import asyncio from datetime import timedelta -from functools import update_wrapper from typing import Any from unittest.mock import AsyncMock @@ -17,15 +16,15 @@ def listener() -> AsyncMock: async def async_listener(payload: Any) -> None: pass - al = AsyncMock() - update_wrapper(al, async_listener) - return al + return AsyncMock(target=async_listener) async def test_emit_system_info_event(listener: AsyncMock) -> None: - async with LocalEventManager(system_info_interval=timedelta(milliseconds=50)) as event_manager: + system_info_interval = timedelta(milliseconds=50) + test_tolerance_coefficient = 10 + async with LocalEventManager(system_info_interval=system_info_interval) as event_manager: event_manager.on(event=Event.SYSTEM_INFO, listener=listener) - await asyncio.sleep(0.2) + await asyncio.sleep(system_info_interval.total_seconds() * test_tolerance_coefficient) assert listener.call_count >= 1 assert isinstance(listener.call_args[0][0], EventSystemInfoData) From 3bec9bb8ffdbe6b31992a1b0d12a10c60721a28c Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Wed, 3 Dec 2025 16:12:01 +0100 Subject: [PATCH 04/26] Revert changes to see status of the tests on MacOS --- tests/unit/events/test_local_event_manager.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/unit/events/test_local_event_manager.py b/tests/unit/events/test_local_event_manager.py index 5fe7c76540..481c7da16b 100644 --- a/tests/unit/events/test_local_event_manager.py +++ b/tests/unit/events/test_local_event_manager.py @@ -2,6 +2,7 @@ import asyncio from datetime import timedelta +from functools import update_wrapper from typing import Any from unittest.mock import AsyncMock @@ -16,15 +17,15 @@ def listener() -> AsyncMock: async def async_listener(payload: Any) -> None: pass - return AsyncMock(target=async_listener) + al = AsyncMock() + update_wrapper(al, async_listener) + return al async def test_emit_system_info_event(listener: AsyncMock) -> None: - system_info_interval = timedelta(milliseconds=50) - test_tolerance_coefficient = 10 - async with LocalEventManager(system_info_interval=system_info_interval) as event_manager: + async with LocalEventManager(system_info_interval=timedelta(milliseconds=50)) as event_manager: event_manager.on(event=Event.SYSTEM_INFO, listener=listener) - await asyncio.sleep(system_info_interval.total_seconds() * test_tolerance_coefficient) + await asyncio.sleep(0.2) assert listener.call_count >= 1 assert isinstance(listener.call_args[0][0], EventSystemInfoData) From 3730920506bfc50f7a3dbd60eac127a5515bc8cc Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Thu, 4 Dec 2025 13:55:57 +0100 Subject: [PATCH 05/26] Add many debug logs for flaky test `test_timeout_in_handler` --- src/crawlee/crawlers/_basic/_basic_crawler.py | 13 +++++++++++-- src/crawlee/statistics/_error_tracker.py | 4 ++++ tests/unit/crawlers/_basic/test_basic_crawler.py | 7 ++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/crawlee/crawlers/_basic/_basic_crawler.py b/src/crawlee/crawlers/_basic/_basic_crawler.py index 79027aeba0..b385735c52 100644 --- a/src/crawlee/crawlers/_basic/_basic_crawler.py +++ b/src/crawlee/crawlers/_basic/_basic_crawler.py @@ -1130,6 +1130,7 @@ async def _handle_request_retries( await self._statistics.error_tracker.add(error=error, context=context) if self._error_handler: + self.log.warning('Error handler') try: new_request = await self._error_handler(context, error) except Exception as e: @@ -1137,9 +1138,10 @@ async def _handle_request_retries( else: if new_request is not None: request = new_request - + self.log.warning('reclaim_request') await request_manager.reclaim_request(request) else: + self.log.warning('mark_request_as_handled') await wait_for( lambda: request_manager.mark_request_as_handled(context.request), timeout=self._internal_timeout, @@ -1148,13 +1150,15 @@ async def _handle_request_retries( logger=self._logger, max_retries=3, ) + self.log.warning('_handle_failed_request') await self._handle_failed_request(context, error) self._statistics.record_request_processing_failure(request.unique_key) + self.log.warning('_handle_request_retries DONE') async def _handle_request_error(self, context: TCrawlingContext | BasicCrawlingContext, error: Exception) -> None: try: context.request.state = RequestState.ERROR_HANDLER - + self.log.warning('Before _handle_request_error') await wait_for( partial(self._handle_request_retries, context, error), timeout=self._internal_timeout, @@ -1162,6 +1166,7 @@ async def _handle_request_error(self, context: TCrawlingContext | BasicCrawlingC f'{self._internal_timeout.total_seconds()} seconds', logger=self._logger, ) + self.log.warning('After _handle_request_error') context.request.state = RequestState.DONE except UserDefinedErrorHandlerError: @@ -1414,9 +1419,12 @@ async def __run_task_function(self) -> None: try: await self._run_request_handler(context=context) except asyncio.TimeoutError as e: + context.log.info('RH error') raise RequestHandlerError(e, context) from e + context.log.info('Commit resutls') await self._commit_request_handler_result(context) + context.log.info('Marking as handled request') await wait_for( lambda: request_manager.mark_request_as_handled(context.request), timeout=self._internal_timeout, @@ -1431,6 +1439,7 @@ async def __run_task_function(self) -> None: if context.session and context.session.is_usable: context.session.mark_good() + context.log.info('Finished processing request') self._statistics.record_request_processing_finish(request.unique_key) except RequestCollisionError as request_error: diff --git a/src/crawlee/statistics/_error_tracker.py b/src/crawlee/statistics/_error_tracker.py index 5d184eabde..1e5d816da8 100644 --- a/src/crawlee/statistics/_error_tracker.py +++ b/src/crawlee/statistics/_error_tracker.py @@ -58,6 +58,7 @@ async def add( early: Flag indicating that the error is added earlier than usual to have access to resources that will be closed before normal error collection. This prevents double reporting during normal error collection. """ + logger.warning('Adding error') if id(error) in self._early_reported_errors: # Error had to be collected earlier before relevant resources are closed. self._early_reported_errors.remove(id(error)) @@ -98,12 +99,15 @@ async def add( == 1 and context is not None ): + logger.warning('awaiting snapshot') # Save snapshot only on the first occurrence of the error and only if context and kvs was passed as well. await self._capture_error_snapshot( error_message=new_error_group_message or error_group_message, file_and_line=error_group_file_and_line, context=context, ) + logger.warning('Snapshot added') + logger.warning('Finished') async def _capture_error_snapshot( self, error_message: str, file_and_line: str, context: BasicCrawlingContext diff --git a/tests/unit/crawlers/_basic/test_basic_crawler.py b/tests/unit/crawlers/_basic/test_basic_crawler.py index c711d0c9d2..539b969cb2 100644 --- a/tests/unit/crawlers/_basic/test_basic_crawler.py +++ b/tests/unit/crawlers/_basic/test_basic_crawler.py @@ -1295,7 +1295,11 @@ async def test_timeout_in_handler(sleep_type: str) -> None: double_handler_timeout_s = handler_timeout.total_seconds() * 2 handler_sleep = iter([double_handler_timeout_s, double_handler_timeout_s, 0]) - crawler = BasicCrawler(request_handler_timeout=handler_timeout, max_request_retries=max_request_retries) + crawler = BasicCrawler( + request_handler_timeout=handler_timeout, + max_request_retries=max_request_retries, + ) + crawler.log.setLevel(logging.DEBUG) mocked_handler_before_sleep = Mock() mocked_handler_after_sleep = Mock() @@ -1311,6 +1315,7 @@ async def handler(context: BasicCrawlingContext) -> None: # This will not execute if timeout happens. mocked_handler_after_sleep() + context.log.info('Handling request') # Timeout in pytest, because previous implementation would run crawler until following: # "The request queue seems to be stuck for 300.0s, resetting internal state." From 0e6d87c5acac867ae1f2f22be0b61d5044a9b01f Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Thu, 4 Dec 2025 14:20:07 +0100 Subject: [PATCH 06/26] Add even more debug. Probably another bug in RQ --- .../_file_system/_request_queue_client.py | 14 ++++++++++++++ tests/unit/crawlers/_basic/test_basic_crawler.py | 1 + 2 files changed, 15 insertions(+) diff --git a/src/crawlee/storage_clients/_file_system/_request_queue_client.py b/src/crawlee/storage_clients/_file_system/_request_queue_client.py index e49771b7c9..76ab51bf84 100644 --- a/src/crawlee/storage_clients/_file_system/_request_queue_client.py +++ b/src/crawlee/storage_clients/_file_system/_request_queue_client.py @@ -546,12 +546,14 @@ async def reclaim_request( # Update sequence number and state to ensure proper ordering. if forefront: + logger.info('Reclaiming forefront request') # Remove from regular requests if it was there state.regular_requests.pop(request.unique_key, None) sequence_number = state.forefront_sequence_counter state.forefront_sequence_counter += 1 state.forefront_requests[request.unique_key] = sequence_number else: + logger.info('Reclaiming regular request') # Remove from forefront requests if it was there state.forefront_requests.pop(request.unique_key, None) sequence_number = state.sequence_counter @@ -559,23 +561,30 @@ async def reclaim_request( state.regular_requests[request.unique_key] = sequence_number # Save the clean request without extra fields + request_data = await json_dumps(request.model_dump()) + logger.info('Atomic write') await atomic_write(request_path, request_data) # Remove from in-progress. + logger.info('Remove from in-progress') state.in_progress_requests.discard(request.unique_key) + logger.info('Update RQ metadata.') # Update RQ metadata. await self._update_metadata( update_modified_at=True, update_accessed_at=True, ) + logger.info('Updated RQ metadata.') # Add the request back to the cache. if forefront: self._request_cache.appendleft(request) + logger.info(f'Add the request back to the cache: forefront. {self._request_cache}') else: self._request_cache.append(request) + logger.info(f'Add the request back to the cache: normal. . {self._request_cache}') return ProcessedRequest( unique_key=request.unique_key, @@ -595,6 +604,7 @@ async def is_empty(self) -> bool: # If there are in-progress requests, return False immediately. if len(state.in_progress_requests) > 0: self._is_empty_cache = False + logger.info(f'{state.in_progress_requests=}') return False # If we have a cached requests, check them first (fast path). @@ -602,8 +612,10 @@ async def is_empty(self) -> bool: for req in self._request_cache: if req.unique_key not in state.handled_requests: self._is_empty_cache = False + logger.info(f'{(req.unique_key not in state.handled_requests)=}') return False self._is_empty_cache = True + logger.info(f'{(len(state.in_progress_requests) == 0)=}') return len(state.in_progress_requests) == 0 # Fallback: check state for unhandled requests. @@ -615,9 +627,11 @@ async def is_empty(self) -> bool: if unhandled_requests: self._is_empty_cache = False + logger.info(f'{unhandled_requests=}') return False self._is_empty_cache = True + logger.info('Last resort is empty') return True def _get_request_path(self, unique_key: str) -> Path: diff --git a/tests/unit/crawlers/_basic/test_basic_crawler.py b/tests/unit/crawlers/_basic/test_basic_crawler.py index 539b969cb2..a201a2d295 100644 --- a/tests/unit/crawlers/_basic/test_basic_crawler.py +++ b/tests/unit/crawlers/_basic/test_basic_crawler.py @@ -1300,6 +1300,7 @@ async def test_timeout_in_handler(sleep_type: str) -> None: max_request_retries=max_request_retries, ) crawler.log.setLevel(logging.DEBUG) + logging.getLogger('crawlee.storage_clients._file_system._request_queue_client').setLevel(logging.DEBUG) mocked_handler_before_sleep = Mock() mocked_handler_after_sleep = Mock() From 55eb4cb650d39f3e3334e8198da102c7929b9cba Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Thu, 4 Dec 2025 14:43:45 +0100 Subject: [PATCH 07/26] Add more debug to RQ state --- src/crawlee/crawlers/_basic/_basic_crawler.py | 6 +++++- .../storage_clients/_file_system/_request_queue_client.py | 1 - 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/crawlee/crawlers/_basic/_basic_crawler.py b/src/crawlee/crawlers/_basic/_basic_crawler.py index b385735c52..1dd3fc8da4 100644 --- a/src/crawlee/crawlers/_basic/_basic_crawler.py +++ b/src/crawlee/crawlers/_basic/_basic_crawler.py @@ -1353,7 +1353,11 @@ async def __is_finished_function(self) -> bool: return False request_manager = await self.get_request_manager() - return await request_manager.is_finished() + is_finished = await request_manager.is_finished() + if is_finished: + self.log.info('I am sure this is a lie!!!') + self.log.info(self._request_manager._client._state._state) + return is_finished async def __is_task_ready_function(self) -> bool: self._stop_if_max_requests_count_exceeded() diff --git a/src/crawlee/storage_clients/_file_system/_request_queue_client.py b/src/crawlee/storage_clients/_file_system/_request_queue_client.py index 76ab51bf84..4277d0ac26 100644 --- a/src/crawlee/storage_clients/_file_system/_request_queue_client.py +++ b/src/crawlee/storage_clients/_file_system/_request_queue_client.py @@ -57,7 +57,6 @@ class RequestQueueState(BaseModel): handled_requests: set[str] = set() """Set of request unique keys that have been handled.""" - class FileSystemRequestQueueClient(RequestQueueClient): """A file system implementation of the request queue client. From 72f8451e68f8871dc40a690751e39604290a2eb5 Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Thu, 4 Dec 2025 14:55:06 +0100 Subject: [PATCH 08/26] Add debug to autoscaled pool. Is the problem there? --- src/crawlee/_autoscaling/autoscaled_pool.py | 12 +++++++----- src/crawlee/crawlers/_basic/_basic_crawler.py | 1 + tests/unit/crawlers/_basic/test_basic_crawler.py | 2 ++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/crawlee/_autoscaling/autoscaled_pool.py b/src/crawlee/_autoscaling/autoscaled_pool.py index 89f7c89312..5e062bacc2 100644 --- a/src/crawlee/_autoscaling/autoscaled_pool.py +++ b/src/crawlee/_autoscaling/autoscaled_pool.py @@ -124,7 +124,9 @@ async def run(self) -> None: try: await run.result + logger.info('Finished naturally') except AbortError: + logger.info('AbortError') orchestrator.cancel() for task in run.worker_tasks: if not task.done(): @@ -245,16 +247,16 @@ async def _worker_task_orchestrator(self, run: _AutoscaledPoolRun) -> None: await asyncio.wait_for(run.worker_tasks_updated.wait(), timeout=0.5) finally: if finished: - logger.debug('`is_finished_function` reports that we are finished') + logger.info('`is_finished_function` reports that we are finished') elif run.result.done() and run.result.exception() is not None: - logger.debug('Unhandled exception in `run_task_function`') + logger.info('Unhandled exception in `run_task_function`') if run.worker_tasks: - logger.debug('Terminating - waiting for tasks to complete') + logger.info('Terminating - waiting for tasks to complete') await asyncio.wait(run.worker_tasks, return_when=asyncio.ALL_COMPLETED) - logger.debug('Worker tasks finished') + logger.info('Worker tasks finished') else: - logger.debug('Terminating - no running tasks to wait for') + logger.info('Terminating - no running tasks to wait for') if not run.result.done(): run.result.set_result(object()) diff --git a/src/crawlee/crawlers/_basic/_basic_crawler.py b/src/crawlee/crawlers/_basic/_basic_crawler.py index 1dd3fc8da4..b2283b046f 100644 --- a/src/crawlee/crawlers/_basic/_basic_crawler.py +++ b/src/crawlee/crawlers/_basic/_basic_crawler.py @@ -1347,6 +1347,7 @@ async def __is_finished_function(self) -> bool: if self._abort_on_error and self._failed: self._failed = False + self.log.info('_abort_on_error') return True if self._keep_alive: diff --git a/tests/unit/crawlers/_basic/test_basic_crawler.py b/tests/unit/crawlers/_basic/test_basic_crawler.py index a201a2d295..1e9d274a01 100644 --- a/tests/unit/crawlers/_basic/test_basic_crawler.py +++ b/tests/unit/crawlers/_basic/test_basic_crawler.py @@ -1301,6 +1301,8 @@ async def test_timeout_in_handler(sleep_type: str) -> None: ) crawler.log.setLevel(logging.DEBUG) logging.getLogger('crawlee.storage_clients._file_system._request_queue_client').setLevel(logging.DEBUG) + logging.getLogger('crawlee._autoscaling.autoscaled_pool').setLevel(logging.INFO) + mocked_handler_before_sleep = Mock() mocked_handler_after_sleep = Mock() From 77716581569990db151a690f3769ea2a2fefe04b Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Thu, 4 Dec 2025 15:02:15 +0100 Subject: [PATCH 09/26] Some unimaginable execption is raised in autoscaled pool. What is it? Add debug --- src/crawlee/_autoscaling/autoscaled_pool.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/crawlee/_autoscaling/autoscaled_pool.py b/src/crawlee/_autoscaling/autoscaled_pool.py index 5e062bacc2..c4ca50098c 100644 --- a/src/crawlee/_autoscaling/autoscaled_pool.py +++ b/src/crawlee/_autoscaling/autoscaled_pool.py @@ -131,6 +131,10 @@ async def run(self) -> None: for task in run.worker_tasks: if not task.done(): task.cancel() + except Exception as exc: + logger.error('Something sinister happened', exc_info=exc) + raise + finally: with suppress(asyncio.CancelledError): await self._autoscale_task.stop() @@ -218,7 +222,7 @@ async def _worker_task_orchestrator(self, run: _AutoscaledPoolRun) -> None: Exits when `is_finished_function` returns True. """ finished = False - + logger.info('_worker_task_orchestrator') try: while not (finished := await self._is_finished_function()) and not run.result.done(): run.worker_tasks_updated.clear() @@ -246,6 +250,7 @@ async def _worker_task_orchestrator(self, run: _AutoscaledPoolRun) -> None: with suppress(asyncio.TimeoutError): await asyncio.wait_for(run.worker_tasks_updated.wait(), timeout=0.5) finally: + logger.info('Finally pool') if finished: logger.info('`is_finished_function` reports that we are finished') elif run.result.done() and run.result.exception() is not None: From 159198425c317d6595bfc7fd28a2d041346f8d4d Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Thu, 4 Dec 2025 15:14:27 +0100 Subject: [PATCH 10/26] Focus only onthe single flaky test --- Makefile | 2 +- src/crawlee/crawlers/_basic/_basic_crawler.py | 1 - tests/unit/crawlers/_basic/test_basic_crawler.py | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 6ca17970b0..a16ff5c578 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ type-check: unit-tests: uv run pytest --numprocesses=1 -vv tests/unit -m "run_alone" - uv run pytest --numprocesses=auto -vv tests/unit -m "not run_alone" + #uv run pytest --numprocesses=auto -vv tests/unit -m "not run_alone" unit-tests-cov: uv run pytest --numprocesses=1 -vv --cov=src/crawlee tests/unit -m "run_alone" diff --git a/src/crawlee/crawlers/_basic/_basic_crawler.py b/src/crawlee/crawlers/_basic/_basic_crawler.py index b2283b046f..c66b1b4d0f 100644 --- a/src/crawlee/crawlers/_basic/_basic_crawler.py +++ b/src/crawlee/crawlers/_basic/_basic_crawler.py @@ -1357,7 +1357,6 @@ async def __is_finished_function(self) -> bool: is_finished = await request_manager.is_finished() if is_finished: self.log.info('I am sure this is a lie!!!') - self.log.info(self._request_manager._client._state._state) return is_finished async def __is_task_ready_function(self) -> bool: diff --git a/tests/unit/crawlers/_basic/test_basic_crawler.py b/tests/unit/crawlers/_basic/test_basic_crawler.py index 1e9d274a01..e34f8f6cdf 100644 --- a/tests/unit/crawlers/_basic/test_basic_crawler.py +++ b/tests/unit/crawlers/_basic/test_basic_crawler.py @@ -1271,7 +1271,7 @@ async def handler(context: BasicCrawlingContext) -> None: await store.persist_autosaved_values() assert (await store.get_value(BasicCrawler._CRAWLEE_STATE_KEY))['counter'] == 2 - +@pytest.mark.parametrize("_", range(10)) @pytest.mark.run_alone @pytest.mark.skipif(sys.version_info[:3] < (3, 11), reason='asyncio.timeout was introduced in Python 3.11.') @pytest.mark.parametrize( @@ -1281,7 +1281,7 @@ async def handler(context: BasicCrawlingContext) -> None: pytest.param('sync_sleep', marks=pytest.mark.skip(reason='https://github.com/apify/crawlee-python/issues/908')), ], ) -async def test_timeout_in_handler(sleep_type: str) -> None: +async def test_timeout_in_handler(sleep_type: str, _) -> None: """Test that timeout from request handler is treated the same way as exception thrown in request handler. Handler should be able to time out even if the code causing the timeout is blocking sync code. From 13325d7bc68f622b0351384db19b6fa1f071ec0d Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Thu, 4 Dec 2025 15:27:55 +0100 Subject: [PATCH 11/26] Even more logs --- src/crawlee/_autoscaling/autoscaled_pool.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crawlee/_autoscaling/autoscaled_pool.py b/src/crawlee/_autoscaling/autoscaled_pool.py index c4ca50098c..1965e3ab25 100644 --- a/src/crawlee/_autoscaling/autoscaled_pool.py +++ b/src/crawlee/_autoscaling/autoscaled_pool.py @@ -250,7 +250,7 @@ async def _worker_task_orchestrator(self, run: _AutoscaledPoolRun) -> None: with suppress(asyncio.TimeoutError): await asyncio.wait_for(run.worker_tasks_updated.wait(), timeout=0.5) finally: - logger.info('Finally pool') + logger.info(f'Finally pool. {finished=}, {(run.result.done())=}') if finished: logger.info('`is_finished_function` reports that we are finished') elif run.result.done() and run.result.exception() is not None: From 8d79ada13c1746b6ee790525241266d05b9e5920 Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Thu, 4 Dec 2025 15:41:08 +0100 Subject: [PATCH 12/26] Who is setting the result? --- src/crawlee/_autoscaling/autoscaled_pool.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/crawlee/_autoscaling/autoscaled_pool.py b/src/crawlee/_autoscaling/autoscaled_pool.py index 1965e3ab25..20e58bf4d9 100644 --- a/src/crawlee/_autoscaling/autoscaled_pool.py +++ b/src/crawlee/_autoscaling/autoscaled_pool.py @@ -124,7 +124,7 @@ async def run(self) -> None: try: await run.result - logger.info('Finished naturally') + logger.info(f'Finished naturally, {run.worker_tasks=}, {run.result.result()=}') except AbortError: logger.info('AbortError') orchestrator.cancel() @@ -249,6 +249,13 @@ async def _worker_task_orchestrator(self, run: _AutoscaledPoolRun) -> None: with suppress(asyncio.TimeoutError): await asyncio.wait_for(run.worker_tasks_updated.wait(), timeout=0.5) + + logger.info("Just finishing") + + except Exception as e: + logger.error('What is hiding here?', exc_info=e) + raise + finally: logger.info(f'Finally pool. {finished=}, {(run.result.done())=}') if finished: @@ -264,7 +271,7 @@ async def _worker_task_orchestrator(self, run: _AutoscaledPoolRun) -> None: logger.info('Terminating - no running tasks to wait for') if not run.result.done(): - run.result.set_result(object()) + run.result.set_result("Hello") def _reap_worker_task(self, task: asyncio.Task, run: _AutoscaledPoolRun) -> None: """Handle cleanup and tracking of a completed worker task. From be6294e3865555df60c3c8221a86f9f9a5d9cbd9 Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Thu, 4 Dec 2025 15:52:23 +0100 Subject: [PATCH 13/26] Even more logs --- src/crawlee/_autoscaling/autoscaled_pool.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/crawlee/_autoscaling/autoscaled_pool.py b/src/crawlee/_autoscaling/autoscaled_pool.py index 20e58bf4d9..76960c2e04 100644 --- a/src/crawlee/_autoscaling/autoscaled_pool.py +++ b/src/crawlee/_autoscaling/autoscaled_pool.py @@ -136,12 +136,16 @@ async def run(self) -> None: raise finally: + logger.error('finally') with suppress(asyncio.CancelledError): + logger.error('self._autoscale_task.stop()') await self._autoscale_task.stop() with suppress(asyncio.CancelledError): + logger.error('await self._log_system_status_task.stop()') await self._log_system_status_task.stop() if not orchestrator.done(): + logger.error('not orchestrator.done()') orchestrator.cancel() elif not orchestrator.cancelled() and orchestrator.exception() is not None: logger.error('Exception in worker task orchestrator', exc_info=orchestrator.exception()) @@ -257,7 +261,7 @@ async def _worker_task_orchestrator(self, run: _AutoscaledPoolRun) -> None: raise finally: - logger.info(f'Finally pool. {finished=}, {(run.result.done())=}') + logger.info(f'Finally pool. {finished=}, {(run.result.done())=}, {(run.result.result() if run.result.done() else None)=}') if finished: logger.info('`is_finished_function` reports that we are finished') elif run.result.done() and run.result.exception() is not None: From 1a71ab73cb63dcb044f3970ac2e2f8f8dfb0bda8 Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Thu, 4 Dec 2025 15:57:33 +0100 Subject: [PATCH 14/26] Is it `BaseException` ? --- src/crawlee/_autoscaling/autoscaled_pool.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/crawlee/_autoscaling/autoscaled_pool.py b/src/crawlee/_autoscaling/autoscaled_pool.py index 76960c2e04..1a83cb89c9 100644 --- a/src/crawlee/_autoscaling/autoscaled_pool.py +++ b/src/crawlee/_autoscaling/autoscaled_pool.py @@ -123,6 +123,7 @@ async def run(self) -> None: ) try: + logger.info(f'Await result') await run.result logger.info(f'Finished naturally, {run.worker_tasks=}, {run.result.result()=}') except AbortError: @@ -134,6 +135,9 @@ async def run(self) -> None: except Exception as exc: logger.error('Something sinister happened', exc_info=exc) raise + except BaseException as exc: + logger.error('BaseException happened', exc_info=exc) + raise finally: logger.error('finally') From 353e82151d80ea6b582268a821fb01d4904a075f Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Thu, 4 Dec 2025 16:06:33 +0100 Subject: [PATCH 15/26] Add test tolerance. It is pytest stoping the test due to MacOS being too slow... --- tests/unit/crawlers/_basic/test_basic_crawler.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/unit/crawlers/_basic/test_basic_crawler.py b/tests/unit/crawlers/_basic/test_basic_crawler.py index e34f8f6cdf..8ec7a347ea 100644 --- a/tests/unit/crawlers/_basic/test_basic_crawler.py +++ b/tests/unit/crawlers/_basic/test_basic_crawler.py @@ -1294,6 +1294,7 @@ async def test_timeout_in_handler(sleep_type: str, _) -> None: max_request_retries = 3 double_handler_timeout_s = handler_timeout.total_seconds() * 2 handler_sleep = iter([double_handler_timeout_s, double_handler_timeout_s, 0]) + CI_test_tolerance = 5 # MacOS CI has been slow in exceptional cases crawler = BasicCrawler( request_handler_timeout=handler_timeout, @@ -1322,7 +1323,7 @@ async def handler(context: BasicCrawlingContext) -> None: # Timeout in pytest, because previous implementation would run crawler until following: # "The request queue seems to be stuck for 300.0s, resetting internal state." - async with timeout(max_request_retries * double_handler_timeout_s): + async with timeout(max_request_retries * double_handler_timeout_s + CI_test_tolerance): await crawler.run(['https://a.placeholder.com']) assert crawler.statistics.state.requests_finished == 1 From 02246f5f3997e43370e3e736948c921a1ae71980 Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Thu, 4 Dec 2025 16:14:52 +0100 Subject: [PATCH 16/26] Pool deadlocked until timeout? --- src/crawlee/_autoscaling/autoscaled_pool.py | 9 +++++---- src/crawlee/crawlers/_basic/_basic_crawler.py | 5 ++++- tests/unit/events/test_local_event_manager.py | 10 +++++----- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/crawlee/_autoscaling/autoscaled_pool.py b/src/crawlee/_autoscaling/autoscaled_pool.py index 1a83cb89c9..6fee395f77 100644 --- a/src/crawlee/_autoscaling/autoscaled_pool.py +++ b/src/crawlee/_autoscaling/autoscaled_pool.py @@ -237,20 +237,21 @@ async def _worker_task_orchestrator(self, run: _AutoscaledPoolRun) -> None: current_status = self._system_status.get_current_system_info() if not current_status.is_system_idle: - logger.debug('Not scheduling new tasks - system is overloaded') + logger.info('Not scheduling new tasks - system is overloaded') elif self._is_paused: - logger.debug('Not scheduling new tasks - the autoscaled pool is paused') + logger.info('Not scheduling new tasks - the autoscaled pool is paused') elif self.current_concurrency >= self.desired_concurrency: - logger.debug('Not scheduling new tasks - already running at desired concurrency') + logger.info('Not scheduling new tasks - already running at desired concurrency') elif not await self._is_task_ready_function(): logger.debug('Not scheduling new task - no task is ready') else: - logger.debug('Scheduling a new task') + logger.info('Scheduling a new task') worker_task = asyncio.create_task(self._worker_task(), name='autoscaled pool worker task') worker_task.add_done_callback(lambda task: self._reap_worker_task(task, run)) run.worker_tasks.append(worker_task) if math.isfinite(self._max_tasks_per_minute): + logger.info('Deadlock sleep????') await asyncio.sleep(60 / self._max_tasks_per_minute) continue diff --git a/src/crawlee/crawlers/_basic/_basic_crawler.py b/src/crawlee/crawlers/_basic/_basic_crawler.py index c66b1b4d0f..dd5f6ec41c 100644 --- a/src/crawlee/crawlers/_basic/_basic_crawler.py +++ b/src/crawlee/crawlers/_basic/_basic_crawler.py @@ -1369,7 +1369,10 @@ async def __is_task_ready_function(self) -> bool: return False request_manager = await self.get_request_manager() - return not await request_manager.is_empty() + is_ready = not await request_manager.is_empty() + if is_ready: + self.log.info('There is a request to process') + return is_ready async def __run_task_function(self) -> None: request_manager = await self.get_request_manager() diff --git a/tests/unit/events/test_local_event_manager.py b/tests/unit/events/test_local_event_manager.py index 481c7da16b..e60de9a5dc 100644 --- a/tests/unit/events/test_local_event_manager.py +++ b/tests/unit/events/test_local_event_manager.py @@ -17,15 +17,15 @@ def listener() -> AsyncMock: async def async_listener(payload: Any) -> None: pass - al = AsyncMock() - update_wrapper(al, async_listener) - return al + return AsyncMock(target=async_listener) async def test_emit_system_info_event(listener: AsyncMock) -> None: - async with LocalEventManager(system_info_interval=timedelta(milliseconds=50)) as event_manager: + system_info_interval = timedelta(milliseconds=50) + test_tolerance_coefficient = 10 + async with LocalEventManager(system_info_interval=system_info_interval) as event_manager: event_manager.on(event=Event.SYSTEM_INFO, listener=listener) - await asyncio.sleep(0.2) + await asyncio.sleep(system_info_interval.total_seconds() * test_tolerance_coefficient) assert listener.call_count >= 1 assert isinstance(listener.call_args[0][0], EventSystemInfoData) From 3befc3ea58662f08b4646913a47f051f7d9f7327 Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Thu, 4 Dec 2025 16:19:29 +0100 Subject: [PATCH 17/26] Seems like the pool is self-exhausting all the resources? Is it due to _worker_task_orchestrator loop being too intensive? --- src/crawlee/_autoscaling/autoscaled_pool.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crawlee/_autoscaling/autoscaled_pool.py b/src/crawlee/_autoscaling/autoscaled_pool.py index 6fee395f77..15d0ac606b 100644 --- a/src/crawlee/_autoscaling/autoscaled_pool.py +++ b/src/crawlee/_autoscaling/autoscaled_pool.py @@ -46,7 +46,7 @@ class AutoscaledPool: _AUTOSCALE_INTERVAL = timedelta(seconds=10) """Interval at which the autoscaled pool adjusts the desired concurrency based on the latest system status.""" - _LOGGING_INTERVAL = timedelta(minutes=1) + _LOGGING_INTERVAL = timedelta(seconds=0.5) """Interval at which the autoscaled pool logs its current state.""" _DESIRED_CONCURRENCY_RATIO = 0.9 From 5d83c477cd1e03d45da58220b7e2e723ee26b1c0 Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Fri, 5 Dec 2025 09:19:52 +0100 Subject: [PATCH 18/26] Try to add waits to avoid busy-waiting in cases where it makes no sense --- src/crawlee/_autoscaling/autoscaled_pool.py | 6 +++++- src/crawlee/crawlers/_basic/_basic_crawler.py | 3 +++ .../storage_clients/_file_system/_request_queue_client.py | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/crawlee/_autoscaling/autoscaled_pool.py b/src/crawlee/_autoscaling/autoscaled_pool.py index 15d0ac606b..502c2399e5 100644 --- a/src/crawlee/_autoscaling/autoscaled_pool.py +++ b/src/crawlee/_autoscaling/autoscaled_pool.py @@ -61,6 +61,9 @@ class AutoscaledPool: _TASK_TIMEOUT: timedelta | None = None """Timeout within which the `run_task_function` must complete.""" + _OVERLOADED_BACKOFF_TIME: timedelta = timedelta(seconds=0.5) + """When overloaded, Autoscaled pool waits this long before rechecking system status.""" + def __init__( self, *, @@ -238,6 +241,7 @@ async def _worker_task_orchestrator(self, run: _AutoscaledPoolRun) -> None: current_status = self._system_status.get_current_system_info() if not current_status.is_system_idle: logger.info('Not scheduling new tasks - system is overloaded') + await asyncio.sleep(self._OVERLOADED_BACKOFF_TIME) elif self._is_paused: logger.info('Not scheduling new tasks - the autoscaled pool is paused') elif self.current_concurrency >= self.desired_concurrency: @@ -261,7 +265,7 @@ async def _worker_task_orchestrator(self, run: _AutoscaledPoolRun) -> None: logger.info("Just finishing") - except Exception as e: + except BaseException as e: logger.error('What is hiding here?', exc_info=e) raise diff --git a/src/crawlee/crawlers/_basic/_basic_crawler.py b/src/crawlee/crawlers/_basic/_basic_crawler.py index dd5f6ec41c..94df73cfa2 100644 --- a/src/crawlee/crawlers/_basic/_basic_crawler.py +++ b/src/crawlee/crawlers/_basic/_basic_crawler.py @@ -1386,6 +1386,9 @@ async def __run_task_function(self) -> None: ) if request is None: + # No request to process, request manager is neither finished nor empty. + # All requests are locked or in progress. + await asyncio.sleep(0.2) # Small backoff time to avoid overloading the system through busy-waiting. return if not (await self._is_allowed_based_on_robots_txt_file(request.url)): diff --git a/src/crawlee/storage_clients/_file_system/_request_queue_client.py b/src/crawlee/storage_clients/_file_system/_request_queue_client.py index 4277d0ac26..9af48fdef5 100644 --- a/src/crawlee/storage_clients/_file_system/_request_queue_client.py +++ b/src/crawlee/storage_clients/_file_system/_request_queue_client.py @@ -596,6 +596,7 @@ async def is_empty(self) -> bool: async with self._lock: # If we have a cached value, return it immediately. if self._is_empty_cache is not None: + logger.info(f'From cache {self._is_empty_cache=}') return self._is_empty_cache state = self._state.current_value From 4da836101c50668c28bf42399dc53f365717b57a Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Fri, 5 Dec 2025 09:58:44 +0100 Subject: [PATCH 19/26] Add more CPU usage measurement logs --- src/crawlee/_autoscaling/system_status.py | 1 + src/crawlee/_log_config.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/crawlee/_autoscaling/system_status.py b/src/crawlee/_autoscaling/system_status.py index b2dfcc60a2..d9b8ead859 100644 --- a/src/crawlee/_autoscaling/system_status.py +++ b/src/crawlee/_autoscaling/system_status.py @@ -123,6 +123,7 @@ def _is_cpu_overloaded(self, sample_duration: timedelta | None = None) -> LoadRa CPU load ratio information. """ sample = self._snapshotter.get_cpu_sample(sample_duration) + logger.info(sample) return self._is_sample_overloaded(sample, self._cpu_overload_threshold) def _is_memory_overloaded(self, sample_duration: timedelta | None = None) -> LoadRatioInfo: diff --git a/src/crawlee/_log_config.py b/src/crawlee/_log_config.py index 5fc9e94b8a..6e06b9f4fb 100644 --- a/src/crawlee/_log_config.py +++ b/src/crawlee/_log_config.py @@ -4,6 +4,7 @@ import logging import sys import textwrap +from datetime import datetime from typing import TYPE_CHECKING, Any from colorama import Fore, Style, just_fix_windows_console @@ -162,6 +163,6 @@ def format(self, record: logging.LogRecord) -> str: if self.include_logger_name: # Include logger name at the beginning of the log line - return f'{logger_name_string}{level_string}{log_string}{extra_string}{exception_string}' + return f'{datetime.utcnow().strftime("%M-%S-%f")}{logger_name_string}{level_string}{log_string}{extra_string}{exception_string}' return f'{level_string}{log_string}{extra_string}{exception_string}' From d3d5c033d00779f74499cae8613762eccd7feec4 Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Fri, 5 Dec 2025 10:23:53 +0100 Subject: [PATCH 20/26] See measurements problems with CPU usage --- src/crawlee/_autoscaling/autoscaled_pool.py | 4 ++-- src/crawlee/events/_local_event_manager.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/crawlee/_autoscaling/autoscaled_pool.py b/src/crawlee/_autoscaling/autoscaled_pool.py index 86fef437a4..4877385ebb 100644 --- a/src/crawlee/_autoscaling/autoscaled_pool.py +++ b/src/crawlee/_autoscaling/autoscaled_pool.py @@ -61,7 +61,7 @@ class AutoscaledPool: _TASK_TIMEOUT: timedelta | None = None """Timeout within which the `run_task_function` must complete.""" - _OVERLOADED_BACKOFF_TIME: timedelta = timedelta(seconds=0.5) + _OVERLOADED_BACKOFF_TIME: timedelta = timedelta(seconds=1) """When overloaded, Autoscaled pool waits this long before rechecking system status.""" def __init__( @@ -240,7 +240,7 @@ async def _worker_task_orchestrator(self, run: _AutoscaledPoolRun) -> None: current_status = self._system_status.get_current_system_info() if not current_status.is_system_idle: - logger.info('Not scheduling new tasks - system is overloaded') + logger.info(f'Not scheduling new tasks - system is overloaded: {current_status}') await asyncio.sleep(self._OVERLOADED_BACKOFF_TIME.total_seconds()) logger.info('Release the overloaded backoff') elif self._is_paused: diff --git a/src/crawlee/events/_local_event_manager.py b/src/crawlee/events/_local_event_manager.py index 459d9731b7..4e3da032f6 100644 --- a/src/crawlee/events/_local_event_manager.py +++ b/src/crawlee/events/_local_event_manager.py @@ -93,8 +93,8 @@ async def __aexit__( async def _emit_system_info_event(self) -> None: """Emit a system info event with the current CPU and memory usage.""" - cpu_info = await asyncio.to_thread(get_cpu_info) - memory_info = await asyncio.to_thread(get_memory_info) + cpu_info = get_cpu_info() + memory_info = get_memory_info() event_data = EventSystemInfoData(cpu_info=cpu_info, memory_info=memory_info) self.emit(event=Event.SYSTEM_INFO, event_data=event_data) From 48830c30a5575b5bc9e19cab9750b901887c5238 Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Fri, 5 Dec 2025 10:43:50 +0100 Subject: [PATCH 21/26] See more detailed CPu measurements --- src/crawlee/_utils/system.py | 7 ++++--- tests/unit/crawlers/_basic/test_basic_crawler.py | 11 +++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/crawlee/_utils/system.py b/src/crawlee/_utils/system.py index d1f1cd9976..39d4b83ba4 100644 --- a/src/crawlee/_utils/system.py +++ b/src/crawlee/_utils/system.py @@ -93,9 +93,10 @@ def get_cpu_info() -> CpuInfo: It utilizes the `psutil` library. Function `psutil.cpu_percent()` returns a float representing the current system-wide CPU utilization as a percentage. """ - logger.debug('Calling get_cpu_info()...') - cpu_percent = psutil.cpu_percent(interval=0.1) - return CpuInfo(used_ratio=cpu_percent / 100) + + cpu_percent = psutil.cpu_percent(percpu=True) + logger.info(f'Calling get_cpu_info()...: {cpu_percent}') + return CpuInfo(used_ratio=sum(cpu_percent)/len(cpu_percent) / 100) def get_memory_info() -> MemoryInfo: diff --git a/tests/unit/crawlers/_basic/test_basic_crawler.py b/tests/unit/crawlers/_basic/test_basic_crawler.py index bb460b97f3..29e5a52647 100644 --- a/tests/unit/crawlers/_basic/test_basic_crawler.py +++ b/tests/unit/crawlers/_basic/test_basic_crawler.py @@ -12,9 +12,11 @@ from dataclasses import dataclass from datetime import timedelta from itertools import product +from subprocess import run from typing import TYPE_CHECKING, Any, Literal, cast from unittest.mock import AsyncMock, Mock, call, patch +import psutil import pytest from crawlee import ConcurrencySettings, Glob, service_locator @@ -1290,6 +1292,13 @@ async def test_timeout_in_handler(sleep_type: str, _) -> None: # Test is skipped in older Python versions. from asyncio import timeout # type:ignore[attr-defined] # noqa: PLC0415 + # Debug CPu usage before starting the test + run("ps -ewfaxo comm,user,pid,%cpu,cmd", shell=True) + + run("ps -awxo pid,%cpu,comm", shell=True) + + + handler_timeout = timedelta(seconds=1) max_request_retries = 3 double_handler_timeout_s = handler_timeout.total_seconds() * 2 @@ -1301,6 +1310,8 @@ async def test_timeout_in_handler(sleep_type: str, _) -> None: max_request_retries=max_request_retries, ) crawler.log.setLevel(logging.DEBUG) + + crawler.log.info(f'Calling get_cpu_info()...: {psutil.cpu_percent(percpu=True)}') logging.getLogger('crawlee.storage_clients._file_system._request_queue_client').setLevel(logging.DEBUG) logging.getLogger('crawlee._autoscaling.autoscaled_pool').setLevel(logging.INFO) From 25207b3218740a9f28419ab60df6f525d1898939 Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Fri, 5 Dec 2025 13:24:26 +0100 Subject: [PATCH 22/26] Try to disable spotlight on the mac executor --- .github/workflows/run_code_checks.yaml | 39 +++++++++++++++++++++----- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/.github/workflows/run_code_checks.yaml b/.github/workflows/run_code_checks.yaml index b51da18ab9..ada5c6a55e 100644 --- a/.github/workflows/run_code_checks.yaml +++ b/.github/workflows/run_code_checks.yaml @@ -30,13 +30,38 @@ jobs: python-versions: '["3.10", "3.11", "3.12", "3.13", "3.14"]' unit_tests: - name: Unit tests - uses: apify/workflows/.github/workflows/python_unit_tests.yaml@main - 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", "3.14"]' - os: '["ubuntu-latest", "windows-latest", "macos-latest"]' + strategy: + fail-fast: false + matrix: + os: ["ubuntu-latest", "windows-latest", "macos-latest"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + runs-on: ${{ matrix.os }} + env: + HTTPBIN_URL: 'asd' + + steps: + - name: Disable Spotlight indexing + if: runner.os == 'macOS' + run: sudo mdutil -i off / + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Set up uv package manager + uses: astral-sh/setup-uv@v6 + with: + python-version: ${{ matrix.python-version }} + + - name: Install Python dependencies + run: make install-dev + + - name: Run unit tests + run: make unit-tests docs_check: name: Docs check From 4435c8aeae582689160f00f2793aaffcbb103e67 Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Fri, 5 Dec 2025 13:45:15 +0100 Subject: [PATCH 23/26] Try to cleanup mac executor even more --- .github/workflows/run_code_checks.yaml | 12 ++++++++++-- src/crawlee/_utils/system.py | 10 +++++++++- tests/unit/crawlers/_basic/test_basic_crawler.py | 7 ++----- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/.github/workflows/run_code_checks.yaml b/.github/workflows/run_code_checks.yaml index ada5c6a55e..f53e1a1848 100644 --- a/.github/workflows/run_code_checks.yaml +++ b/.github/workflows/run_code_checks.yaml @@ -40,9 +40,17 @@ jobs: HTTPBIN_URL: 'asd' steps: - - name: Disable Spotlight indexing + - name: Os cleanup if: runner.os == 'macOS' - run: sudo mdutil -i off / + run: | + sudo mdutil -i off / + sudo killall ecosystemanalyticsd + sudo killall Finder || true + sudo killall mds || true + sudo killall mds_stores || true + sudo killall mds_worker || true + sudo killall mdworker || true + sudo killall mdworker_shared || true - name: Checkout repository uses: actions/checkout@v4 diff --git a/src/crawlee/_utils/system.py b/src/crawlee/_utils/system.py index 39d4b83ba4..5863dbafbb 100644 --- a/src/crawlee/_utils/system.py +++ b/src/crawlee/_utils/system.py @@ -5,6 +5,7 @@ from contextlib import suppress from datetime import datetime, timezone from logging import getLogger +from subprocess import run from typing import Annotated import psutil @@ -96,7 +97,10 @@ def get_cpu_info() -> CpuInfo: cpu_percent = psutil.cpu_percent(percpu=True) logger.info(f'Calling get_cpu_info()...: {cpu_percent}') - return CpuInfo(used_ratio=sum(cpu_percent)/len(cpu_percent) / 100) + ratio = sum(cpu_percent)/len(cpu_percent) / 100 + if ratio>0.95: + print_ps() + return CpuInfo(used_ratio=ratio) def get_memory_info() -> MemoryInfo: @@ -124,3 +128,7 @@ def get_memory_info() -> MemoryInfo: current_size=ByteSize(current_size_bytes), system_wide_used_size=ByteSize(vm.total - vm.available), ) + + +def print_ps(): + run("ps -awxo pid,%cpu,comm", shell=True) diff --git a/tests/unit/crawlers/_basic/test_basic_crawler.py b/tests/unit/crawlers/_basic/test_basic_crawler.py index 29e5a52647..514a358d2a 100644 --- a/tests/unit/crawlers/_basic/test_basic_crawler.py +++ b/tests/unit/crawlers/_basic/test_basic_crawler.py @@ -23,6 +23,7 @@ from crawlee._request import Request, RequestState from crawlee._types import BasicCrawlingContext, EnqueueLinksKwargs, HttpMethod from crawlee._utils.robots import RobotsTxtFile +from crawlee._utils.system import print_ps from crawlee.configuration import Configuration from crawlee.crawlers import BasicCrawler from crawlee.errors import RequestCollisionError, SessionError, UserDefinedErrorHandlerError @@ -1293,11 +1294,7 @@ async def test_timeout_in_handler(sleep_type: str, _) -> None: from asyncio import timeout # type:ignore[attr-defined] # noqa: PLC0415 # Debug CPu usage before starting the test - run("ps -ewfaxo comm,user,pid,%cpu,cmd", shell=True) - - run("ps -awxo pid,%cpu,comm", shell=True) - - + print_ps() handler_timeout = timedelta(seconds=1) max_request_retries = 3 From 58c8140e5c4bca28c1295f64430cbcfd4a55fd7b Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Fri, 5 Dec 2025 14:22:45 +0100 Subject: [PATCH 24/26] Revert all but executor changes --- .github/workflows/run_code_checks.yaml | 11 ++-- Makefile | 2 +- src/crawlee/_autoscaling/autoscaled_pool.py | 52 +++++-------------- src/crawlee/_autoscaling/system_status.py | 1 - src/crawlee/_log_config.py | 3 +- src/crawlee/_utils/system.py | 15 ++---- src/crawlee/crawlers/_basic/_basic_crawler.py | 24 ++------- src/crawlee/events/_local_event_manager.py | 4 +- src/crawlee/statistics/_error_tracker.py | 4 -- .../_file_system/_request_queue_client.py | 16 +----- .../crawlers/_basic/test_basic_crawler.py | 25 ++------- tests/unit/events/test_local_event_manager.py | 10 ++-- 12 files changed, 35 insertions(+), 132 deletions(-) diff --git a/.github/workflows/run_code_checks.yaml b/.github/workflows/run_code_checks.yaml index f53e1a1848..0f06554b59 100644 --- a/.github/workflows/run_code_checks.yaml +++ b/.github/workflows/run_code_checks.yaml @@ -40,17 +40,12 @@ jobs: HTTPBIN_URL: 'asd' steps: - - name: Os cleanup + - name: macOS cleanup if: runner.os == 'macOS' + # Disable Spotlight indexing and try to kill all useless processes that could drain CPU during tests run: | sudo mdutil -i off / - sudo killall ecosystemanalyticsd - sudo killall Finder || true - sudo killall mds || true - sudo killall mds_stores || true - sudo killall mds_worker || true - sudo killall mdworker || true - sudo killall mdworker_shared || true + sudo killall Finder spindump ecosystemanalyticsd SystemUIServer NotificationCenter mds mds_stores mds_worker mdworker mdworker_shared || true - name: Checkout repository uses: actions/checkout@v4 diff --git a/Makefile b/Makefile index a16ff5c578..6ca17970b0 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ type-check: unit-tests: uv run pytest --numprocesses=1 -vv tests/unit -m "run_alone" - #uv run pytest --numprocesses=auto -vv tests/unit -m "not run_alone" + uv run pytest --numprocesses=auto -vv tests/unit -m "not run_alone" unit-tests-cov: uv run pytest --numprocesses=1 -vv --cov=src/crawlee tests/unit -m "run_alone" diff --git a/src/crawlee/_autoscaling/autoscaled_pool.py b/src/crawlee/_autoscaling/autoscaled_pool.py index 4877385ebb..89f7c89312 100644 --- a/src/crawlee/_autoscaling/autoscaled_pool.py +++ b/src/crawlee/_autoscaling/autoscaled_pool.py @@ -46,7 +46,7 @@ class AutoscaledPool: _AUTOSCALE_INTERVAL = timedelta(seconds=10) """Interval at which the autoscaled pool adjusts the desired concurrency based on the latest system status.""" - _LOGGING_INTERVAL = timedelta(seconds=0.5) + _LOGGING_INTERVAL = timedelta(minutes=1) """Interval at which the autoscaled pool logs its current state.""" _DESIRED_CONCURRENCY_RATIO = 0.9 @@ -61,9 +61,6 @@ class AutoscaledPool: _TASK_TIMEOUT: timedelta | None = None """Timeout within which the `run_task_function` must complete.""" - _OVERLOADED_BACKOFF_TIME: timedelta = timedelta(seconds=1) - """When overloaded, Autoscaled pool waits this long before rechecking system status.""" - def __init__( self, *, @@ -126,33 +123,19 @@ async def run(self) -> None: ) try: - logger.info(f'Await result') await run.result - logger.info(f'Finished naturally, {run.worker_tasks=}, {run.result.result()=}') except AbortError: - logger.info('AbortError') orchestrator.cancel() for task in run.worker_tasks: if not task.done(): task.cancel() - except Exception as exc: - logger.error('Something sinister happened', exc_info=exc) - raise - except BaseException as exc: - logger.error('BaseException happened', exc_info=exc) - raise - finally: - logger.error('finally') with suppress(asyncio.CancelledError): - logger.error('self._autoscale_task.stop()') await self._autoscale_task.stop() with suppress(asyncio.CancelledError): - logger.error('await self._log_system_status_task.stop()') await self._log_system_status_task.stop() if not orchestrator.done(): - logger.error('not orchestrator.done()') orchestrator.cancel() elif not orchestrator.cancelled() and orchestrator.exception() is not None: logger.error('Exception in worker task orchestrator', exc_info=orchestrator.exception()) @@ -233,59 +216,48 @@ async def _worker_task_orchestrator(self, run: _AutoscaledPoolRun) -> None: Exits when `is_finished_function` returns True. """ finished = False - logger.info('_worker_task_orchestrator') + try: while not (finished := await self._is_finished_function()) and not run.result.done(): run.worker_tasks_updated.clear() current_status = self._system_status.get_current_system_info() if not current_status.is_system_idle: - logger.info(f'Not scheduling new tasks - system is overloaded: {current_status}') - await asyncio.sleep(self._OVERLOADED_BACKOFF_TIME.total_seconds()) - logger.info('Release the overloaded backoff') + logger.debug('Not scheduling new tasks - system is overloaded') elif self._is_paused: - logger.info('Not scheduling new tasks - the autoscaled pool is paused') + logger.debug('Not scheduling new tasks - the autoscaled pool is paused') elif self.current_concurrency >= self.desired_concurrency: - logger.info('Not scheduling new tasks - already running at desired concurrency') + logger.debug('Not scheduling new tasks - already running at desired concurrency') elif not await self._is_task_ready_function(): logger.debug('Not scheduling new task - no task is ready') else: - logger.info('Scheduling a new task') + logger.debug('Scheduling a new task') worker_task = asyncio.create_task(self._worker_task(), name='autoscaled pool worker task') worker_task.add_done_callback(lambda task: self._reap_worker_task(task, run)) run.worker_tasks.append(worker_task) if math.isfinite(self._max_tasks_per_minute): - logger.info('Deadlock sleep????') await asyncio.sleep(60 / self._max_tasks_per_minute) continue with suppress(asyncio.TimeoutError): await asyncio.wait_for(run.worker_tasks_updated.wait(), timeout=0.5) - - logger.info("Just finishing") - - except BaseException as e: - logger.error('What is hiding here?', exc_info=e) - raise - finally: - logger.info(f'Finally pool. {finished=}, {(run.result.done())=}, {(run.result.result() if run.result.done() else None)=}') if finished: - logger.info('`is_finished_function` reports that we are finished') + logger.debug('`is_finished_function` reports that we are finished') elif run.result.done() and run.result.exception() is not None: - logger.info('Unhandled exception in `run_task_function`') + logger.debug('Unhandled exception in `run_task_function`') if run.worker_tasks: - logger.info('Terminating - waiting for tasks to complete') + logger.debug('Terminating - waiting for tasks to complete') await asyncio.wait(run.worker_tasks, return_when=asyncio.ALL_COMPLETED) - logger.info('Worker tasks finished') + logger.debug('Worker tasks finished') else: - logger.info('Terminating - no running tasks to wait for') + logger.debug('Terminating - no running tasks to wait for') if not run.result.done(): - run.result.set_result("Hello") + run.result.set_result(object()) def _reap_worker_task(self, task: asyncio.Task, run: _AutoscaledPoolRun) -> None: """Handle cleanup and tracking of a completed worker task. diff --git a/src/crawlee/_autoscaling/system_status.py b/src/crawlee/_autoscaling/system_status.py index d9b8ead859..b2dfcc60a2 100644 --- a/src/crawlee/_autoscaling/system_status.py +++ b/src/crawlee/_autoscaling/system_status.py @@ -123,7 +123,6 @@ def _is_cpu_overloaded(self, sample_duration: timedelta | None = None) -> LoadRa CPU load ratio information. """ sample = self._snapshotter.get_cpu_sample(sample_duration) - logger.info(sample) return self._is_sample_overloaded(sample, self._cpu_overload_threshold) def _is_memory_overloaded(self, sample_duration: timedelta | None = None) -> LoadRatioInfo: diff --git a/src/crawlee/_log_config.py b/src/crawlee/_log_config.py index 6e06b9f4fb..5fc9e94b8a 100644 --- a/src/crawlee/_log_config.py +++ b/src/crawlee/_log_config.py @@ -4,7 +4,6 @@ import logging import sys import textwrap -from datetime import datetime from typing import TYPE_CHECKING, Any from colorama import Fore, Style, just_fix_windows_console @@ -163,6 +162,6 @@ def format(self, record: logging.LogRecord) -> str: if self.include_logger_name: # Include logger name at the beginning of the log line - return f'{datetime.utcnow().strftime("%M-%S-%f")}{logger_name_string}{level_string}{log_string}{extra_string}{exception_string}' + return f'{logger_name_string}{level_string}{log_string}{extra_string}{exception_string}' return f'{level_string}{log_string}{extra_string}{exception_string}' diff --git a/src/crawlee/_utils/system.py b/src/crawlee/_utils/system.py index 5863dbafbb..d1f1cd9976 100644 --- a/src/crawlee/_utils/system.py +++ b/src/crawlee/_utils/system.py @@ -5,7 +5,6 @@ from contextlib import suppress from datetime import datetime, timezone from logging import getLogger -from subprocess import run from typing import Annotated import psutil @@ -94,13 +93,9 @@ def get_cpu_info() -> CpuInfo: It utilizes the `psutil` library. Function `psutil.cpu_percent()` returns a float representing the current system-wide CPU utilization as a percentage. """ - - cpu_percent = psutil.cpu_percent(percpu=True) - logger.info(f'Calling get_cpu_info()...: {cpu_percent}') - ratio = sum(cpu_percent)/len(cpu_percent) / 100 - if ratio>0.95: - print_ps() - return CpuInfo(used_ratio=ratio) + logger.debug('Calling get_cpu_info()...') + cpu_percent = psutil.cpu_percent(interval=0.1) + return CpuInfo(used_ratio=cpu_percent / 100) def get_memory_info() -> MemoryInfo: @@ -128,7 +123,3 @@ def get_memory_info() -> MemoryInfo: current_size=ByteSize(current_size_bytes), system_wide_used_size=ByteSize(vm.total - vm.available), ) - - -def print_ps(): - run("ps -awxo pid,%cpu,comm", shell=True) diff --git a/src/crawlee/crawlers/_basic/_basic_crawler.py b/src/crawlee/crawlers/_basic/_basic_crawler.py index 73fcb37a6f..7de3c2fcdf 100644 --- a/src/crawlee/crawlers/_basic/_basic_crawler.py +++ b/src/crawlee/crawlers/_basic/_basic_crawler.py @@ -1130,7 +1130,6 @@ async def _handle_request_retries( await self._statistics.error_tracker.add(error=error, context=context) if self._error_handler: - self.log.warning('Error handler') try: new_request = await self._error_handler(context, error) except Exception as e: @@ -1146,12 +1145,11 @@ async def _handle_request_retries( await self._mark_request_as_handled(request) await self._handle_failed_request(context, error) self._statistics.record_request_processing_failure(request.unique_key) - self.log.warning('_handle_request_retries DONE') async def _handle_request_error(self, context: TCrawlingContext | BasicCrawlingContext, error: Exception) -> None: try: context.request.state = RequestState.ERROR_HANDLER - self.log.warning('Before _handle_request_error') + await wait_for( partial(self._handle_request_retries, context, error), timeout=self._internal_timeout, @@ -1159,7 +1157,6 @@ async def _handle_request_error(self, context: TCrawlingContext | BasicCrawlingC f'{self._internal_timeout.total_seconds()} seconds', logger=self._logger, ) - self.log.warning('After _handle_request_error') context.request.state = RequestState.DONE except UserDefinedErrorHandlerError: @@ -1331,17 +1328,13 @@ async def __is_finished_function(self) -> bool: if self._abort_on_error and self._failed: self._failed = False - self.log.info('_abort_on_error') return True if self._keep_alive: return False request_manager = await self.get_request_manager() - is_finished = await request_manager.is_finished() - if is_finished: - self.log.info('I am sure this is a lie!!!') - return is_finished + return await request_manager.is_finished() async def __is_task_ready_function(self) -> bool: self._stop_if_max_requests_count_exceeded() @@ -1353,10 +1346,7 @@ async def __is_task_ready_function(self) -> bool: return False request_manager = await self.get_request_manager() - is_ready = not await request_manager.is_empty() - if is_ready: - self.log.info('There is a request to process') - return is_ready + return not await request_manager.is_empty() async def __run_task_function(self) -> None: request_manager = await self.get_request_manager() @@ -1370,11 +1360,6 @@ async def __run_task_function(self) -> None: ) if request is None: - # No request to process, request manager is neither finished nor empty. - # All requests are locked or in progress. - self._logger.warning("Backoff: No available requests to process.") - await asyncio.sleep(0.2) # Small backoff time to avoid overloading the system through busy-waiting. - self._logger.warning("Backoff finished.") return if not (await self._is_allowed_based_on_robots_txt_file(request.url)): @@ -1415,10 +1400,8 @@ async def __run_task_function(self) -> None: try: await self._run_request_handler(context=context) except asyncio.TimeoutError as e: - context.log.info('RH error') raise RequestHandlerError(e, context) from e - context.log.info('Commit resutls') await self._commit_request_handler_result(context) await self._mark_request_as_handled(request) @@ -1428,7 +1411,6 @@ async def __run_task_function(self) -> None: if context.session and context.session.is_usable: context.session.mark_good() - context.log.info('Finished processing request') self._statistics.record_request_processing_finish(request.unique_key) except RequestCollisionError as request_error: diff --git a/src/crawlee/events/_local_event_manager.py b/src/crawlee/events/_local_event_manager.py index 4e3da032f6..459d9731b7 100644 --- a/src/crawlee/events/_local_event_manager.py +++ b/src/crawlee/events/_local_event_manager.py @@ -93,8 +93,8 @@ async def __aexit__( async def _emit_system_info_event(self) -> None: """Emit a system info event with the current CPU and memory usage.""" - cpu_info = get_cpu_info() - memory_info = get_memory_info() + cpu_info = await asyncio.to_thread(get_cpu_info) + memory_info = await asyncio.to_thread(get_memory_info) event_data = EventSystemInfoData(cpu_info=cpu_info, memory_info=memory_info) self.emit(event=Event.SYSTEM_INFO, event_data=event_data) diff --git a/src/crawlee/statistics/_error_tracker.py b/src/crawlee/statistics/_error_tracker.py index 1e5d816da8..5d184eabde 100644 --- a/src/crawlee/statistics/_error_tracker.py +++ b/src/crawlee/statistics/_error_tracker.py @@ -58,7 +58,6 @@ async def add( early: Flag indicating that the error is added earlier than usual to have access to resources that will be closed before normal error collection. This prevents double reporting during normal error collection. """ - logger.warning('Adding error') if id(error) in self._early_reported_errors: # Error had to be collected earlier before relevant resources are closed. self._early_reported_errors.remove(id(error)) @@ -99,15 +98,12 @@ async def add( == 1 and context is not None ): - logger.warning('awaiting snapshot') # Save snapshot only on the first occurrence of the error and only if context and kvs was passed as well. await self._capture_error_snapshot( error_message=new_error_group_message or error_group_message, file_and_line=error_group_file_and_line, context=context, ) - logger.warning('Snapshot added') - logger.warning('Finished') async def _capture_error_snapshot( self, error_message: str, file_and_line: str, context: BasicCrawlingContext diff --git a/src/crawlee/storage_clients/_file_system/_request_queue_client.py b/src/crawlee/storage_clients/_file_system/_request_queue_client.py index 9af48fdef5..e49771b7c9 100644 --- a/src/crawlee/storage_clients/_file_system/_request_queue_client.py +++ b/src/crawlee/storage_clients/_file_system/_request_queue_client.py @@ -57,6 +57,7 @@ class RequestQueueState(BaseModel): handled_requests: set[str] = set() """Set of request unique keys that have been handled.""" + class FileSystemRequestQueueClient(RequestQueueClient): """A file system implementation of the request queue client. @@ -545,14 +546,12 @@ async def reclaim_request( # Update sequence number and state to ensure proper ordering. if forefront: - logger.info('Reclaiming forefront request') # Remove from regular requests if it was there state.regular_requests.pop(request.unique_key, None) sequence_number = state.forefront_sequence_counter state.forefront_sequence_counter += 1 state.forefront_requests[request.unique_key] = sequence_number else: - logger.info('Reclaiming regular request') # Remove from forefront requests if it was there state.forefront_requests.pop(request.unique_key, None) sequence_number = state.sequence_counter @@ -560,30 +559,23 @@ async def reclaim_request( state.regular_requests[request.unique_key] = sequence_number # Save the clean request without extra fields - request_data = await json_dumps(request.model_dump()) - logger.info('Atomic write') await atomic_write(request_path, request_data) # Remove from in-progress. - logger.info('Remove from in-progress') state.in_progress_requests.discard(request.unique_key) - logger.info('Update RQ metadata.') # Update RQ metadata. await self._update_metadata( update_modified_at=True, update_accessed_at=True, ) - logger.info('Updated RQ metadata.') # Add the request back to the cache. if forefront: self._request_cache.appendleft(request) - logger.info(f'Add the request back to the cache: forefront. {self._request_cache}') else: self._request_cache.append(request) - logger.info(f'Add the request back to the cache: normal. . {self._request_cache}') return ProcessedRequest( unique_key=request.unique_key, @@ -596,7 +588,6 @@ async def is_empty(self) -> bool: async with self._lock: # If we have a cached value, return it immediately. if self._is_empty_cache is not None: - logger.info(f'From cache {self._is_empty_cache=}') return self._is_empty_cache state = self._state.current_value @@ -604,7 +595,6 @@ async def is_empty(self) -> bool: # If there are in-progress requests, return False immediately. if len(state.in_progress_requests) > 0: self._is_empty_cache = False - logger.info(f'{state.in_progress_requests=}') return False # If we have a cached requests, check them first (fast path). @@ -612,10 +602,8 @@ async def is_empty(self) -> bool: for req in self._request_cache: if req.unique_key not in state.handled_requests: self._is_empty_cache = False - logger.info(f'{(req.unique_key not in state.handled_requests)=}') return False self._is_empty_cache = True - logger.info(f'{(len(state.in_progress_requests) == 0)=}') return len(state.in_progress_requests) == 0 # Fallback: check state for unhandled requests. @@ -627,11 +615,9 @@ async def is_empty(self) -> bool: if unhandled_requests: self._is_empty_cache = False - logger.info(f'{unhandled_requests=}') return False self._is_empty_cache = True - logger.info('Last resort is empty') return True def _get_request_path(self, unique_key: str) -> Path: diff --git a/tests/unit/crawlers/_basic/test_basic_crawler.py b/tests/unit/crawlers/_basic/test_basic_crawler.py index 514a358d2a..a3c43acf40 100644 --- a/tests/unit/crawlers/_basic/test_basic_crawler.py +++ b/tests/unit/crawlers/_basic/test_basic_crawler.py @@ -12,18 +12,15 @@ from dataclasses import dataclass from datetime import timedelta from itertools import product -from subprocess import run from typing import TYPE_CHECKING, Any, Literal, cast from unittest.mock import AsyncMock, Mock, call, patch -import psutil import pytest from crawlee import ConcurrencySettings, Glob, service_locator from crawlee._request import Request, RequestState from crawlee._types import BasicCrawlingContext, EnqueueLinksKwargs, HttpMethod from crawlee._utils.robots import RobotsTxtFile -from crawlee._utils.system import print_ps from crawlee.configuration import Configuration from crawlee.crawlers import BasicCrawler from crawlee.errors import RequestCollisionError, SessionError, UserDefinedErrorHandlerError @@ -1274,7 +1271,7 @@ async def handler(context: BasicCrawlingContext) -> None: await store.persist_autosaved_values() assert (await store.get_value(BasicCrawler._CRAWLEE_STATE_KEY))['counter'] == 2 -@pytest.mark.parametrize("_", range(10)) + @pytest.mark.run_alone @pytest.mark.skipif(sys.version_info[:3] < (3, 11), reason='asyncio.timeout was introduced in Python 3.11.') @pytest.mark.parametrize( @@ -1284,7 +1281,7 @@ async def handler(context: BasicCrawlingContext) -> None: pytest.param('sync_sleep', marks=pytest.mark.skip(reason='https://github.com/apify/crawlee-python/issues/908')), ], ) -async def test_timeout_in_handler(sleep_type: str, _) -> None: +async def test_timeout_in_handler(sleep_type: str) -> None: """Test that timeout from request handler is treated the same way as exception thrown in request handler. Handler should be able to time out even if the code causing the timeout is blocking sync code. @@ -1293,25 +1290,12 @@ async def test_timeout_in_handler(sleep_type: str, _) -> None: # Test is skipped in older Python versions. from asyncio import timeout # type:ignore[attr-defined] # noqa: PLC0415 - # Debug CPu usage before starting the test - print_ps() - handler_timeout = timedelta(seconds=1) max_request_retries = 3 double_handler_timeout_s = handler_timeout.total_seconds() * 2 handler_sleep = iter([double_handler_timeout_s, double_handler_timeout_s, 0]) - CI_test_tolerance = 5 # MacOS CI has been slow in exceptional cases - - crawler = BasicCrawler( - request_handler_timeout=handler_timeout, - max_request_retries=max_request_retries, - ) - crawler.log.setLevel(logging.DEBUG) - - crawler.log.info(f'Calling get_cpu_info()...: {psutil.cpu_percent(percpu=True)}') - logging.getLogger('crawlee.storage_clients._file_system._request_queue_client').setLevel(logging.DEBUG) - logging.getLogger('crawlee._autoscaling.autoscaled_pool').setLevel(logging.INFO) + crawler = BasicCrawler(request_handler_timeout=handler_timeout, max_request_retries=max_request_retries) mocked_handler_before_sleep = Mock() mocked_handler_after_sleep = Mock() @@ -1327,11 +1311,10 @@ async def handler(context: BasicCrawlingContext) -> None: # This will not execute if timeout happens. mocked_handler_after_sleep() - context.log.info('Handling request') # Timeout in pytest, because previous implementation would run crawler until following: # "The request queue seems to be stuck for 300.0s, resetting internal state." - async with timeout(max_request_retries * double_handler_timeout_s + CI_test_tolerance): + async with timeout(max_request_retries * double_handler_timeout_s): await crawler.run(['https://a.placeholder.com']) assert crawler.statistics.state.requests_finished == 1 diff --git a/tests/unit/events/test_local_event_manager.py b/tests/unit/events/test_local_event_manager.py index e60de9a5dc..481c7da16b 100644 --- a/tests/unit/events/test_local_event_manager.py +++ b/tests/unit/events/test_local_event_manager.py @@ -17,15 +17,15 @@ def listener() -> AsyncMock: async def async_listener(payload: Any) -> None: pass - return AsyncMock(target=async_listener) + al = AsyncMock() + update_wrapper(al, async_listener) + return al async def test_emit_system_info_event(listener: AsyncMock) -> None: - system_info_interval = timedelta(milliseconds=50) - test_tolerance_coefficient = 10 - async with LocalEventManager(system_info_interval=system_info_interval) as event_manager: + async with LocalEventManager(system_info_interval=timedelta(milliseconds=50)) as event_manager: event_manager.on(event=Event.SYSTEM_INFO, listener=listener) - await asyncio.sleep(system_info_interval.total_seconds() * test_tolerance_coefficient) + await asyncio.sleep(0.2) assert listener.call_count >= 1 assert isinstance(listener.call_args[0][0], EventSystemInfoData) From fc0632f484322e41c89425011834c498fd1a943c Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Fri, 5 Dec 2025 15:00:12 +0100 Subject: [PATCH 25/26] Add test tolerance --- tests/unit/events/test_local_event_manager.py | 28 ++++++++----------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/tests/unit/events/test_local_event_manager.py b/tests/unit/events/test_local_event_manager.py index 481c7da16b..bc50c84c92 100644 --- a/tests/unit/events/test_local_event_manager.py +++ b/tests/unit/events/test_local_event_manager.py @@ -2,30 +2,24 @@ import asyncio from datetime import timedelta -from functools import update_wrapper from typing import Any from unittest.mock import AsyncMock -import pytest - from crawlee.events import LocalEventManager from crawlee.events._types import Event, EventSystemInfoData -@pytest.fixture -def listener() -> AsyncMock: - async def async_listener(payload: Any) -> None: - pass - - al = AsyncMock() - update_wrapper(al, async_listener) - return al +async def test_emit_system_info_event() -> None: + mocked_listener = AsyncMock() + async def async_listener(payload: Any) -> None: + mocked_listener(payload) -async def test_emit_system_info_event(listener: AsyncMock) -> None: - async with LocalEventManager(system_info_interval=timedelta(milliseconds=50)) as event_manager: - event_manager.on(event=Event.SYSTEM_INFO, listener=listener) - await asyncio.sleep(0.2) + system_info_interval = timedelta(milliseconds=50) + test_tolerance_coefficient = 10 + async with LocalEventManager(system_info_interval=system_info_interval) as event_manager: + event_manager.on(event=Event.SYSTEM_INFO, listener=async_listener) + await asyncio.sleep(system_info_interval.total_seconds() * test_tolerance_coefficient) - assert listener.call_count >= 1 - assert isinstance(listener.call_args[0][0], EventSystemInfoData) + assert mocked_listener.call_count >= 1 + assert isinstance(mocked_listener.call_args[0][0], EventSystemInfoData) From 2ef29dbe33fd26e2360e2442b7fa960384d9c651 Mon Sep 17 00:00:00 2001 From: Josef Prochazka Date: Mon, 8 Dec 2025 07:40:09 +0100 Subject: [PATCH 26/26] Revert custom ut wrkflow --- .github/workflows/run_code_checks.yaml | 42 +++++--------------------- 1 file changed, 7 insertions(+), 35 deletions(-) diff --git a/.github/workflows/run_code_checks.yaml b/.github/workflows/run_code_checks.yaml index 0f06554b59..b51da18ab9 100644 --- a/.github/workflows/run_code_checks.yaml +++ b/.github/workflows/run_code_checks.yaml @@ -30,41 +30,13 @@ jobs: python-versions: '["3.10", "3.11", "3.12", "3.13", "3.14"]' unit_tests: - strategy: - fail-fast: false - matrix: - os: ["ubuntu-latest", "windows-latest", "macos-latest"] - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] - runs-on: ${{ matrix.os }} - env: - HTTPBIN_URL: 'asd' - - steps: - - name: macOS cleanup - if: runner.os == 'macOS' - # Disable Spotlight indexing and try to kill all useless processes that could drain CPU during tests - run: | - sudo mdutil -i off / - sudo killall Finder spindump ecosystemanalyticsd SystemUIServer NotificationCenter mds mds_stores mds_worker mdworker mdworker_shared || true - - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - - name: Set up uv package manager - uses: astral-sh/setup-uv@v6 - with: - python-version: ${{ matrix.python-version }} - - - name: Install Python dependencies - run: make install-dev - - - name: Run unit tests - run: make unit-tests + name: Unit tests + uses: apify/workflows/.github/workflows/python_unit_tests.yaml@main + 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", "3.14"]' + os: '["ubuntu-latest", "windows-latest", "macos-latest"]' docs_check: name: Docs check