From 75f51121ea316364255b5e8eead7b9b7288f5f63 Mon Sep 17 00:00:00 2001 From: Flash Date: Fri, 10 Apr 2026 15:29:44 +0000 Subject: [PATCH] Add production-ready scraper with README --- Dockerfile | 19 + README.md | 26 + app/main.py | 52 + k8s.yaml | 117 + requirements.txt | 3 + skaffold.yaml | 16 + venv/bin/Activate.ps1 | 247 + venv/bin/activate | 70 + venv/bin/activate.csh | 27 + venv/bin/activate.fish | 69 + venv/bin/fastapi | 8 + venv/bin/httpx | 8 + venv/bin/pip | 8 + venv/bin/pip3 | 8 + venv/bin/pip3.12 | 8 + venv/bin/python | 1 + venv/bin/python3 | 1 + venv/bin/python3.12 | 1 + venv/bin/uvicorn | 8 + .../typing_extensions.cpython-312.pyc | Bin 0 -> 163763 bytes .../annotated_doc-0.0.4.dist-info/INSTALLER | 1 + .../annotated_doc-0.0.4.dist-info/METADATA | 145 + .../annotated_doc-0.0.4.dist-info/RECORD | 11 + .../annotated_doc-0.0.4.dist-info/WHEEL | 4 + .../entry_points.txt | 4 + .../licenses/LICENSE | 21 + .../site-packages/annotated_doc/__init__.py | 3 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 265 bytes .../__pycache__/main.cpython-312.pyc | Bin 0 -> 1913 bytes .../site-packages/annotated_doc/main.py | 36 + .../site-packages/annotated_doc/py.typed | 0 .../annotated_types-0.7.0.dist-info/INSTALLER | 1 + .../annotated_types-0.7.0.dist-info/METADATA | 295 + .../annotated_types-0.7.0.dist-info/RECORD | 10 + .../annotated_types-0.7.0.dist-info/WHEEL | 4 + .../licenses/LICENSE | 21 + .../site-packages/annotated_types/__init__.py | 432 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 18634 bytes .../__pycache__/test_cases.cpython-312.pyc | Bin 0 -> 13253 bytes .../site-packages/annotated_types/py.typed | 0 .../annotated_types/test_cases.py | 151 + .../anyio-4.13.0.dist-info/INSTALLER | 1 + .../anyio-4.13.0.dist-info/METADATA | 105 + .../anyio-4.13.0.dist-info/RECORD | 92 + .../anyio-4.13.0.dist-info/WHEEL | 5 + .../anyio-4.13.0.dist-info/entry_points.txt | 2 + .../anyio-4.13.0.dist-info/licenses/LICENSE | 20 + .../anyio-4.13.0.dist-info/top_level.txt | 1 + .../site-packages/anyio/__init__.py | 111 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 4642 bytes .../__pycache__/from_thread.cpython-312.pyc | Bin 0 -> 25885 bytes .../__pycache__/functools.cpython-312.pyc | Bin 0 -> 16608 bytes .../__pycache__/lowlevel.cpython-312.pyc | Bin 0 -> 8008 bytes .../__pycache__/pytest_plugin.cpython-312.pyc | Bin 0 -> 16837 bytes .../to_interpreter.cpython-312.pyc | Bin 0 -> 10365 bytes .../__pycache__/to_process.cpython-312.pyc | Bin 0 -> 12037 bytes .../__pycache__/to_thread.cpython-312.pyc | Bin 0 -> 3217 bytes .../site-packages/anyio/_backends/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 203 bytes .../__pycache__/_asyncio.cpython-312.pyc | Bin 0 -> 138982 bytes .../__pycache__/_trio.cpython-312.pyc | Bin 0 -> 71662 bytes .../site-packages/anyio/_backends/_asyncio.py | 2996 ++++++ .../site-packages/anyio/_backends/_trio.py | 1343 +++ .../site-packages/anyio/_core/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 199 bytes .../_asyncio_selector_thread.cpython-312.pyc | Bin 0 -> 8430 bytes .../_contextmanagers.cpython-312.pyc | Bin 0 -> 9005 bytes .../__pycache__/_eventloop.cpython-312.pyc | Bin 0 -> 8198 bytes .../__pycache__/_exceptions.cpython-312.pyc | Bin 0 -> 7441 bytes .../_core/__pycache__/_fileio.cpython-312.pyc | Bin 0 -> 43315 bytes .../__pycache__/_resources.cpython-312.pyc | Bin 0 -> 952 bytes .../__pycache__/_signals.cpython-312.pyc | Bin 0 -> 1395 bytes .../__pycache__/_sockets.cpython-312.pyc | Bin 0 -> 40651 bytes .../__pycache__/_streams.cpython-312.pyc | Bin 0 -> 2348 bytes .../__pycache__/_subprocesses.cpython-312.pyc | Bin 0 -> 9499 bytes .../_synchronization.cpython-312.pyc | Bin 0 -> 33135 bytes .../_core/__pycache__/_tasks.cpython-312.pyc | Bin 0 -> 7703 bytes .../__pycache__/_tempfile.cpython-312.pyc | Bin 0 -> 28059 bytes .../__pycache__/_testing.cpython-312.pyc | Bin 0 -> 3801 bytes .../__pycache__/_typedattr.cpython-312.pyc | Bin 0 -> 3849 bytes .../anyio/_core/_asyncio_selector_thread.py | 167 + .../anyio/_core/_contextmanagers.py | 200 + .../site-packages/anyio/_core/_eventloop.py | 234 + .../site-packages/anyio/_core/_exceptions.py | 156 + .../site-packages/anyio/_core/_fileio.py | 799 ++ .../site-packages/anyio/_core/_resources.py | 18 + .../site-packages/anyio/_core/_signals.py | 29 + .../site-packages/anyio/_core/_sockets.py | 1003 ++ .../site-packages/anyio/_core/_streams.py | 52 + .../anyio/_core/_subprocesses.py | 196 + .../anyio/_core/_synchronization.py | 757 ++ .../site-packages/anyio/_core/_tasks.py | 173 + .../site-packages/anyio/_core/_tempfile.py | 613 ++ .../site-packages/anyio/_core/_testing.py | 82 + .../site-packages/anyio/_core/_typedattr.py | 81 + .../site-packages/anyio/abc/__init__.py | 58 + .../abc/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 2379 bytes .../__pycache__/_eventloop.cpython-312.pyc | Bin 0 -> 16544 bytes .../__pycache__/_resources.cpython-312.pyc | Bin 0 -> 1646 bytes .../abc/__pycache__/_sockets.cpython-312.pyc | Bin 0 -> 18303 bytes .../abc/__pycache__/_streams.cpython-312.pyc | Bin 0 -> 9680 bytes .../__pycache__/_subprocesses.cpython-312.pyc | Bin 0 -> 3254 bytes .../abc/__pycache__/_tasks.cpython-312.pyc | Bin 0 -> 5153 bytes .../abc/__pycache__/_testing.cpython-312.pyc | Bin 0 -> 2849 bytes .../site-packages/anyio/abc/_eventloop.py | 409 + .../site-packages/anyio/abc/_resources.py | 33 + .../site-packages/anyio/abc/_sockets.py | 399 + .../site-packages/anyio/abc/_streams.py | 233 + .../site-packages/anyio/abc/_subprocesses.py | 79 + .../site-packages/anyio/abc/_tasks.py | 117 + .../site-packages/anyio/abc/_testing.py | 65 + .../site-packages/anyio/from_thread.py | 578 ++ .../site-packages/anyio/functools.py | 409 + .../site-packages/anyio/lowlevel.py | 196 + .../python3.12/site-packages/anyio/py.typed | 0 .../site-packages/anyio/pytest_plugin.py | 363 + .../site-packages/anyio/streams/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 201 bytes .../__pycache__/buffered.cpython-312.pyc | Bin 0 -> 9080 bytes .../streams/__pycache__/file.cpython-312.pyc | Bin 0 -> 7478 bytes .../__pycache__/memory.cpython-312.pyc | Bin 0 -> 15032 bytes .../__pycache__/stapled.cpython-312.pyc | Bin 0 -> 7601 bytes .../streams/__pycache__/text.cpython-312.pyc | Bin 0 -> 9347 bytes .../streams/__pycache__/tls.cpython-312.pyc | Bin 0 -> 20168 bytes .../site-packages/anyio/streams/buffered.py | 188 + .../site-packages/anyio/streams/file.py | 154 + .../site-packages/anyio/streams/memory.py | 325 + .../site-packages/anyio/streams/stapled.py | 147 + .../site-packages/anyio/streams/text.py | 176 + .../site-packages/anyio/streams/tls.py | 421 + .../site-packages/anyio/to_interpreter.py | 246 + .../site-packages/anyio/to_process.py | 266 + .../site-packages/anyio/to_thread.py | 78 + .../certifi-2026.2.25.dist-info/INSTALLER | 1 + .../certifi-2026.2.25.dist-info/METADATA | 78 + .../certifi-2026.2.25.dist-info/RECORD | 14 + .../certifi-2026.2.25.dist-info/WHEEL | 5 + .../licenses/LICENSE | 20 + .../certifi-2026.2.25.dist-info/top_level.txt | 1 + .../site-packages/certifi/__init__.py | 4 + .../site-packages/certifi/__main__.py | 12 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 322 bytes .../__pycache__/__main__.cpython-312.pyc | Bin 0 -> 637 bytes .../certifi/__pycache__/core.cpython-312.pyc | Bin 0 -> 2069 bytes .../site-packages/certifi/cacert.pem | 4494 +++++++++ .../python3.12/site-packages/certifi/core.py | 83 + .../python3.12/site-packages/certifi/py.typed | 0 .../click-8.3.2.dist-info/INSTALLER | 1 + .../click-8.3.2.dist-info/METADATA | 84 + .../click-8.3.2.dist-info/RECORD | 40 + .../site-packages/click-8.3.2.dist-info/WHEEL | 4 + .../licenses/LICENSE.txt | 28 + .../site-packages/click/__init__.py | 123 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 4079 bytes .../click/__pycache__/_compat.cpython-312.pyc | Bin 0 -> 24201 bytes .../__pycache__/_termui_impl.cpython-312.pyc | Bin 0 -> 31623 bytes .../__pycache__/_textwrap.cpython-312.pyc | Bin 0 -> 2432 bytes .../click/__pycache__/_utils.cpython-312.pyc | Bin 0 -> 1207 bytes .../__pycache__/_winconsole.cpython-312.pyc | Bin 0 -> 11777 bytes .../click/__pycache__/core.cpython-312.pyc | Bin 0 -> 135169 bytes .../__pycache__/decorators.cpython-312.pyc | Bin 0 -> 22144 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 14783 bytes .../__pycache__/formatting.cpython-312.pyc | Bin 0 -> 13679 bytes .../click/__pycache__/globals.cpython-312.pyc | Bin 0 -> 2972 bytes .../click/__pycache__/parser.cpython-312.pyc | Bin 0 -> 20449 bytes .../shell_completion.cpython-312.pyc | Bin 0 -> 23344 bytes .../click/__pycache__/termui.cpython-312.pyc | Bin 0 -> 34658 bytes .../click/__pycache__/testing.cpython-312.pyc | Bin 0 -> 27157 bytes .../click/__pycache__/types.cpython-312.pyc | Bin 0 -> 50045 bytes .../click/__pycache__/utils.cpython-312.pyc | Bin 0 -> 24886 bytes .../python3.12/site-packages/click/_compat.py | 622 ++ .../site-packages/click/_termui_impl.py | 852 ++ .../site-packages/click/_textwrap.py | 51 + .../python3.12/site-packages/click/_utils.py | 36 + .../site-packages/click/_winconsole.py | 296 + .../python3.12/site-packages/click/core.py | 3437 +++++++ .../site-packages/click/decorators.py | 551 + .../site-packages/click/exceptions.py | 308 + .../site-packages/click/formatting.py | 301 + .../python3.12/site-packages/click/globals.py | 67 + .../python3.12/site-packages/click/parser.py | 532 + .../python3.12/site-packages/click/py.typed | 0 .../site-packages/click/shell_completion.py | 667 ++ .../python3.12/site-packages/click/termui.py | 883 ++ .../python3.12/site-packages/click/testing.py | 574 ++ .../python3.12/site-packages/click/types.py | 1209 +++ .../python3.12/site-packages/click/utils.py | 627 ++ .../fastapi-0.135.3.dist-info/INSTALLER | 1 + .../fastapi-0.135.3.dist-info/METADATA | 623 ++ .../fastapi-0.135.3.dist-info/RECORD | 109 + .../fastapi-0.135.3.dist-info/REQUESTED | 0 .../fastapi-0.135.3.dist-info/WHEEL | 4 + .../entry_points.txt | 5 + .../licenses/LICENSE | 21 + .../fastapi/.agents/skills/fastapi/SKILL.md | 436 + .../skills/fastapi/references/dependencies.md | 142 + .../skills/fastapi/references/other-tools.md | 76 + .../skills/fastapi/references/streaming.md | 105 + .../site-packages/fastapi/__init__.py | 25 + .../site-packages/fastapi/__main__.py | 3 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1110 bytes .../__pycache__/__main__.cpython-312.pyc | Bin 0 -> 257 bytes .../__pycache__/applications.cpython-312.pyc | Bin 0 -> 88893 bytes .../__pycache__/background.cpython-312.pyc | Bin 0 -> 2438 bytes .../fastapi/__pycache__/cli.cpython-312.pyc | Bin 0 -> 671 bytes .../__pycache__/concurrency.cpython-312.pyc | Bin 0 -> 1732 bytes .../datastructures.cpython-312.pyc | Bin 0 -> 7262 bytes .../__pycache__/encoders.cpython-312.pyc | Bin 0 -> 11075 bytes .../exception_handlers.cpython-312.pyc | Bin 0 -> 2037 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 10458 bytes .../__pycache__/logger.cpython-312.pyc | Bin 0 -> 297 bytes .../param_functions.cpython-312.pyc | Bin 0 -> 40957 bytes .../__pycache__/params.cpython-312.pyc | Bin 0 -> 23556 bytes .../__pycache__/requests.cpython-312.pyc | Bin 0 -> 286 bytes .../__pycache__/responses.cpython-312.pyc | Bin 0 -> 4323 bytes .../__pycache__/routing.cpython-312.pyc | Bin 0 -> 104824 bytes .../fastapi/__pycache__/sse.cpython-312.pyc | Bin 0 -> 7312 bytes .../__pycache__/staticfiles.cpython-312.pyc | Bin 0 -> 258 bytes .../__pycache__/templating.cpython-312.pyc | Bin 0 -> 260 bytes .../__pycache__/testclient.cpython-312.pyc | Bin 0 -> 255 bytes .../fastapi/__pycache__/types.cpython-312.pyc | Bin 0 -> 800 bytes .../fastapi/__pycache__/utils.cpython-312.pyc | Bin 0 -> 5419 bytes .../__pycache__/websockets.cpython-312.pyc | Bin 0 -> 335 bytes .../site-packages/fastapi/_compat/__init__.py | 40 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1639 bytes .../__pycache__/shared.cpython-312.pyc | Bin 0 -> 9415 bytes .../_compat/__pycache__/v2.cpython-312.pyc | Bin 0 -> 19316 bytes .../site-packages/fastapi/_compat/shared.py | 214 + .../site-packages/fastapi/_compat/v2.py | 480 + .../site-packages/fastapi/applications.py | 4749 +++++++++ .../site-packages/fastapi/background.py | 61 + .../python3.12/site-packages/fastapi/cli.py | 13 + .../site-packages/fastapi/concurrency.py | 41 + .../site-packages/fastapi/datastructures.py | 186 + .../fastapi/dependencies/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 208 bytes .../__pycache__/models.cpython-312.pyc | Bin 0 -> 9161 bytes .../__pycache__/utils.cpython-312.pyc | Bin 0 -> 41013 bytes .../fastapi/dependencies/models.py | 193 + .../fastapi/dependencies/utils.py | 1057 ++ .../site-packages/fastapi/encoders.py | 347 + .../fastapi/exception_handlers.py | 34 + .../site-packages/fastapi/exceptions.py | 256 + .../site-packages/fastapi/logger.py | 3 + .../fastapi/middleware/__init__.py | 1 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 264 bytes .../asyncexitstack.cpython-312.pyc | Bin 0 -> 1516 bytes .../__pycache__/cors.cpython-312.pyc | Bin 0 -> 269 bytes .../__pycache__/gzip.cpython-312.pyc | Bin 0 -> 269 bytes .../__pycache__/httpsredirect.cpython-312.pyc | Bin 0 -> 298 bytes .../__pycache__/trustedhost.cpython-312.pyc | Bin 0 -> 292 bytes .../__pycache__/wsgi.cpython-312.pyc | Bin 0 -> 271 bytes .../fastapi/middleware/asyncexitstack.py | 18 + .../site-packages/fastapi/middleware/cors.py | 1 + .../site-packages/fastapi/middleware/gzip.py | 1 + .../fastapi/middleware/httpsredirect.py | 3 + .../fastapi/middleware/trustedhost.py | 3 + .../site-packages/fastapi/middleware/wsgi.py | 3 + .../site-packages/fastapi/openapi/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 203 bytes .../__pycache__/constants.cpython-312.pyc | Bin 0 -> 373 bytes .../openapi/__pycache__/docs.cpython-312.pyc | Bin 0 -> 12862 bytes .../__pycache__/models.cpython-312.pyc | Bin 0 -> 22367 bytes .../openapi/__pycache__/utils.cpython-312.pyc | Bin 0 -> 22721 bytes .../fastapi/openapi/constants.py | 3 + .../site-packages/fastapi/openapi/docs.py | 389 + .../site-packages/fastapi/openapi/models.py | 435 + .../site-packages/fastapi/openapi/utils.py | 606 ++ .../site-packages/fastapi/param_functions.py | 2460 +++++ .../site-packages/fastapi/params.py | 754 ++ .../python3.12/site-packages/fastapi/py.typed | 0 .../site-packages/fastapi/requests.py | 2 + .../site-packages/fastapi/responses.py | 85 + .../site-packages/fastapi/routing.py | 4956 +++++++++ .../fastapi/security/__init__.py | 15 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 860 bytes .../__pycache__/api_key.cpython-312.pyc | Bin 0 -> 10470 bytes .../security/__pycache__/base.cpython-312.pyc | Bin 0 -> 522 bytes .../security/__pycache__/http.cpython-312.pyc | Bin 0 -> 14533 bytes .../__pycache__/oauth2.cpython-312.pyc | Bin 0 -> 20548 bytes .../open_id_connect_url.cpython-312.pyc | Bin 0 -> 3749 bytes .../__pycache__/utils.cpython-312.pyc | Bin 0 -> 603 bytes .../site-packages/fastapi/security/api_key.py | 320 + .../site-packages/fastapi/security/base.py | 6 + .../site-packages/fastapi/security/http.py | 417 + .../site-packages/fastapi/security/oauth2.py | 693 ++ .../fastapi/security/open_id_connect_url.py | 94 + .../site-packages/fastapi/security/utils.py | 7 + .../python3.12/site-packages/fastapi/sse.py | 222 + .../site-packages/fastapi/staticfiles.py | 1 + .../site-packages/fastapi/templating.py | 1 + .../site-packages/fastapi/testclient.py | 1 + .../python3.12/site-packages/fastapi/types.py | 12 + .../python3.12/site-packages/fastapi/utils.py | 136 + .../site-packages/fastapi/websockets.py | 3 + .../h11-0.16.0.dist-info/INSTALLER | 1 + .../h11-0.16.0.dist-info/METADATA | 202 + .../site-packages/h11-0.16.0.dist-info/RECORD | 29 + .../site-packages/h11-0.16.0.dist-info/WHEEL | 5 + .../h11-0.16.0.dist-info/licenses/LICENSE.txt | 22 + .../h11-0.16.0.dist-info/top_level.txt | 1 + .../python3.12/site-packages/h11/__init__.py | 62 + .../h11/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1082 bytes .../h11/__pycache__/_abnf.cpython-312.pyc | Bin 0 -> 1788 bytes .../__pycache__/_connection.cpython-312.pyc | Bin 0 -> 23138 bytes .../h11/__pycache__/_events.cpython-312.pyc | Bin 0 -> 13233 bytes .../h11/__pycache__/_headers.cpython-312.pyc | Bin 0 -> 8009 bytes .../h11/__pycache__/_readers.cpython-312.pyc | Bin 0 -> 9665 bytes .../_receivebuffer.cpython-312.pyc | Bin 0 -> 4711 bytes .../h11/__pycache__/_state.cpython-312.pyc | Bin 0 -> 8475 bytes .../h11/__pycache__/_util.cpython-312.pyc | Bin 0 -> 4726 bytes .../h11/__pycache__/_version.cpython-312.pyc | Bin 0 -> 220 bytes .../h11/__pycache__/_writers.cpython-312.pyc | Bin 0 -> 6302 bytes .../lib/python3.12/site-packages/h11/_abnf.py | 132 + .../site-packages/h11/_connection.py | 659 ++ .../python3.12/site-packages/h11/_events.py | 369 + .../python3.12/site-packages/h11/_headers.py | 282 + .../python3.12/site-packages/h11/_readers.py | 250 + .../site-packages/h11/_receivebuffer.py | 153 + .../python3.12/site-packages/h11/_state.py | 365 + .../lib/python3.12/site-packages/h11/_util.py | 135 + .../python3.12/site-packages/h11/_version.py | 16 + .../python3.12/site-packages/h11/_writers.py | 145 + .../lib/python3.12/site-packages/h11/py.typed | 1 + .../httpcore-1.0.9.dist-info/INSTALLER | 1 + .../httpcore-1.0.9.dist-info/METADATA | 625 ++ .../httpcore-1.0.9.dist-info/RECORD | 68 + .../httpcore-1.0.9.dist-info/WHEEL | 4 + .../licenses/LICENSE.md | 27 + .../site-packages/httpcore/__init__.py | 141 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 3178 bytes .../httpcore/__pycache__/_api.cpython-312.pyc | Bin 0 -> 3782 bytes .../__pycache__/_exceptions.cpython-312.pyc | Bin 0 -> 3197 bytes .../__pycache__/_models.cpython-312.pyc | Bin 0 -> 23128 bytes .../httpcore/__pycache__/_ssl.cpython-312.pyc | Bin 0 -> 617 bytes .../_synchronization.cpython-312.pyc | Bin 0 -> 14192 bytes .../__pycache__/_trace.cpython-312.pyc | Bin 0 -> 5609 bytes .../__pycache__/_utils.cpython-312.pyc | Bin 0 -> 1297 bytes .../python3.12/site-packages/httpcore/_api.py | 94 + .../site-packages/httpcore/_async/__init__.py | 39 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1630 bytes .../__pycache__/connection.cpython-312.pyc | Bin 0 -> 11807 bytes .../connection_pool.cpython-312.pyc | Bin 0 -> 19687 bytes .../_async/__pycache__/http11.cpython-312.pyc | Bin 0 -> 20249 bytes .../_async/__pycache__/http2.cpython-312.pyc | Bin 0 -> 31452 bytes .../__pycache__/http_proxy.cpython-312.pyc | Bin 0 -> 18007 bytes .../__pycache__/interfaces.cpython-312.pyc | Bin 0 -> 5761 bytes .../__pycache__/socks_proxy.cpython-312.pyc | Bin 0 -> 16904 bytes .../httpcore/_async/connection.py | 222 + .../httpcore/_async/connection_pool.py | 420 + .../site-packages/httpcore/_async/http11.py | 379 + .../site-packages/httpcore/_async/http2.py | 592 ++ .../httpcore/_async/http_proxy.py | 367 + .../httpcore/_async/interfaces.py | 137 + .../httpcore/_async/socks_proxy.py | 341 + .../httpcore/_backends/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 206 bytes .../__pycache__/anyio.cpython-312.pyc | Bin 0 -> 8636 bytes .../__pycache__/auto.cpython-312.pyc | Bin 0 -> 2698 bytes .../__pycache__/base.cpython-312.pyc | Bin 0 -> 4900 bytes .../__pycache__/mock.cpython-312.pyc | Bin 0 -> 7164 bytes .../__pycache__/sync.cpython-312.pyc | Bin 0 -> 11437 bytes .../__pycache__/trio.cpython-312.pyc | Bin 0 -> 8973 bytes .../site-packages/httpcore/_backends/anyio.py | 146 + .../site-packages/httpcore/_backends/auto.py | 52 + .../site-packages/httpcore/_backends/base.py | 101 + .../site-packages/httpcore/_backends/mock.py | 143 + .../site-packages/httpcore/_backends/sync.py | 241 + .../site-packages/httpcore/_backends/trio.py | 159 + .../site-packages/httpcore/_exceptions.py | 81 + .../site-packages/httpcore/_models.py | 516 + .../python3.12/site-packages/httpcore/_ssl.py | 9 + .../site-packages/httpcore/_sync/__init__.py | 39 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1584 bytes .../__pycache__/connection.cpython-312.pyc | Bin 0 -> 10427 bytes .../connection_pool.cpython-312.pyc | Bin 0 -> 18766 bytes .../_sync/__pycache__/http11.cpython-312.pyc | Bin 0 -> 17793 bytes .../_sync/__pycache__/http2.cpython-312.pyc | Bin 0 -> 27457 bytes .../__pycache__/http_proxy.cpython-312.pyc | Bin 0 -> 17190 bytes .../__pycache__/interfaces.cpython-312.pyc | Bin 0 -> 5308 bytes .../__pycache__/socks_proxy.cpython-312.pyc | Bin 0 -> 15655 bytes .../httpcore/_sync/connection.py | 222 + .../httpcore/_sync/connection_pool.py | 420 + .../site-packages/httpcore/_sync/http11.py | 379 + .../site-packages/httpcore/_sync/http2.py | 592 ++ .../httpcore/_sync/http_proxy.py | 367 + .../httpcore/_sync/interfaces.py | 137 + .../httpcore/_sync/socks_proxy.py | 341 + .../httpcore/_synchronization.py | 318 + .../site-packages/httpcore/_trace.py | 107 + .../site-packages/httpcore/_utils.py | 37 + .../site-packages/httpcore/py.typed | 0 .../httpx-0.28.1.dist-info/INSTALLER | 1 + .../httpx-0.28.1.dist-info/METADATA | 203 + .../httpx-0.28.1.dist-info/RECORD | 55 + .../httpx-0.28.1.dist-info/REQUESTED | 0 .../httpx-0.28.1.dist-info/WHEEL | 4 + .../httpx-0.28.1.dist-info/entry_points.txt | 2 + .../licenses/LICENSE.md | 12 + .../site-packages/httpx/__init__.py | 105 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 2132 bytes .../__pycache__/__version__.cpython-312.pyc | Bin 0 -> 322 bytes .../httpx/__pycache__/_api.cpython-312.pyc | Bin 0 -> 10357 bytes .../httpx/__pycache__/_auth.cpython-312.pyc | Bin 0 -> 15609 bytes .../httpx/__pycache__/_client.cpython-312.pyc | Bin 0 -> 64194 bytes .../httpx/__pycache__/_config.cpython-312.pyc | Bin 0 -> 10990 bytes .../__pycache__/_content.cpython-312.pyc | Bin 0 -> 10415 bytes .../__pycache__/_decoders.cpython-312.pyc | Bin 0 -> 16767 bytes .../__pycache__/_exceptions.cpython-312.pyc | Bin 0 -> 12092 bytes .../httpx/__pycache__/_main.cpython-312.pyc | Bin 0 -> 20630 bytes .../httpx/__pycache__/_models.cpython-312.pyc | Bin 0 -> 58604 bytes .../__pycache__/_multipart.cpython-312.pyc | Bin 0 -> 13615 bytes .../__pycache__/_status_codes.cpython-312.pyc | Bin 0 -> 7202 bytes .../httpx/__pycache__/_types.cpython-312.pyc | Bin 0 -> 3834 bytes .../__pycache__/_urlparse.cpython-312.pyc | Bin 0 -> 17495 bytes .../httpx/__pycache__/_urls.cpython-312.pyc | Bin 0 -> 27938 bytes .../httpx/__pycache__/_utils.cpython-312.pyc | Bin 0 -> 9371 bytes .../site-packages/httpx/__version__.py | 3 + .../python3.12/site-packages/httpx/_api.py | 438 + .../python3.12/site-packages/httpx/_auth.py | 348 + .../python3.12/site-packages/httpx/_client.py | 2019 ++++ .../python3.12/site-packages/httpx/_config.py | 248 + .../site-packages/httpx/_content.py | 240 + .../site-packages/httpx/_decoders.py | 393 + .../site-packages/httpx/_exceptions.py | 379 + .../python3.12/site-packages/httpx/_main.py | 506 + .../python3.12/site-packages/httpx/_models.py | 1277 +++ .../site-packages/httpx/_multipart.py | 300 + .../site-packages/httpx/_status_codes.py | 162 + .../httpx/_transports/__init__.py | 15 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 451 bytes .../__pycache__/asgi.cpython-312.pyc | Bin 0 -> 7588 bytes .../__pycache__/base.cpython-312.pyc | Bin 0 -> 3881 bytes .../__pycache__/default.cpython-312.pyc | Bin 0 -> 17134 bytes .../__pycache__/mock.cpython-312.pyc | Bin 0 -> 1949 bytes .../__pycache__/wsgi.cpython-312.pyc | Bin 0 -> 6823 bytes .../site-packages/httpx/_transports/asgi.py | 187 + .../site-packages/httpx/_transports/base.py | 86 + .../httpx/_transports/default.py | 406 + .../site-packages/httpx/_transports/mock.py | 43 + .../site-packages/httpx/_transports/wsgi.py | 149 + .../python3.12/site-packages/httpx/_types.py | 114 + .../site-packages/httpx/_urlparse.py | 527 + .../python3.12/site-packages/httpx/_urls.py | 641 ++ .../python3.12/site-packages/httpx/_utils.py | 242 + .../python3.12/site-packages/httpx/py.typed | 0 .../idna-3.11.dist-info/INSTALLER | 1 + .../idna-3.11.dist-info/METADATA | 209 + .../site-packages/idna-3.11.dist-info/RECORD | 22 + .../site-packages/idna-3.11.dist-info/WHEEL | 4 + .../idna-3.11.dist-info/licenses/LICENSE.md | 31 + .../python3.12/site-packages/idna/__init__.py | 45 + .../idna/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 890 bytes .../idna/__pycache__/codec.cpython-312.pyc | Bin 0 -> 4990 bytes .../idna/__pycache__/compat.cpython-312.pyc | Bin 0 -> 894 bytes .../idna/__pycache__/core.cpython-312.pyc | Bin 0 -> 16202 bytes .../idna/__pycache__/idnadata.cpython-312.pyc | Bin 0 -> 100919 bytes .../__pycache__/intranges.cpython-312.pyc | Bin 0 -> 2642 bytes .../__pycache__/package_data.cpython-312.pyc | Bin 0 -> 221 bytes .../__pycache__/uts46data.cpython-312.pyc | Bin 0 -> 161849 bytes .../python3.12/site-packages/idna/codec.py | 122 + .../python3.12/site-packages/idna/compat.py | 15 + .../lib/python3.12/site-packages/idna/core.py | 437 + .../python3.12/site-packages/idna/idnadata.py | 4309 ++++++++ .../site-packages/idna/intranges.py | 57 + .../site-packages/idna/package_data.py | 1 + .../python3.12/site-packages/idna/py.typed | 0 .../site-packages/idna/uts46data.py | 8841 +++++++++++++++++ .../pip-24.0.dist-info/AUTHORS.txt | 760 ++ .../pip-24.0.dist-info/INSTALLER | 1 + .../pip-24.0.dist-info/LICENSE.txt | 20 + .../site-packages/pip-24.0.dist-info/METADATA | 88 + .../site-packages/pip-24.0.dist-info/RECORD | 1005 ++ .../pip-24.0.dist-info/REQUESTED | 0 .../site-packages/pip-24.0.dist-info/WHEEL | 5 + .../pip-24.0.dist-info/entry_points.txt | 4 + .../pip-24.0.dist-info/top_level.txt | 1 + .../python3.12/site-packages/pip/__init__.py | 13 + .../python3.12/site-packages/pip/__main__.py | 24 + .../site-packages/pip/__pip-runner__.py | 50 + .../pip/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 700 bytes .../pip/__pycache__/__main__.cpython-312.pyc | Bin 0 -> 856 bytes .../__pip-runner__.cpython-312.pyc | Bin 0 -> 2219 bytes .../site-packages/pip/_internal/__init__.py | 18 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 802 bytes .../__pycache__/build_env.cpython-312.pyc | Bin 0 -> 14309 bytes .../__pycache__/cache.cpython-312.pyc | Bin 0 -> 12680 bytes .../__pycache__/configuration.cpython-312.pyc | Bin 0 -> 17681 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 33299 bytes .../__pycache__/main.cpython-312.pyc | Bin 0 -> 685 bytes .../__pycache__/pyproject.cpython-312.pyc | Bin 0 -> 4986 bytes .../self_outdated_check.cpython-312.pyc | Bin 0 -> 10567 bytes .../__pycache__/wheel_builder.cpython-312.pyc | Bin 0 -> 13664 bytes .../site-packages/pip/_internal/build_env.py | 311 + .../site-packages/pip/_internal/cache.py | 290 + .../pip/_internal/cli/__init__.py | 4 + .../cli/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 293 bytes .../autocompletion.cpython-312.pyc | Bin 0 -> 8480 bytes .../__pycache__/base_command.cpython-312.pyc | Bin 0 -> 10470 bytes .../__pycache__/cmdoptions.cpython-312.pyc | Bin 0 -> 30389 bytes .../command_context.cpython-312.pyc | Bin 0 -> 1796 bytes .../cli/__pycache__/main.cpython-312.pyc | Bin 0 -> 2313 bytes .../__pycache__/main_parser.cpython-312.pyc | Bin 0 -> 4920 bytes .../cli/__pycache__/parser.cpython-312.pyc | Bin 0 -> 15037 bytes .../__pycache__/progress_bars.cpython-312.pyc | Bin 0 -> 2635 bytes .../__pycache__/req_command.cpython-312.pyc | Bin 0 -> 18867 bytes .../cli/__pycache__/spinners.cpython-312.pyc | Bin 0 -> 7855 bytes .../__pycache__/status_codes.cpython-312.pyc | Bin 0 -> 390 bytes .../pip/_internal/cli/autocompletion.py | 172 + .../pip/_internal/cli/base_command.py | 236 + .../pip/_internal/cli/cmdoptions.py | 1074 ++ .../pip/_internal/cli/command_context.py | 27 + .../site-packages/pip/_internal/cli/main.py | 79 + .../pip/_internal/cli/main_parser.py | 134 + .../site-packages/pip/_internal/cli/parser.py | 294 + .../pip/_internal/cli/progress_bars.py | 68 + .../pip/_internal/cli/req_command.py | 505 + .../pip/_internal/cli/spinners.py | 159 + .../pip/_internal/cli/status_codes.py | 6 + .../pip/_internal/commands/__init__.py | 132 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 4017 bytes .../__pycache__/cache.cpython-312.pyc | Bin 0 -> 9726 bytes .../__pycache__/check.cpython-312.pyc | Bin 0 -> 2105 bytes .../__pycache__/completion.cpython-312.pyc | Bin 0 -> 5207 bytes .../__pycache__/configuration.cpython-312.pyc | Bin 0 -> 13227 bytes .../__pycache__/debug.cpython-312.pyc | Bin 0 -> 10176 bytes .../__pycache__/download.cpython-312.pyc | Bin 0 -> 7604 bytes .../__pycache__/freeze.cpython-312.pyc | Bin 0 -> 4431 bytes .../commands/__pycache__/hash.cpython-312.pyc | Bin 0 -> 2998 bytes .../commands/__pycache__/help.cpython-312.pyc | Bin 0 -> 1688 bytes .../__pycache__/index.cpython-312.pyc | Bin 0 -> 6735 bytes .../__pycache__/inspect.cpython-312.pyc | Bin 0 -> 3990 bytes .../__pycache__/install.cpython-312.pyc | Bin 0 -> 28928 bytes .../commands/__pycache__/list.cpython-312.pyc | Bin 0 -> 15671 bytes .../__pycache__/search.cpython-312.pyc | Bin 0 -> 7636 bytes .../commands/__pycache__/show.cpython-312.pyc | Bin 0 -> 9743 bytes .../__pycache__/uninstall.cpython-312.pyc | Bin 0 -> 4741 bytes .../__pycache__/wheel.cpython-312.pyc | Bin 0 -> 8971 bytes .../pip/_internal/commands/cache.py | 225 + .../pip/_internal/commands/check.py | 54 + .../pip/_internal/commands/completion.py | 130 + .../pip/_internal/commands/configuration.py | 280 + .../pip/_internal/commands/debug.py | 201 + .../pip/_internal/commands/download.py | 147 + .../pip/_internal/commands/freeze.py | 109 + .../pip/_internal/commands/hash.py | 59 + .../pip/_internal/commands/help.py | 41 + .../pip/_internal/commands/index.py | 139 + .../pip/_internal/commands/inspect.py | 92 + .../pip/_internal/commands/install.py | 774 ++ .../pip/_internal/commands/list.py | 370 + .../pip/_internal/commands/search.py | 174 + .../pip/_internal/commands/show.py | 189 + .../pip/_internal/commands/uninstall.py | 113 + .../pip/_internal/commands/wheel.py | 183 + .../pip/_internal/configuration.py | 383 + .../pip/_internal/distributions/__init__.py | 21 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 956 bytes .../__pycache__/base.cpython-312.pyc | Bin 0 -> 2877 bytes .../__pycache__/installed.cpython-312.pyc | Bin 0 -> 1715 bytes .../__pycache__/sdist.cpython-312.pyc | Bin 0 -> 8503 bytes .../__pycache__/wheel.cpython-312.pyc | Bin 0 -> 2263 bytes .../pip/_internal/distributions/base.py | 51 + .../pip/_internal/distributions/installed.py | 29 + .../pip/_internal/distributions/sdist.py | 156 + .../pip/_internal/distributions/wheel.py | 40 + .../site-packages/pip/_internal/exceptions.py | 728 ++ .../pip/_internal/index/__init__.py | 2 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 247 bytes .../__pycache__/collector.cpython-312.pyc | Bin 0 -> 21901 bytes .../package_finder.cpython-312.pyc | Bin 0 -> 40750 bytes .../index/__pycache__/sources.cpython-312.pyc | Bin 0 -> 12619 bytes .../pip/_internal/index/collector.py | 507 + .../pip/_internal/index/package_finder.py | 1027 ++ .../pip/_internal/index/sources.py | 285 + .../pip/_internal/locations/__init__.py | 467 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 16791 bytes .../__pycache__/_distutils.cpython-312.pyc | Bin 0 -> 6871 bytes .../__pycache__/_sysconfig.cpython-312.pyc | Bin 0 -> 8026 bytes .../__pycache__/base.cpython-312.pyc | Bin 0 -> 3796 bytes .../pip/_internal/locations/_distutils.py | 172 + .../pip/_internal/locations/_sysconfig.py | 213 + .../pip/_internal/locations/base.py | 81 + .../site-packages/pip/_internal/main.py | 12 + .../pip/_internal/metadata/__init__.py | 128 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 5897 bytes .../__pycache__/_json.cpython-312.pyc | Bin 0 -> 2890 bytes .../metadata/__pycache__/base.cpython-312.pyc | Bin 0 -> 35727 bytes .../__pycache__/pkg_resources.cpython-312.pyc | Bin 0 -> 15805 bytes .../pip/_internal/metadata/_json.py | 84 + .../pip/_internal/metadata/base.py | 702 ++ .../_internal/metadata/importlib/__init__.py | 6 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 373 bytes .../__pycache__/_compat.cpython-312.pyc | Bin 0 -> 3348 bytes .../__pycache__/_dists.cpython-312.pyc | Bin 0 -> 13440 bytes .../__pycache__/_envs.cpython-312.pyc | Bin 0 -> 11195 bytes .../_internal/metadata/importlib/_compat.py | 55 + .../_internal/metadata/importlib/_dists.py | 227 + .../pip/_internal/metadata/importlib/_envs.py | 189 + .../pip/_internal/metadata/pkg_resources.py | 278 + .../pip/_internal/models/__init__.py | 2 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 281 bytes .../__pycache__/candidate.cpython-312.pyc | Bin 0 -> 1920 bytes .../__pycache__/direct_url.cpython-312.pyc | Bin 0 -> 11214 bytes .../format_control.cpython-312.pyc | Bin 0 -> 4242 bytes .../models/__pycache__/index.cpython-312.pyc | Bin 0 -> 1709 bytes .../installation_report.cpython-312.pyc | Bin 0 -> 2287 bytes .../models/__pycache__/link.cpython-312.pyc | Bin 0 -> 26017 bytes .../models/__pycache__/scheme.cpython-312.pyc | Bin 0 -> 1184 bytes .../__pycache__/search_scope.cpython-312.pyc | Bin 0 -> 5103 bytes .../selection_prefs.cpython-312.pyc | Bin 0 -> 1866 bytes .../__pycache__/target_python.cpython-312.pyc | Bin 0 -> 4969 bytes .../models/__pycache__/wheel.cpython-312.pyc | Bin 0 -> 5795 bytes .../pip/_internal/models/candidate.py | 30 + .../pip/_internal/models/direct_url.py | 235 + .../pip/_internal/models/format_control.py | 78 + .../pip/_internal/models/index.py | 28 + .../_internal/models/installation_report.py | 56 + .../pip/_internal/models/link.py | 579 ++ .../pip/_internal/models/scheme.py | 31 + .../pip/_internal/models/search_scope.py | 132 + .../pip/_internal/models/selection_prefs.py | 51 + .../pip/_internal/models/target_python.py | 122 + .../pip/_internal/models/wheel.py | 92 + .../pip/_internal/network/__init__.py | 2 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 269 bytes .../network/__pycache__/auth.cpython-312.pyc | Bin 0 -> 22011 bytes .../network/__pycache__/cache.cpython-312.pyc | Bin 0 -> 6533 bytes .../__pycache__/download.cpython-312.pyc | Bin 0 -> 8568 bytes .../__pycache__/lazy_wheel.cpython-312.pyc | Bin 0 -> 11678 bytes .../__pycache__/session.cpython-312.pyc | Bin 0 -> 18789 bytes .../network/__pycache__/utils.cpython-312.pyc | Bin 0 -> 2268 bytes .../__pycache__/xmlrpc.cpython-312.pyc | Bin 0 -> 2964 bytes .../pip/_internal/network/auth.py | 561 ++ .../pip/_internal/network/cache.py | 106 + .../pip/_internal/network/download.py | 186 + .../pip/_internal/network/lazy_wheel.py | 210 + .../pip/_internal/network/session.py | 520 + .../pip/_internal/network/utils.py | 96 + .../pip/_internal/network/xmlrpc.py | 62 + .../pip/_internal/operations/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 212 bytes .../__pycache__/check.cpython-312.pyc | Bin 0 -> 7594 bytes .../__pycache__/freeze.cpython-312.pyc | Bin 0 -> 10132 bytes .../__pycache__/prepare.cpython-312.pyc | Bin 0 -> 25762 bytes .../_internal/operations/build/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 218 bytes .../__pycache__/build_tracker.cpython-312.pyc | Bin 0 -> 7838 bytes .../__pycache__/metadata.cpython-312.pyc | Bin 0 -> 1895 bytes .../metadata_editable.cpython-312.pyc | Bin 0 -> 1929 bytes .../metadata_legacy.cpython-312.pyc | Bin 0 -> 3080 bytes .../build/__pycache__/wheel.cpython-312.pyc | Bin 0 -> 1699 bytes .../wheel_editable.cpython-312.pyc | Bin 0 -> 2040 bytes .../__pycache__/wheel_legacy.cpython-312.pyc | Bin 0 -> 3944 bytes .../operations/build/build_tracker.py | 139 + .../_internal/operations/build/metadata.py | 39 + .../operations/build/metadata_editable.py | 41 + .../operations/build/metadata_legacy.py | 74 + .../pip/_internal/operations/build/wheel.py | 37 + .../operations/build/wheel_editable.py | 46 + .../operations/build/wheel_legacy.py | 102 + .../pip/_internal/operations/check.py | 187 + .../pip/_internal/operations/freeze.py | 255 + .../_internal/operations/install/__init__.py | 2 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 281 bytes .../editable_legacy.cpython-312.pyc | Bin 0 -> 1832 bytes .../install/__pycache__/wheel.cpython-312.pyc | Bin 0 -> 33874 bytes .../operations/install/editable_legacy.py | 46 + .../pip/_internal/operations/install/wheel.py | 734 ++ .../pip/_internal/operations/prepare.py | 730 ++ .../site-packages/pip/_internal/pyproject.py | 179 + .../pip/_internal/req/__init__.py | 92 + .../req/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 3758 bytes .../__pycache__/constructors.cpython-312.pyc | Bin 0 -> 21597 bytes .../req/__pycache__/req_file.cpython-312.pyc | Bin 0 -> 21476 bytes .../__pycache__/req_install.cpython-312.pyc | Bin 0 -> 38429 bytes .../req/__pycache__/req_set.cpython-312.pyc | Bin 0 -> 7233 bytes .../__pycache__/req_uninstall.cpython-312.pyc | Bin 0 -> 32992 bytes .../pip/_internal/req/constructors.py | 576 ++ .../pip/_internal/req/req_file.py | 554 ++ .../pip/_internal/req/req_install.py | 923 ++ .../pip/_internal/req/req_set.py | 119 + .../pip/_internal/req/req_uninstall.py | 649 ++ .../pip/_internal/resolution/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 212 bytes .../__pycache__/base.cpython-312.pyc | Bin 0 -> 1200 bytes .../pip/_internal/resolution/base.py | 20 + .../_internal/resolution/legacy/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 219 bytes .../__pycache__/resolver.cpython-312.pyc | Bin 0 -> 22454 bytes .../_internal/resolution/legacy/resolver.py | 598 ++ .../resolution/resolvelib/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 223 bytes .../__pycache__/base.cpython-312.pyc | Bin 0 -> 8352 bytes .../__pycache__/candidates.cpython-312.pyc | Bin 0 -> 30413 bytes .../__pycache__/factory.cpython-312.pyc | Bin 0 -> 32129 bytes .../found_candidates.cpython-312.pyc | Bin 0 -> 6223 bytes .../__pycache__/provider.cpython-312.pyc | Bin 0 -> 10393 bytes .../__pycache__/reporter.cpython-312.pyc | Bin 0 -> 4950 bytes .../__pycache__/requirements.cpython-312.pyc | Bin 0 -> 11444 bytes .../__pycache__/resolver.cpython-312.pyc | Bin 0 -> 12366 bytes .../_internal/resolution/resolvelib/base.py | 141 + .../resolution/resolvelib/candidates.py | 597 ++ .../resolution/resolvelib/factory.py | 812 ++ .../resolution/resolvelib/found_candidates.py | 155 + .../resolution/resolvelib/provider.py | 255 + .../resolution/resolvelib/reporter.py | 80 + .../resolution/resolvelib/requirements.py | 166 + .../resolution/resolvelib/resolver.py | 317 + .../pip/_internal/self_outdated_check.py | 248 + .../pip/_internal/utils/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 207 bytes .../__pycache__/_jaraco_text.cpython-312.pyc | Bin 0 -> 4548 bytes .../utils/__pycache__/_log.cpython-312.pyc | Bin 0 -> 1878 bytes .../utils/__pycache__/appdirs.cpython-312.pyc | Bin 0 -> 2422 bytes .../utils/__pycache__/compat.cpython-312.pyc | Bin 0 -> 2225 bytes .../compatibility_tags.cpython-312.pyc | Bin 0 -> 5573 bytes .../__pycache__/datetime.cpython-312.pyc | Bin 0 -> 696 bytes .../__pycache__/deprecation.cpython-312.pyc | Bin 0 -> 4198 bytes .../direct_url_helpers.cpython-312.pyc | Bin 0 -> 3575 bytes .../__pycache__/egg_link.cpython-312.pyc | Bin 0 -> 3238 bytes .../__pycache__/encoding.cpython-312.pyc | Bin 0 -> 2170 bytes .../__pycache__/entrypoints.cpython-312.pyc | Bin 0 -> 4005 bytes .../__pycache__/filesystem.cpython-312.pyc | Bin 0 -> 7470 bytes .../__pycache__/filetypes.cpython-312.pyc | Bin 0 -> 1176 bytes .../utils/__pycache__/glibc.cpython-312.pyc | Bin 0 -> 2354 bytes .../utils/__pycache__/hashes.cpython-312.pyc | Bin 0 -> 7566 bytes .../utils/__pycache__/logging.cpython-312.pyc | Bin 0 -> 13569 bytes .../utils/__pycache__/misc.cpython-312.pyc | Bin 0 -> 34133 bytes .../utils/__pycache__/models.cpython-312.pyc | Bin 0 -> 2724 bytes .../__pycache__/packaging.cpython-312.pyc | Bin 0 -> 2595 bytes .../setuptools_build.cpython-312.pyc | Bin 0 -> 4562 bytes .../__pycache__/subprocess.cpython-312.pyc | Bin 0 -> 8730 bytes .../__pycache__/temp_dir.cpython-312.pyc | Bin 0 -> 12074 bytes .../__pycache__/unpacking.cpython-312.pyc | Bin 0 -> 11120 bytes .../utils/__pycache__/urls.cpython-312.pyc | Bin 0 -> 2417 bytes .../__pycache__/virtualenv.cpython-312.pyc | Bin 0 -> 4492 bytes .../utils/__pycache__/wheel.cpython-312.pyc | Bin 0 -> 5938 bytes .../pip/_internal/utils/_jaraco_text.py | 109 + .../site-packages/pip/_internal/utils/_log.py | 38 + .../pip/_internal/utils/appdirs.py | 52 + .../pip/_internal/utils/compat.py | 63 + .../pip/_internal/utils/compatibility_tags.py | 165 + .../pip/_internal/utils/datetime.py | 11 + .../pip/_internal/utils/deprecation.py | 120 + .../pip/_internal/utils/direct_url_helpers.py | 87 + .../pip/_internal/utils/egg_link.py | 80 + .../pip/_internal/utils/encoding.py | 36 + .../pip/_internal/utils/entrypoints.py | 84 + .../pip/_internal/utils/filesystem.py | 153 + .../pip/_internal/utils/filetypes.py | 27 + .../pip/_internal/utils/glibc.py | 88 + .../pip/_internal/utils/hashes.py | 151 + .../pip/_internal/utils/logging.py | 348 + .../site-packages/pip/_internal/utils/misc.py | 783 ++ .../pip/_internal/utils/models.py | 39 + .../pip/_internal/utils/packaging.py | 57 + .../pip/_internal/utils/setuptools_build.py | 146 + .../pip/_internal/utils/subprocess.py | 260 + .../pip/_internal/utils/temp_dir.py | 296 + .../pip/_internal/utils/unpacking.py | 257 + .../site-packages/pip/_internal/utils/urls.py | 62 + .../pip/_internal/utils/virtualenv.py | 104 + .../pip/_internal/utils/wheel.py | 134 + .../pip/_internal/vcs/__init__.py | 15 + .../vcs/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 546 bytes .../vcs/__pycache__/bazaar.cpython-312.pyc | Bin 0 -> 5038 bytes .../vcs/__pycache__/git.cpython-312.pyc | Bin 0 -> 19007 bytes .../vcs/__pycache__/mercurial.cpython-312.pyc | Bin 0 -> 7627 bytes .../__pycache__/subversion.cpython-312.pyc | Bin 0 -> 12499 bytes .../versioncontrol.cpython-312.pyc | Bin 0 -> 29025 bytes .../site-packages/pip/_internal/vcs/bazaar.py | 112 + .../site-packages/pip/_internal/vcs/git.py | 526 + .../pip/_internal/vcs/mercurial.py | 163 + .../pip/_internal/vcs/subversion.py | 324 + .../pip/_internal/vcs/versioncontrol.py | 705 ++ .../pip/_internal/wheel_builder.py | 354 + .../site-packages/pip/_vendor/__init__.py | 121 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 4708 bytes .../_vendor/__pycache__/six.cpython-312.pyc | Bin 0 -> 41285 bytes .../typing_extensions.cpython-312.pyc | Bin 0 -> 122065 bytes .../pip/_vendor/cachecontrol/__init__.py | 28 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 918 bytes .../__pycache__/_cmd.cpython-312.pyc | Bin 0 -> 2662 bytes .../__pycache__/adapter.cpython-312.pyc | Bin 0 -> 6480 bytes .../__pycache__/cache.cpython-312.pyc | Bin 0 -> 3825 bytes .../__pycache__/controller.cpython-312.pyc | Bin 0 -> 16183 bytes .../__pycache__/filewrapper.cpython-312.pyc | Bin 0 -> 4363 bytes .../__pycache__/heuristics.cpython-312.pyc | Bin 0 -> 6710 bytes .../__pycache__/serialize.cpython-312.pyc | Bin 0 -> 6421 bytes .../__pycache__/wrapper.cpython-312.pyc | Bin 0 -> 1690 bytes .../pip/_vendor/cachecontrol/_cmd.py | 70 + .../pip/_vendor/cachecontrol/adapter.py | 161 + .../pip/_vendor/cachecontrol/cache.py | 74 + .../_vendor/cachecontrol/caches/__init__.py | 8 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 451 bytes .../__pycache__/file_cache.cpython-312.pyc | Bin 0 -> 7726 bytes .../__pycache__/redis_cache.cpython-312.pyc | Bin 0 -> 2754 bytes .../_vendor/cachecontrol/caches/file_cache.py | 181 + .../cachecontrol/caches/redis_cache.py | 48 + .../pip/_vendor/cachecontrol/controller.py | 494 + .../pip/_vendor/cachecontrol/filewrapper.py | 119 + .../pip/_vendor/cachecontrol/heuristics.py | 154 + .../pip/_vendor/cachecontrol/serialize.py | 206 + .../pip/_vendor/cachecontrol/wrapper.py | 43 + .../pip/_vendor/certifi/__init__.py | 4 + .../pip/_vendor/certifi/__main__.py | 12 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 334 bytes .../__pycache__/__main__.cpython-312.pyc | Bin 0 -> 661 bytes .../certifi/__pycache__/core.cpython-312.pyc | Bin 0 -> 3343 bytes .../pip/_vendor/certifi/cacert.pem | 4635 +++++++++ .../site-packages/pip/_vendor/certifi/core.py | 119 + .../pip/_vendor/chardet/__init__.py | 115 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 4584 bytes .../__pycache__/big5freq.cpython-312.pyc | Bin 0 -> 27215 bytes .../__pycache__/big5prober.cpython-312.pyc | Bin 0 -> 1403 bytes .../chardistribution.cpython-312.pyc | Bin 0 -> 9654 bytes .../charsetgroupprober.cpython-312.pyc | Bin 0 -> 4138 bytes .../__pycache__/charsetprober.cpython-312.pyc | Bin 0 -> 5034 bytes .../codingstatemachine.cpython-312.pyc | Bin 0 -> 3894 bytes .../codingstatemachinedict.cpython-312.pyc | Bin 0 -> 805 bytes .../__pycache__/cp949prober.cpython-312.pyc | Bin 0 -> 1412 bytes .../chardet/__pycache__/enums.cpython-312.pyc | Bin 0 -> 3012 bytes .../__pycache__/escprober.cpython-312.pyc | Bin 0 -> 4582 bytes .../chardet/__pycache__/escsm.cpython-312.pyc | Bin 0 -> 15326 bytes .../__pycache__/eucjpprober.cpython-312.pyc | Bin 0 -> 4399 bytes .../__pycache__/euckrfreq.cpython-312.pyc | Bin 0 -> 12098 bytes .../__pycache__/euckrprober.cpython-312.pyc | Bin 0 -> 1406 bytes .../__pycache__/euctwfreq.cpython-312.pyc | Bin 0 -> 27220 bytes .../__pycache__/euctwprober.cpython-312.pyc | Bin 0 -> 1406 bytes .../__pycache__/gb2312freq.cpython-312.pyc | Bin 0 -> 19142 bytes .../__pycache__/gb2312prober.cpython-312.pyc | Bin 0 -> 1419 bytes .../__pycache__/hebrewprober.cpython-312.pyc | Bin 0 -> 5838 bytes .../__pycache__/jisfreq.cpython-312.pyc | Bin 0 -> 22171 bytes .../__pycache__/johabfreq.cpython-312.pyc | Bin 0 -> 83019 bytes .../__pycache__/johabprober.cpython-312.pyc | Bin 0 -> 1410 bytes .../__pycache__/jpcntx.cpython-312.pyc | Bin 0 -> 39565 bytes .../langbulgarianmodel.cpython-312.pyc | Bin 0 -> 83138 bytes .../langgreekmodel.cpython-312.pyc | Bin 0 -> 77004 bytes .../langhebrewmodel.cpython-312.pyc | Bin 0 -> 77515 bytes .../langhungarianmodel.cpython-312.pyc | Bin 0 -> 83092 bytes .../langrussianmodel.cpython-312.pyc | Bin 0 -> 105267 bytes .../__pycache__/langthaimodel.cpython-312.pyc | Bin 0 -> 77693 bytes .../langturkishmodel.cpython-312.pyc | Bin 0 -> 77532 bytes .../__pycache__/latin1prober.cpython-312.pyc | Bin 0 -> 7018 bytes .../macromanprober.cpython-312.pyc | Bin 0 -> 7198 bytes .../mbcharsetprober.cpython-312.pyc | Bin 0 -> 3919 bytes .../mbcsgroupprober.cpython-312.pyc | Bin 0 -> 1604 bytes .../__pycache__/mbcssm.cpython-312.pyc | Bin 0 -> 38661 bytes .../__pycache__/resultdict.cpython-312.pyc | Bin 0 -> 648 bytes .../sbcharsetprober.cpython-312.pyc | Bin 0 -> 6403 bytes .../sbcsgroupprober.cpython-312.pyc | Bin 0 -> 2373 bytes .../__pycache__/sjisprober.cpython-312.pyc | Bin 0 -> 4511 bytes .../universaldetector.cpython-312.pyc | Bin 0 -> 12285 bytes .../__pycache__/utf1632prober.cpython-312.pyc | Bin 0 -> 9995 bytes .../__pycache__/utf8prober.cpython-312.pyc | Bin 0 -> 3191 bytes .../__pycache__/version.cpython-312.pyc | Bin 0 -> 504 bytes .../pip/_vendor/chardet/big5freq.py | 386 + .../pip/_vendor/chardet/big5prober.py | 47 + .../pip/_vendor/chardet/chardistribution.py | 261 + .../pip/_vendor/chardet/charsetgroupprober.py | 106 + .../pip/_vendor/chardet/charsetprober.py | 147 + .../pip/_vendor/chardet/cli/__init__.py | 0 .../cli/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 211 bytes .../__pycache__/chardetect.cpython-312.pyc | Bin 0 -> 4028 bytes .../pip/_vendor/chardet/cli/chardetect.py | 112 + .../pip/_vendor/chardet/codingstatemachine.py | 90 + .../_vendor/chardet/codingstatemachinedict.py | 19 + .../pip/_vendor/chardet/cp949prober.py | 49 + .../pip/_vendor/chardet/enums.py | 85 + .../pip/_vendor/chardet/escprober.py | 102 + .../pip/_vendor/chardet/escsm.py | 261 + .../pip/_vendor/chardet/eucjpprober.py | 102 + .../pip/_vendor/chardet/euckrfreq.py | 196 + .../pip/_vendor/chardet/euckrprober.py | 47 + .../pip/_vendor/chardet/euctwfreq.py | 388 + .../pip/_vendor/chardet/euctwprober.py | 47 + .../pip/_vendor/chardet/gb2312freq.py | 284 + .../pip/_vendor/chardet/gb2312prober.py | 47 + .../pip/_vendor/chardet/hebrewprober.py | 316 + .../pip/_vendor/chardet/jisfreq.py | 325 + .../pip/_vendor/chardet/johabfreq.py | 2382 +++++ .../pip/_vendor/chardet/johabprober.py | 47 + .../pip/_vendor/chardet/jpcntx.py | 238 + .../pip/_vendor/chardet/langbulgarianmodel.py | 4649 +++++++++ .../pip/_vendor/chardet/langgreekmodel.py | 4397 ++++++++ .../pip/_vendor/chardet/langhebrewmodel.py | 4380 ++++++++ .../pip/_vendor/chardet/langhungarianmodel.py | 4649 +++++++++ .../pip/_vendor/chardet/langrussianmodel.py | 5725 +++++++++++ .../pip/_vendor/chardet/langthaimodel.py | 4380 ++++++++ .../pip/_vendor/chardet/langturkishmodel.py | 4380 ++++++++ .../pip/_vendor/chardet/latin1prober.py | 147 + .../pip/_vendor/chardet/macromanprober.py | 162 + .../pip/_vendor/chardet/mbcharsetprober.py | 95 + .../pip/_vendor/chardet/mbcsgroupprober.py | 57 + .../pip/_vendor/chardet/mbcssm.py | 661 ++ .../pip/_vendor/chardet/metadata/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 216 bytes .../__pycache__/languages.cpython-312.pyc | Bin 0 -> 9771 bytes .../pip/_vendor/chardet/metadata/languages.py | 352 + .../pip/_vendor/chardet/resultdict.py | 16 + .../pip/_vendor/chardet/sbcharsetprober.py | 162 + .../pip/_vendor/chardet/sbcsgroupprober.py | 88 + .../pip/_vendor/chardet/sjisprober.py | 105 + .../pip/_vendor/chardet/universaldetector.py | 362 + .../pip/_vendor/chardet/utf1632prober.py | 225 + .../pip/_vendor/chardet/utf8prober.py | 82 + .../pip/_vendor/chardet/version.py | 9 + .../pip/_vendor/colorama/__init__.py | 7 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 508 bytes .../colorama/__pycache__/ansi.cpython-312.pyc | Bin 0 -> 3966 bytes .../__pycache__/ansitowin32.cpython-312.pyc | Bin 0 -> 16437 bytes .../__pycache__/initialise.cpython-312.pyc | Bin 0 -> 3566 bytes .../__pycache__/win32.cpython-312.pyc | Bin 0 -> 8142 bytes .../__pycache__/winterm.cpython-312.pyc | Bin 0 -> 9104 bytes .../pip/_vendor/colorama/ansi.py | 102 + .../pip/_vendor/colorama/ansitowin32.py | 277 + .../pip/_vendor/colorama/initialise.py | 121 + .../pip/_vendor/colorama/tests/__init__.py | 1 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 214 bytes .../__pycache__/ansi_test.cpython-312.pyc | Bin 0 -> 5483 bytes .../ansitowin32_test.cpython-312.pyc | Bin 0 -> 18119 bytes .../initialise_test.cpython-312.pyc | Bin 0 -> 11764 bytes .../__pycache__/isatty_test.cpython-312.pyc | Bin 0 -> 4920 bytes .../tests/__pycache__/utils.cpython-312.pyc | Bin 0 -> 2504 bytes .../__pycache__/winterm_test.cpython-312.pyc | Bin 0 -> 6628 bytes .../pip/_vendor/colorama/tests/ansi_test.py | 76 + .../colorama/tests/ansitowin32_test.py | 294 + .../_vendor/colorama/tests/initialise_test.py | 189 + .../pip/_vendor/colorama/tests/isatty_test.py | 57 + .../pip/_vendor/colorama/tests/utils.py | 49 + .../_vendor/colorama/tests/winterm_test.py | 131 + .../pip/_vendor/colorama/win32.py | 180 + .../pip/_vendor/colorama/winterm.py | 195 + .../pip/_vendor/distlib/__init__.py | 33 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1285 bytes .../__pycache__/compat.cpython-312.pyc | Bin 0 -> 45621 bytes .../__pycache__/database.cpython-312.pyc | Bin 0 -> 66043 bytes .../distlib/__pycache__/index.cpython-312.pyc | Bin 0 -> 24382 bytes .../__pycache__/locators.cpython-312.pyc | Bin 0 -> 60174 bytes .../__pycache__/manifest.cpython-312.pyc | Bin 0 -> 15141 bytes .../__pycache__/markers.cpython-312.pyc | Bin 0 -> 7698 bytes .../__pycache__/metadata.cpython-312.pyc | Bin 0 -> 41815 bytes .../__pycache__/resources.cpython-312.pyc | Bin 0 -> 17341 bytes .../__pycache__/scripts.cpython-312.pyc | Bin 0 -> 19596 bytes .../distlib/__pycache__/util.cpython-312.pyc | Bin 0 -> 88272 bytes .../__pycache__/version.cpython-312.pyc | Bin 0 -> 30382 bytes .../distlib/__pycache__/wheel.cpython-312.pyc | Bin 0 -> 51877 bytes .../pip/_vendor/distlib/compat.py | 1138 +++ .../pip/_vendor/distlib/database.py | 1359 +++ .../pip/_vendor/distlib/index.py | 508 + .../pip/_vendor/distlib/locators.py | 1303 +++ .../pip/_vendor/distlib/manifest.py | 384 + .../pip/_vendor/distlib/markers.py | 167 + .../pip/_vendor/distlib/metadata.py | 1068 ++ .../pip/_vendor/distlib/resources.py | 358 + .../pip/_vendor/distlib/scripts.py | 452 + .../site-packages/pip/_vendor/distlib/util.py | 2025 ++++ .../pip/_vendor/distlib/version.py | 751 ++ .../pip/_vendor/distlib/wheel.py | 1099 ++ .../pip/_vendor/distro/__init__.py | 54 + .../pip/_vendor/distro/__main__.py | 4 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 976 bytes .../__pycache__/__main__.cpython-312.pyc | Bin 0 -> 308 bytes .../distro/__pycache__/distro.cpython-312.pyc | Bin 0 -> 53770 bytes .../pip/_vendor/distro/distro.py | 1399 +++ .../pip/_vendor/idna/__init__.py | 44 + .../idna/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 897 bytes .../idna/__pycache__/codec.cpython-312.pyc | Bin 0 -> 4649 bytes .../idna/__pycache__/compat.cpython-312.pyc | Bin 0 -> 903 bytes .../idna/__pycache__/core.cpython-312.pyc | Bin 0 -> 16039 bytes .../idna/__pycache__/idnadata.cpython-312.pyc | Bin 0 -> 99513 bytes .../__pycache__/intranges.cpython-312.pyc | Bin 0 -> 2654 bytes .../__pycache__/package_data.cpython-312.pyc | Bin 0 -> 232 bytes .../__pycache__/uts46data.cpython-312.pyc | Bin 0 -> 158886 bytes .../site-packages/pip/_vendor/idna/codec.py | 112 + .../site-packages/pip/_vendor/idna/compat.py | 13 + .../site-packages/pip/_vendor/idna/core.py | 400 + .../pip/_vendor/idna/idnadata.py | 4246 ++++++++ .../pip/_vendor/idna/intranges.py | 54 + .../pip/_vendor/idna/package_data.py | 2 + .../pip/_vendor/idna/uts46data.py | 8600 ++++++++++++++++ .../pip/_vendor/msgpack/__init__.py | 57 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1847 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 2041 bytes .../msgpack/__pycache__/ext.cpython-312.pyc | Bin 0 -> 8684 bytes .../__pycache__/fallback.cpython-312.pyc | Bin 0 -> 43592 bytes .../pip/_vendor/msgpack/exceptions.py | 48 + .../site-packages/pip/_vendor/msgpack/ext.py | 193 + .../pip/_vendor/msgpack/fallback.py | 1010 ++ .../pip/_vendor/packaging/__about__.py | 26 + .../pip/_vendor/packaging/__init__.py | 25 + .../__pycache__/__about__.cpython-312.pyc | Bin 0 -> 646 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 482 bytes .../__pycache__/_manylinux.cpython-312.pyc | Bin 0 -> 12092 bytes .../__pycache__/_musllinux.cpython-312.pyc | Bin 0 -> 6926 bytes .../__pycache__/_structures.cpython-312.pyc | Bin 0 -> 3257 bytes .../__pycache__/markers.cpython-312.pyc | Bin 0 -> 14074 bytes .../__pycache__/requirements.cpython-312.pyc | Bin 0 -> 6962 bytes .../__pycache__/specifiers.cpython-312.pyc | Bin 0 -> 31263 bytes .../__pycache__/tags.cpython-312.pyc | Bin 0 -> 18972 bytes .../__pycache__/utils.cpython-312.pyc | Bin 0 -> 5884 bytes .../__pycache__/version.cpython-312.pyc | Bin 0 -> 19955 bytes .../pip/_vendor/packaging/_manylinux.py | 301 + .../pip/_vendor/packaging/_musllinux.py | 136 + .../pip/_vendor/packaging/_structures.py | 61 + .../pip/_vendor/packaging/markers.py | 304 + .../pip/_vendor/packaging/requirements.py | 146 + .../pip/_vendor/packaging/specifiers.py | 802 ++ .../pip/_vendor/packaging/tags.py | 487 + .../pip/_vendor/packaging/utils.py | 136 + .../pip/_vendor/packaging/version.py | 504 + .../pip/_vendor/pkg_resources/__init__.py | 3361 +++++++ .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 146490 bytes .../pip/_vendor/platformdirs/__init__.py | 566 ++ .../pip/_vendor/platformdirs/__main__.py | 53 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 18045 bytes .../__pycache__/__main__.cpython-312.pyc | Bin 0 -> 1962 bytes .../__pycache__/android.cpython-312.pyc | Bin 0 -> 9460 bytes .../__pycache__/api.cpython-312.pyc | Bin 0 -> 9688 bytes .../__pycache__/macos.cpython-312.pyc | Bin 0 -> 5653 bytes .../__pycache__/unix.cpython-312.pyc | Bin 0 -> 12457 bytes .../__pycache__/version.cpython-312.pyc | Bin 0 -> 327 bytes .../__pycache__/windows.cpython-312.pyc | Bin 0 -> 13015 bytes .../pip/_vendor/platformdirs/android.py | 210 + .../pip/_vendor/platformdirs/api.py | 223 + .../pip/_vendor/platformdirs/macos.py | 91 + .../pip/_vendor/platformdirs/unix.py | 223 + .../pip/_vendor/platformdirs/version.py | 4 + .../pip/_vendor/platformdirs/windows.py | 255 + .../pip/_vendor/pygments/__init__.py | 82 + .../pip/_vendor/pygments/__main__.py | 17 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 3505 bytes .../__pycache__/__main__.cpython-312.pyc | Bin 0 -> 751 bytes .../__pycache__/cmdline.cpython-312.pyc | Bin 0 -> 26622 bytes .../__pycache__/console.cpython-312.pyc | Bin 0 -> 2643 bytes .../__pycache__/filter.cpython-312.pyc | Bin 0 -> 3249 bytes .../__pycache__/formatter.cpython-312.pyc | Bin 0 -> 4586 bytes .../__pycache__/lexer.cpython-312.pyc | Bin 0 -> 38346 bytes .../__pycache__/modeline.cpython-312.pyc | Bin 0 -> 1585 bytes .../__pycache__/plugin.cpython-312.pyc | Bin 0 -> 3413 bytes .../__pycache__/regexopt.cpython-312.pyc | Bin 0 -> 4098 bytes .../__pycache__/scanner.cpython-312.pyc | Bin 0 -> 4773 bytes .../__pycache__/sphinxext.cpython-312.pyc | Bin 0 -> 11063 bytes .../__pycache__/style.cpython-312.pyc | Bin 0 -> 6691 bytes .../__pycache__/token.cpython-312.pyc | Bin 0 -> 8159 bytes .../__pycache__/unistring.cpython-312.pyc | Bin 0 -> 33005 bytes .../pygments/__pycache__/util.cpython-312.pyc | Bin 0 -> 13998 bytes .../pip/_vendor/pygments/cmdline.py | 668 ++ .../pip/_vendor/pygments/console.py | 70 + .../pip/_vendor/pygments/filter.py | 71 + .../pip/_vendor/pygments/filters/__init__.py | 940 ++ .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 37953 bytes .../pip/_vendor/pygments/formatter.py | 124 + .../_vendor/pygments/formatters/__init__.py | 158 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 6943 bytes .../__pycache__/_mapping.cpython-312.pyc | Bin 0 -> 4232 bytes .../__pycache__/bbcode.cpython-312.pyc | Bin 0 -> 4211 bytes .../__pycache__/groff.cpython-312.pyc | Bin 0 -> 7281 bytes .../__pycache__/html.cpython-312.pyc | Bin 0 -> 40589 bytes .../__pycache__/img.cpython-312.pyc | Bin 0 -> 27060 bytes .../__pycache__/irc.cpython-312.pyc | Bin 0 -> 6082 bytes .../__pycache__/latex.cpython-312.pyc | Bin 0 -> 19971 bytes .../__pycache__/other.cpython-312.pyc | Bin 0 -> 6901 bytes .../__pycache__/pangomarkup.cpython-312.pyc | Bin 0 -> 2947 bytes .../__pycache__/rtf.cpython-312.pyc | Bin 0 -> 6143 bytes .../__pycache__/svg.cpython-312.pyc | Bin 0 -> 9083 bytes .../__pycache__/terminal.cpython-312.pyc | Bin 0 -> 5846 bytes .../__pycache__/terminal256.cpython-312.pyc | Bin 0 -> 15174 bytes .../_vendor/pygments/formatters/_mapping.py | 23 + .../pip/_vendor/pygments/formatters/bbcode.py | 108 + .../pip/_vendor/pygments/formatters/groff.py | 170 + .../pip/_vendor/pygments/formatters/html.py | 989 ++ .../pip/_vendor/pygments/formatters/img.py | 645 ++ .../pip/_vendor/pygments/formatters/irc.py | 154 + .../pip/_vendor/pygments/formatters/latex.py | 521 + .../pip/_vendor/pygments/formatters/other.py | 161 + .../pygments/formatters/pangomarkup.py | 83 + .../pip/_vendor/pygments/formatters/rtf.py | 146 + .../pip/_vendor/pygments/formatters/svg.py | 188 + .../_vendor/pygments/formatters/terminal.py | 127 + .../pygments/formatters/terminal256.py | 338 + .../pip/_vendor/pygments/lexer.py | 943 ++ .../pip/_vendor/pygments/lexers/__init__.py | 362 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 14669 bytes .../__pycache__/_mapping.cpython-312.pyc | Bin 0 -> 64421 bytes .../lexers/__pycache__/python.cpython-312.pyc | Bin 0 -> 42656 bytes .../pip/_vendor/pygments/lexers/_mapping.py | 559 ++ .../pip/_vendor/pygments/lexers/python.py | 1198 +++ .../pip/_vendor/pygments/modeline.py | 43 + .../pip/_vendor/pygments/plugin.py | 88 + .../pip/_vendor/pygments/regexopt.py | 91 + .../pip/_vendor/pygments/scanner.py | 104 + .../pip/_vendor/pygments/sphinxext.py | 217 + .../pip/_vendor/pygments/style.py | 197 + .../pip/_vendor/pygments/styles/__init__.py | 103 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 4465 bytes .../pip/_vendor/pygments/token.py | 213 + .../pip/_vendor/pygments/unistring.py | 153 + .../pip/_vendor/pygments/util.py | 330 + .../pip/_vendor/pyparsing/__init__.py | 322 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 7928 bytes .../__pycache__/actions.cpython-312.pyc | Bin 0 -> 8412 bytes .../__pycache__/common.cpython-312.pyc | Bin 0 -> 13431 bytes .../__pycache__/core.cpython-312.pyc | Bin 0 -> 267725 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 13011 bytes .../__pycache__/helpers.cpython-312.pyc | Bin 0 -> 48518 bytes .../__pycache__/results.cpython-312.pyc | Bin 0 -> 34127 bytes .../__pycache__/testing.cpython-312.pyc | Bin 0 -> 17205 bytes .../__pycache__/unicode.cpython-312.pyc | Bin 0 -> 13201 bytes .../__pycache__/util.cpython-312.pyc | Bin 0 -> 14921 bytes .../pip/_vendor/pyparsing/actions.py | 217 + .../pip/_vendor/pyparsing/common.py | 432 + .../pip/_vendor/pyparsing/core.py | 6115 ++++++++++++ .../pip/_vendor/pyparsing/diagram/__init__.py | 656 ++ .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 26830 bytes .../pip/_vendor/pyparsing/exceptions.py | 299 + .../pip/_vendor/pyparsing/helpers.py | 1100 ++ .../pip/_vendor/pyparsing/results.py | 796 ++ .../pip/_vendor/pyparsing/testing.py | 331 + .../pip/_vendor/pyparsing/unicode.py | 361 + .../pip/_vendor/pyparsing/util.py | 284 + .../pip/_vendor/pyproject_hooks/__init__.py | 23 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 630 bytes .../__pycache__/_compat.cpython-312.pyc | Bin 0 -> 391 bytes .../__pycache__/_impl.cpython-312.pyc | Bin 0 -> 14742 bytes .../pip/_vendor/pyproject_hooks/_compat.py | 8 + .../pip/_vendor/pyproject_hooks/_impl.py | 330 + .../pyproject_hooks/_in_process/__init__.py | 18 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1097 bytes .../__pycache__/_in_process.cpython-312.pyc | Bin 0 -> 14414 bytes .../_in_process/_in_process.py | 353 + .../pip/_vendor/requests/__init__.py | 182 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 5470 bytes .../__pycache__/__version__.cpython-312.pyc | Bin 0 -> 601 bytes .../_internal_utils.cpython-312.pyc | Bin 0 -> 2041 bytes .../__pycache__/adapters.cpython-312.pyc | Bin 0 -> 21297 bytes .../requests/__pycache__/api.cpython-312.pyc | Bin 0 -> 7221 bytes .../requests/__pycache__/auth.cpython-312.pyc | Bin 0 -> 13940 bytes .../__pycache__/certs.cpython-312.pyc | Bin 0 -> 939 bytes .../__pycache__/compat.cpython-312.pyc | Bin 0 -> 1524 bytes .../__pycache__/cookies.cpython-312.pyc | Bin 0 -> 25263 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 7064 bytes .../requests/__pycache__/help.cpython-312.pyc | Bin 0 -> 4329 bytes .../__pycache__/hooks.cpython-312.pyc | Bin 0 -> 1069 bytes .../__pycache__/models.cpython-312.pyc | Bin 0 -> 35465 bytes .../__pycache__/packages.cpython-312.pyc | Bin 0 -> 789 bytes .../__pycache__/sessions.cpython-312.pyc | Bin 0 -> 27774 bytes .../__pycache__/status_codes.cpython-312.pyc | Bin 0 -> 5976 bytes .../__pycache__/structures.cpython-312.pyc | Bin 0 -> 5634 bytes .../__pycache__/utils.cpython-312.pyc | Bin 0 -> 36092 bytes .../pip/_vendor/requests/__version__.py | 14 + .../pip/_vendor/requests/_internal_utils.py | 50 + .../pip/_vendor/requests/adapters.py | 538 + .../site-packages/pip/_vendor/requests/api.py | 157 + .../pip/_vendor/requests/auth.py | 315 + .../pip/_vendor/requests/certs.py | 24 + .../pip/_vendor/requests/compat.py | 67 + .../pip/_vendor/requests/cookies.py | 561 ++ .../pip/_vendor/requests/exceptions.py | 141 + .../pip/_vendor/requests/help.py | 131 + .../pip/_vendor/requests/hooks.py | 33 + .../pip/_vendor/requests/models.py | 1034 ++ .../pip/_vendor/requests/packages.py | 16 + .../pip/_vendor/requests/sessions.py | 833 ++ .../pip/_vendor/requests/status_codes.py | 128 + .../pip/_vendor/requests/structures.py | 99 + .../pip/_vendor/requests/utils.py | 1088 ++ .../pip/_vendor/resolvelib/__init__.py | 26 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 651 bytes .../__pycache__/providers.cpython-312.pyc | Bin 0 -> 6868 bytes .../__pycache__/reporters.cpython-312.pyc | Bin 0 -> 2671 bytes .../__pycache__/resolvers.cpython-312.pyc | Bin 0 -> 25914 bytes .../__pycache__/structs.cpython-312.pyc | Bin 0 -> 10523 bytes .../pip/_vendor/resolvelib/compat/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 217 bytes .../collections_abc.cpython-312.pyc | Bin 0 -> 437 bytes .../resolvelib/compat/collections_abc.py | 6 + .../pip/_vendor/resolvelib/providers.py | 133 + .../pip/_vendor/resolvelib/reporters.py | 43 + .../pip/_vendor/resolvelib/resolvers.py | 547 + .../pip/_vendor/resolvelib/structs.py | 170 + .../pip/_vendor/rich/__init__.py | 177 + .../pip/_vendor/rich/__main__.py | 274 + .../rich/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 7032 bytes .../rich/__pycache__/__main__.cpython-312.pyc | Bin 0 -> 10321 bytes .../__pycache__/_cell_widths.cpython-312.pyc | Bin 0 -> 7838 bytes .../__pycache__/_emoji_codes.cpython-312.pyc | Bin 0 -> 205993 bytes .../_emoji_replace.cpython-312.pyc | Bin 0 -> 1746 bytes .../_export_format.cpython-312.pyc | Bin 0 -> 2338 bytes .../__pycache__/_extension.cpython-312.pyc | Bin 0 -> 554 bytes .../rich/__pycache__/_fileno.cpython-312.pyc | Bin 0 -> 872 bytes .../rich/__pycache__/_inspect.cpython-312.pyc | Bin 0 -> 12094 bytes .../__pycache__/_log_render.cpython-312.pyc | Bin 0 -> 4164 bytes .../rich/__pycache__/_loop.cpython-312.pyc | Bin 0 -> 1902 bytes .../__pycache__/_null_file.cpython-312.pyc | Bin 0 -> 3637 bytes .../__pycache__/_palettes.cpython-312.pyc | Bin 0 -> 5177 bytes .../rich/__pycache__/_pick.cpython-312.pyc | Bin 0 -> 743 bytes .../rich/__pycache__/_ratio.cpython-312.pyc | Bin 0 -> 6596 bytes .../__pycache__/_spinners.cpython-312.pyc | Bin 0 -> 13196 bytes .../rich/__pycache__/_stack.cpython-312.pyc | Bin 0 -> 982 bytes .../rich/__pycache__/_timer.cpython-312.pyc | Bin 0 -> 882 bytes .../_win32_console.cpython-312.pyc | Bin 0 -> 28993 bytes .../rich/__pycache__/_windows.cpython-312.pyc | Bin 0 -> 2507 bytes .../_windows_renderer.cpython-312.pyc | Bin 0 -> 3590 bytes .../rich/__pycache__/_wrap.cpython-312.pyc | Bin 0 -> 2377 bytes .../rich/__pycache__/abc.cpython-312.pyc | Bin 0 -> 1625 bytes .../rich/__pycache__/align.cpython-312.pyc | Bin 0 -> 12339 bytes .../rich/__pycache__/ansi.cpython-312.pyc | Bin 0 -> 9123 bytes .../rich/__pycache__/bar.cpython-312.pyc | Bin 0 -> 4289 bytes .../rich/__pycache__/box.cpython-312.pyc | Bin 0 -> 11875 bytes .../rich/__pycache__/cells.cpython-312.pyc | Bin 0 -> 5635 bytes .../rich/__pycache__/color.cpython-312.pyc | Bin 0 -> 26587 bytes .../__pycache__/color_triplet.cpython-312.pyc | Bin 0 -> 1718 bytes .../rich/__pycache__/columns.cpython-312.pyc | Bin 0 -> 8604 bytes .../rich/__pycache__/console.cpython-312.pyc | Bin 0 -> 113810 bytes .../__pycache__/constrain.cpython-312.pyc | Bin 0 -> 2275 bytes .../__pycache__/containers.cpython-312.pyc | Bin 0 -> 9243 bytes .../rich/__pycache__/control.cpython-312.pyc | Bin 0 -> 10946 bytes .../default_styles.cpython-312.pyc | Bin 0 -> 10390 bytes .../rich/__pycache__/diagnose.cpython-312.pyc | Bin 0 -> 1504 bytes .../rich/__pycache__/emoji.cpython-312.pyc | Bin 0 -> 4226 bytes .../rich/__pycache__/errors.cpython-312.pyc | Bin 0 -> 1862 bytes .../__pycache__/file_proxy.cpython-312.pyc | Bin 0 -> 3594 bytes .../rich/__pycache__/filesize.cpython-312.pyc | Bin 0 -> 3099 bytes .../__pycache__/highlighter.cpython-312.pyc | Bin 0 -> 9915 bytes .../rich/__pycache__/json.cpython-312.pyc | Bin 0 -> 6052 bytes .../rich/__pycache__/jupyter.cpython-312.pyc | Bin 0 -> 5226 bytes .../rich/__pycache__/layout.cpython-312.pyc | Bin 0 -> 20237 bytes .../rich/__pycache__/live.cpython-312.pyc | Bin 0 -> 19160 bytes .../__pycache__/live_render.cpython-312.pyc | Bin 0 -> 4911 bytes .../rich/__pycache__/logging.cpython-312.pyc | Bin 0 -> 13571 bytes .../rich/__pycache__/markup.cpython-312.pyc | Bin 0 -> 9315 bytes .../rich/__pycache__/measure.cpython-312.pyc | Bin 0 -> 6393 bytes .../rich/__pycache__/padding.cpython-312.pyc | Bin 0 -> 7151 bytes .../rich/__pycache__/pager.cpython-312.pyc | Bin 0 -> 1837 bytes .../rich/__pycache__/palette.cpython-312.pyc | Bin 0 -> 5331 bytes .../rich/__pycache__/panel.cpython-312.pyc | Bin 0 -> 12114 bytes .../rich/__pycache__/pretty.cpython-312.pyc | Bin 0 -> 40073 bytes .../rich/__pycache__/progress.cpython-312.pyc | Bin 0 -> 75095 bytes .../__pycache__/progress_bar.cpython-312.pyc | Bin 0 -> 10406 bytes .../rich/__pycache__/prompt.cpython-312.pyc | Bin 0 -> 14798 bytes .../rich/__pycache__/protocol.cpython-312.pyc | Bin 0 -> 1809 bytes .../rich/__pycache__/region.cpython-312.pyc | Bin 0 -> 584 bytes .../rich/__pycache__/repr.cpython-312.pyc | Bin 0 -> 6643 bytes .../rich/__pycache__/rule.cpython-312.pyc | Bin 0 -> 6585 bytes .../rich/__pycache__/scope.cpython-312.pyc | Bin 0 -> 3847 bytes .../rich/__pycache__/screen.cpython-312.pyc | Bin 0 -> 2501 bytes .../rich/__pycache__/segment.cpython-312.pyc | Bin 0 -> 28178 bytes .../rich/__pycache__/spinner.cpython-312.pyc | Bin 0 -> 6081 bytes .../rich/__pycache__/status.cpython-312.pyc | Bin 0 -> 6085 bytes .../rich/__pycache__/style.cpython-312.pyc | Bin 0 -> 33531 bytes .../rich/__pycache__/styled.cpython-312.pyc | Bin 0 -> 2156 bytes .../rich/__pycache__/syntax.cpython-312.pyc | Bin 0 -> 39629 bytes .../rich/__pycache__/table.cpython-312.pyc | Bin 0 -> 43601 bytes .../terminal_theme.cpython-312.pyc | Bin 0 -> 3365 bytes .../rich/__pycache__/text.cpython-312.pyc | Bin 0 -> 58980 bytes .../rich/__pycache__/theme.cpython-312.pyc | Bin 0 -> 6357 bytes .../rich/__pycache__/themes.cpython-312.pyc | Bin 0 -> 331 bytes .../__pycache__/traceback.cpython-312.pyc | Bin 0 -> 31565 bytes .../rich/__pycache__/tree.cpython-312.pyc | Bin 0 -> 11456 bytes .../pip/_vendor/rich/_cell_widths.py | 451 + .../pip/_vendor/rich/_emoji_codes.py | 3610 +++++++ .../pip/_vendor/rich/_emoji_replace.py | 32 + .../pip/_vendor/rich/_export_format.py | 76 + .../pip/_vendor/rich/_extension.py | 10 + .../site-packages/pip/_vendor/rich/_fileno.py | 24 + .../pip/_vendor/rich/_inspect.py | 270 + .../pip/_vendor/rich/_log_render.py | 94 + .../site-packages/pip/_vendor/rich/_loop.py | 43 + .../pip/_vendor/rich/_null_file.py | 69 + .../pip/_vendor/rich/_palettes.py | 309 + .../site-packages/pip/_vendor/rich/_pick.py | 17 + .../site-packages/pip/_vendor/rich/_ratio.py | 160 + .../pip/_vendor/rich/_spinners.py | 482 + .../site-packages/pip/_vendor/rich/_stack.py | 16 + .../site-packages/pip/_vendor/rich/_timer.py | 19 + .../pip/_vendor/rich/_win32_console.py | 662 ++ .../pip/_vendor/rich/_windows.py | 72 + .../pip/_vendor/rich/_windows_renderer.py | 56 + .../site-packages/pip/_vendor/rich/_wrap.py | 56 + .../site-packages/pip/_vendor/rich/abc.py | 33 + .../site-packages/pip/_vendor/rich/align.py | 311 + .../site-packages/pip/_vendor/rich/ansi.py | 240 + .../site-packages/pip/_vendor/rich/bar.py | 94 + .../site-packages/pip/_vendor/rich/box.py | 517 + .../site-packages/pip/_vendor/rich/cells.py | 154 + .../site-packages/pip/_vendor/rich/color.py | 622 ++ .../pip/_vendor/rich/color_triplet.py | 38 + .../site-packages/pip/_vendor/rich/columns.py | 187 + .../site-packages/pip/_vendor/rich/console.py | 2633 +++++ .../pip/_vendor/rich/constrain.py | 37 + .../pip/_vendor/rich/containers.py | 167 + .../site-packages/pip/_vendor/rich/control.py | 225 + .../pip/_vendor/rich/default_styles.py | 190 + .../pip/_vendor/rich/diagnose.py | 37 + .../site-packages/pip/_vendor/rich/emoji.py | 96 + .../site-packages/pip/_vendor/rich/errors.py | 34 + .../pip/_vendor/rich/file_proxy.py | 57 + .../pip/_vendor/rich/filesize.py | 89 + .../pip/_vendor/rich/highlighter.py | 232 + .../site-packages/pip/_vendor/rich/json.py | 140 + .../site-packages/pip/_vendor/rich/jupyter.py | 101 + .../site-packages/pip/_vendor/rich/layout.py | 443 + .../site-packages/pip/_vendor/rich/live.py | 375 + .../pip/_vendor/rich/live_render.py | 113 + .../site-packages/pip/_vendor/rich/logging.py | 289 + .../site-packages/pip/_vendor/rich/markup.py | 246 + .../site-packages/pip/_vendor/rich/measure.py | 151 + .../site-packages/pip/_vendor/rich/padding.py | 141 + .../site-packages/pip/_vendor/rich/pager.py | 34 + .../site-packages/pip/_vendor/rich/palette.py | 100 + .../site-packages/pip/_vendor/rich/panel.py | 308 + .../site-packages/pip/_vendor/rich/pretty.py | 994 ++ .../pip/_vendor/rich/progress.py | 1702 ++++ .../pip/_vendor/rich/progress_bar.py | 224 + .../site-packages/pip/_vendor/rich/prompt.py | 376 + .../pip/_vendor/rich/protocol.py | 42 + .../site-packages/pip/_vendor/rich/region.py | 10 + .../site-packages/pip/_vendor/rich/repr.py | 149 + .../site-packages/pip/_vendor/rich/rule.py | 130 + .../site-packages/pip/_vendor/rich/scope.py | 86 + .../site-packages/pip/_vendor/rich/screen.py | 54 + .../site-packages/pip/_vendor/rich/segment.py | 739 ++ .../site-packages/pip/_vendor/rich/spinner.py | 137 + .../site-packages/pip/_vendor/rich/status.py | 132 + .../site-packages/pip/_vendor/rich/style.py | 796 ++ .../site-packages/pip/_vendor/rich/styled.py | 42 + .../site-packages/pip/_vendor/rich/syntax.py | 948 ++ .../site-packages/pip/_vendor/rich/table.py | 1002 ++ .../pip/_vendor/rich/terminal_theme.py | 153 + .../site-packages/pip/_vendor/rich/text.py | 1307 +++ .../site-packages/pip/_vendor/rich/theme.py | 115 + .../site-packages/pip/_vendor/rich/themes.py | 5 + .../pip/_vendor/rich/traceback.py | 756 ++ .../site-packages/pip/_vendor/rich/tree.py | 251 + .../site-packages/pip/_vendor/six.py | 998 ++ .../pip/_vendor/tenacity/__init__.py | 608 ++ .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 27103 bytes .../__pycache__/_asyncio.cpython-312.pyc | Bin 0 -> 4823 bytes .../__pycache__/_utils.cpython-312.pyc | Bin 0 -> 2332 bytes .../__pycache__/after.cpython-312.pyc | Bin 0 -> 1641 bytes .../__pycache__/before.cpython-312.pyc | Bin 0 -> 1481 bytes .../__pycache__/before_sleep.cpython-312.pyc | Bin 0 -> 2319 bytes .../tenacity/__pycache__/nap.cpython-312.pyc | Bin 0 -> 1429 bytes .../__pycache__/retry.cpython-312.pyc | Bin 0 -> 14298 bytes .../tenacity/__pycache__/stop.cpython-312.pyc | Bin 0 -> 5585 bytes .../__pycache__/tornadoweb.cpython-312.pyc | Bin 0 -> 2603 bytes .../tenacity/__pycache__/wait.cpython-312.pyc | Bin 0 -> 12430 bytes .../pip/_vendor/tenacity/_asyncio.py | 94 + .../pip/_vendor/tenacity/_utils.py | 76 + .../pip/_vendor/tenacity/after.py | 51 + .../pip/_vendor/tenacity/before.py | 46 + .../pip/_vendor/tenacity/before_sleep.py | 71 + .../site-packages/pip/_vendor/tenacity/nap.py | 43 + .../pip/_vendor/tenacity/retry.py | 272 + .../pip/_vendor/tenacity/stop.py | 103 + .../pip/_vendor/tenacity/tornadoweb.py | 59 + .../pip/_vendor/tenacity/wait.py | 228 + .../pip/_vendor/tomli/__init__.py | 11 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 401 bytes .../tomli/__pycache__/_parser.cpython-312.pyc | Bin 0 -> 26944 bytes .../tomli/__pycache__/_re.cpython-312.pyc | Bin 0 -> 3925 bytes .../tomli/__pycache__/_types.cpython-312.pyc | Bin 0 -> 383 bytes .../pip/_vendor/tomli/_parser.py | 691 ++ .../site-packages/pip/_vendor/tomli/_re.py | 107 + .../site-packages/pip/_vendor/tomli/_types.py | 10 + .../pip/_vendor/truststore/__init__.py | 13 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 635 bytes .../__pycache__/_api.cpython-312.pyc | Bin 0 -> 15814 bytes .../__pycache__/_macos.cpython-312.pyc | Bin 0 -> 16679 bytes .../__pycache__/_openssl.cpython-312.pyc | Bin 0 -> 2232 bytes .../_ssl_constants.cpython-312.pyc | Bin 0 -> 1116 bytes .../__pycache__/_windows.cpython-312.pyc | Bin 0 -> 15523 bytes .../pip/_vendor/truststore/_api.py | 302 + .../pip/_vendor/truststore/_macos.py | 501 + .../pip/_vendor/truststore/_openssl.py | 66 + .../pip/_vendor/truststore/_ssl_constants.py | 31 + .../pip/_vendor/truststore/_windows.py | 554 ++ .../pip/_vendor/typing_extensions.py | 3072 ++++++ .../pip/_vendor/urllib3/__init__.py | 102 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 3422 bytes .../__pycache__/_collections.cpython-312.pyc | Bin 0 -> 16505 bytes .../__pycache__/_version.cpython-312.pyc | Bin 0 -> 235 bytes .../__pycache__/connection.cpython-312.pyc | Bin 0 -> 20424 bytes .../connectionpool.cpython-312.pyc | Bin 0 -> 36459 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 13510 bytes .../__pycache__/fields.cpython-312.pyc | Bin 0 -> 10430 bytes .../__pycache__/filepost.cpython-312.pyc | Bin 0 -> 4035 bytes .../__pycache__/poolmanager.cpython-312.pyc | Bin 0 -> 20817 bytes .../__pycache__/request.cpython-312.pyc | Bin 0 -> 7311 bytes .../__pycache__/response.cpython-312.pyc | Bin 0 -> 33985 bytes .../pip/_vendor/urllib3/_collections.py | 355 + .../pip/_vendor/urllib3/_version.py | 2 + .../pip/_vendor/urllib3/connection.py | 572 ++ .../pip/_vendor/urllib3/connectionpool.py | 1137 +++ .../pip/_vendor/urllib3/contrib/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 215 bytes .../_appengine_environ.cpython-312.pyc | Bin 0 -> 1865 bytes .../__pycache__/appengine.cpython-312.pyc | Bin 0 -> 11581 bytes .../__pycache__/ntlmpool.cpython-312.pyc | Bin 0 -> 5736 bytes .../__pycache__/pyopenssl.cpython-312.pyc | Bin 0 -> 24467 bytes .../securetransport.cpython-312.pyc | Bin 0 -> 35573 bytes .../contrib/__pycache__/socks.cpython-312.pyc | Bin 0 -> 7528 bytes .../urllib3/contrib/_appengine_environ.py | 36 + .../contrib/_securetransport/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 232 bytes .../__pycache__/bindings.cpython-312.pyc | Bin 0 -> 17444 bytes .../__pycache__/low_level.cpython-312.pyc | Bin 0 -> 14818 bytes .../contrib/_securetransport/bindings.py | 519 + .../contrib/_securetransport/low_level.py | 397 + .../pip/_vendor/urllib3/contrib/appengine.py | 314 + .../pip/_vendor/urllib3/contrib/ntlmpool.py | 130 + .../pip/_vendor/urllib3/contrib/pyopenssl.py | 518 + .../urllib3/contrib/securetransport.py | 921 ++ .../pip/_vendor/urllib3/contrib/socks.py | 216 + .../pip/_vendor/urllib3/exceptions.py | 323 + .../pip/_vendor/urllib3/fields.py | 274 + .../pip/_vendor/urllib3/filepost.py | 98 + .../pip/_vendor/urllib3/packages/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 216 bytes .../packages/__pycache__/six.cpython-312.pyc | Bin 0 -> 41336 bytes .../urllib3/packages/backports/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 226 bytes .../__pycache__/makefile.cpython-312.pyc | Bin 0 -> 1842 bytes .../weakref_finalize.cpython-312.pyc | Bin 0 -> 7348 bytes .../urllib3/packages/backports/makefile.py | 51 + .../packages/backports/weakref_finalize.py | 155 + .../pip/_vendor/urllib3/packages/six.py | 1076 ++ .../pip/_vendor/urllib3/poolmanager.py | 556 ++ .../pip/_vendor/urllib3/request.py | 191 + .../pip/_vendor/urllib3/response.py | 879 ++ .../pip/_vendor/urllib3/util/__init__.py | 49 + .../util/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1163 bytes .../__pycache__/connection.cpython-312.pyc | Bin 0 -> 4773 bytes .../util/__pycache__/proxy.cpython-312.pyc | Bin 0 -> 1569 bytes .../util/__pycache__/queue.cpython-312.pyc | Bin 0 -> 1369 bytes .../util/__pycache__/request.cpython-312.pyc | Bin 0 -> 4200 bytes .../util/__pycache__/response.cpython-312.pyc | Bin 0 -> 3006 bytes .../util/__pycache__/retry.cpython-312.pyc | Bin 0 -> 21735 bytes .../util/__pycache__/ssl_.cpython-312.pyc | Bin 0 -> 15120 bytes .../ssl_match_hostname.cpython-312.pyc | Bin 0 -> 5088 bytes .../__pycache__/ssltransport.cpython-312.pyc | Bin 0 -> 10789 bytes .../util/__pycache__/timeout.cpython-312.pyc | Bin 0 -> 11156 bytes .../util/__pycache__/url.cpython-312.pyc | Bin 0 -> 15812 bytes .../util/__pycache__/wait.cpython-312.pyc | Bin 0 -> 4420 bytes .../pip/_vendor/urllib3/util/connection.py | 149 + .../pip/_vendor/urllib3/util/proxy.py | 57 + .../pip/_vendor/urllib3/util/queue.py | 22 + .../pip/_vendor/urllib3/util/request.py | 137 + .../pip/_vendor/urllib3/util/response.py | 107 + .../pip/_vendor/urllib3/util/retry.py | 622 ++ .../pip/_vendor/urllib3/util/ssl_.py | 495 + .../urllib3/util/ssl_match_hostname.py | 159 + .../pip/_vendor/urllib3/util/ssltransport.py | 221 + .../pip/_vendor/urllib3/util/timeout.py | 271 + .../pip/_vendor/urllib3/util/url.py | 435 + .../pip/_vendor/urllib3/util/wait.py | 152 + .../site-packages/pip/_vendor/vendor.txt | 24 + .../pip/_vendor/webencodings/__init__.py | 342 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 12018 bytes .../__pycache__/labels.cpython-312.pyc | Bin 0 -> 7149 bytes .../__pycache__/mklabels.cpython-312.pyc | Bin 0 -> 2716 bytes .../__pycache__/tests.cpython-312.pyc | Bin 0 -> 9268 bytes .../x_user_defined.cpython-312.pyc | Bin 0 -> 3312 bytes .../pip/_vendor/webencodings/labels.py | 231 + .../pip/_vendor/webencodings/mklabels.py | 59 + .../pip/_vendor/webencodings/tests.py | 153 + .../_vendor/webencodings/x_user_defined.py | 325 + .../lib/python3.12/site-packages/pip/py.typed | 4 + .../pydantic-2.12.5.dist-info/INSTALLER | 1 + .../pydantic-2.12.5.dist-info/METADATA | 1029 ++ .../pydantic-2.12.5.dist-info/RECORD | 217 + .../pydantic-2.12.5.dist-info/WHEEL | 4 + .../licenses/LICENSE | 21 + .../site-packages/pydantic/__init__.py | 456 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 14441 bytes .../__pycache__/_migration.cpython-312.pyc | Bin 0 -> 11034 bytes .../alias_generators.cpython-312.pyc | Bin 0 -> 3301 bytes .../__pycache__/aliases.cpython-312.pyc | Bin 0 -> 6583 bytes .../annotated_handlers.cpython-312.pyc | Bin 0 -> 5507 bytes .../class_validators.cpython-312.pyc | Bin 0 -> 381 bytes .../__pycache__/color.cpython-312.pyc | Bin 0 -> 30164 bytes .../__pycache__/config.cpython-312.pyc | Bin 0 -> 7513 bytes .../__pycache__/dataclasses.cpython-312.pyc | Bin 0 -> 17354 bytes .../datetime_parse.cpython-312.pyc | Bin 0 -> 381 bytes .../__pycache__/decorator.cpython-312.pyc | Bin 0 -> 371 bytes .../__pycache__/env_settings.cpython-312.pyc | Bin 0 -> 377 bytes .../error_wrappers.cpython-312.pyc | Bin 0 -> 381 bytes .../__pycache__/errors.cpython-312.pyc | Bin 0 -> 7642 bytes .../__pycache__/fields.cpython-312.pyc | Bin 0 -> 72955 bytes .../functional_serializers.cpython-312.pyc | Bin 0 -> 17944 bytes .../functional_validators.cpython-312.pyc | Bin 0 -> 34753 bytes .../__pycache__/generics.cpython-312.pyc | Bin 0 -> 369 bytes .../pydantic/__pycache__/json.cpython-312.pyc | Bin 0 -> 361 bytes .../__pycache__/json_schema.cpython-312.pyc | Bin 0 -> 120170 bytes .../pydantic/__pycache__/main.cpython-312.pyc | Bin 0 -> 77349 bytes .../pydantic/__pycache__/mypy.cpython-312.pyc | Bin 0 -> 61810 bytes .../__pycache__/networks.cpython-312.pyc | Bin 0 -> 50232 bytes .../__pycache__/parse.cpython-312.pyc | Bin 0 -> 363 bytes .../__pycache__/root_model.cpython-312.pyc | Bin 0 -> 7824 bytes .../__pycache__/schema.cpython-312.pyc | Bin 0 -> 365 bytes .../__pycache__/tools.cpython-312.pyc | Bin 0 -> 363 bytes .../__pycache__/type_adapter.cpython-312.pyc | Bin 0 -> 35565 bytes .../__pycache__/types.cpython-312.pyc | Bin 0 -> 96800 bytes .../__pycache__/typing.cpython-312.pyc | Bin 0 -> 361 bytes .../__pycache__/utils.cpython-312.pyc | Bin 0 -> 363 bytes .../validate_call_decorator.cpython-312.pyc | Bin 0 -> 5459 bytes .../__pycache__/validators.cpython-312.pyc | Bin 0 -> 373 bytes .../__pycache__/version.cpython-312.pyc | Bin 0 -> 4811 bytes .../__pycache__/warnings.cpython-312.pyc | Bin 0 -> 7225 bytes .../pydantic/_internal/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 206 bytes .../__pycache__/_config.cpython-312.pyc | Bin 0 -> 15673 bytes .../_core_metadata.cpython-312.pyc | Bin 0 -> 4626 bytes .../__pycache__/_core_utils.cpython-312.pyc | Bin 0 -> 7736 bytes .../__pycache__/_dataclasses.cpython-312.pyc | Bin 0 -> 13438 bytes .../__pycache__/_decorators.cpython-312.pyc | Bin 0 -> 36780 bytes .../_decorators_v1.cpython-312.pyc | Bin 0 -> 8607 bytes .../_discriminated_union.cpython-312.pyc | Bin 0 -> 20872 bytes .../_docs_extraction.cpython-312.pyc | Bin 0 -> 5319 bytes .../__pycache__/_fields.cpython-312.pyc | Bin 0 -> 24378 bytes .../__pycache__/_forward_ref.cpython-312.pyc | Bin 0 -> 1315 bytes .../_generate_schema.cpython-312.pyc | Bin 0 -> 130708 bytes .../__pycache__/_generics.cpython-312.pyc | Bin 0 -> 24366 bytes .../__pycache__/_git.cpython-312.pyc | Bin 0 -> 1521 bytes .../__pycache__/_import_utils.cpython-312.pyc | Bin 0 -> 834 bytes .../_internal_dataclass.cpython-312.pyc | Bin 0 -> 355 bytes .../_known_annotated_metadata.cpython-312.pyc | Bin 0 -> 14258 bytes .../__pycache__/_mock_val_ser.cpython-312.pyc | Bin 0 -> 11116 bytes .../_model_construction.cpython-312.pyc | Bin 0 -> 35130 bytes .../_namespace_utils.cpython-312.pyc | Bin 0 -> 12317 bytes .../__pycache__/_repr.cpython-312.pyc | Bin 0 -> 7864 bytes .../_schema_gather.cpython-312.pyc | Bin 0 -> 7706 bytes .../_schema_generation_shared.cpython-312.pyc | Bin 0 -> 6232 bytes .../__pycache__/_serializers.cpython-312.pyc | Bin 0 -> 2127 bytes .../__pycache__/_signature.cpython-312.pyc | Bin 0 -> 6775 bytes .../__pycache__/_typing_extra.cpython-312.pyc | Bin 0 -> 28258 bytes .../__pycache__/_utils.cpython-312.pyc | Bin 0 -> 19804 bytes .../_validate_call.cpython-312.pyc | Bin 0 -> 6993 bytes .../__pycache__/_validators.cpython-312.pyc | Bin 0 -> 22963 bytes .../pydantic/_internal/_config.py | 383 + .../pydantic/_internal/_core_metadata.py | 97 + .../pydantic/_internal/_core_utils.py | 174 + .../pydantic/_internal/_dataclasses.py | 315 + .../pydantic/_internal/_decorators.py | 858 ++ .../pydantic/_internal/_decorators_v1.py | 174 + .../_internal/_discriminated_union.py | 479 + .../pydantic/_internal/_docs_extraction.py | 113 + .../pydantic/_internal/_fields.py | 635 ++ .../pydantic/_internal/_forward_ref.py | 23 + .../pydantic/_internal/_generate_schema.py | 2867 ++++++ .../pydantic/_internal/_generics.py | 543 + .../site-packages/pydantic/_internal/_git.py | 27 + .../pydantic/_internal/_import_utils.py | 20 + .../pydantic/_internal/_internal_dataclass.py | 7 + .../_internal/_known_annotated_metadata.py | 401 + .../pydantic/_internal/_mock_val_ser.py | 228 + .../pydantic/_internal/_model_construction.py | 848 ++ .../pydantic/_internal/_namespace_utils.py | 293 + .../site-packages/pydantic/_internal/_repr.py | 124 + .../pydantic/_internal/_schema_gather.py | 209 + .../_internal/_schema_generation_shared.py | 125 + .../pydantic/_internal/_serializers.py | 53 + .../pydantic/_internal/_signature.py | 188 + .../pydantic/_internal/_typing_extra.py | 760 ++ .../pydantic/_internal/_utils.py | 446 + .../pydantic/_internal/_validate_call.py | 140 + .../pydantic/_internal/_validators.py | 533 + .../site-packages/pydantic/_migration.py | 316 + .../pydantic/alias_generators.py | 62 + .../site-packages/pydantic/aliases.py | 135 + .../pydantic/annotated_handlers.py | 122 + .../pydantic/class_validators.py | 5 + .../site-packages/pydantic/color.py | 604 ++ .../site-packages/pydantic/config.py | 1288 +++ .../site-packages/pydantic/dataclasses.py | 413 + .../site-packages/pydantic/datetime_parse.py | 5 + .../site-packages/pydantic/decorator.py | 5 + .../pydantic/deprecated/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 207 bytes .../class_validators.cpython-312.pyc | Bin 0 -> 11743 bytes .../__pycache__/config.cpython-312.pyc | Bin 0 -> 4084 bytes .../copy_internals.cpython-312.pyc | Bin 0 -> 8657 bytes .../__pycache__/decorator.cpython-312.pyc | Bin 0 -> 14045 bytes .../__pycache__/json.cpython-312.pyc | Bin 0 -> 6203 bytes .../__pycache__/parse.cpython-312.pyc | Bin 0 -> 3413 bytes .../__pycache__/tools.cpython-312.pyc | Bin 0 -> 3549 bytes .../pydantic/deprecated/class_validators.py | 256 + .../pydantic/deprecated/config.py | 72 + .../pydantic/deprecated/copy_internals.py | 224 + .../pydantic/deprecated/decorator.py | 284 + .../site-packages/pydantic/deprecated/json.py | 141 + .../pydantic/deprecated/parse.py | 80 + .../pydantic/deprecated/tools.py | 103 + .../site-packages/pydantic/env_settings.py | 5 + .../site-packages/pydantic/error_wrappers.py | 5 + .../site-packages/pydantic/errors.py | 189 + .../pydantic/experimental/__init__.py | 1 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 321 bytes .../arguments_schema.cpython-312.pyc | Bin 0 -> 2413 bytes .../missing_sentinel.cpython-312.pyc | Bin 0 -> 362 bytes .../__pycache__/pipeline.cpython-312.pyc | Bin 0 -> 34474 bytes .../pydantic/experimental/arguments_schema.py | 44 + .../pydantic/experimental/missing_sentinel.py | 5 + .../pydantic/experimental/pipeline.py | 654 ++ .../site-packages/pydantic/fields.py | 1834 ++++ .../pydantic/functional_serializers.py | 451 + .../pydantic/functional_validators.py | 893 ++ .../site-packages/pydantic/generics.py | 5 + .../python3.12/site-packages/pydantic/json.py | 5 + .../site-packages/pydantic/json_schema.py | 2854 ++++++ .../python3.12/site-packages/pydantic/main.py | 1819 ++++ .../python3.12/site-packages/pydantic/mypy.py | 1374 +++ .../site-packages/pydantic/networks.py | 1331 +++ .../site-packages/pydantic/parse.py | 5 + .../site-packages/pydantic/plugin/__init__.py | 193 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 8949 bytes .../__pycache__/_loader.cpython-312.pyc | Bin 0 -> 2449 bytes .../_schema_validator.cpython-312.pyc | Bin 0 -> 6949 bytes .../site-packages/pydantic/plugin/_loader.py | 58 + .../pydantic/plugin/_schema_validator.py | 140 + .../site-packages/pydantic/py.typed | 0 .../site-packages/pydantic/root_model.py | 155 + .../site-packages/pydantic/schema.py | 5 + .../site-packages/pydantic/tools.py | 5 + .../site-packages/pydantic/type_adapter.py | 795 ++ .../site-packages/pydantic/types.py | 3295 ++++++ .../site-packages/pydantic/typing.py | 5 + .../site-packages/pydantic/utils.py | 5 + .../site-packages/pydantic/v1/__init__.py | 142 + .../v1/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 2528 bytes .../_hypothesis_plugin.cpython-312.pyc | Bin 0 -> 20552 bytes .../annotated_types.cpython-312.pyc | Bin 0 -> 3883 bytes .../class_validators.cpython-312.pyc | Bin 0 -> 19682 bytes .../v1/__pycache__/color.cpython-312.pyc | Bin 0 -> 25837 bytes .../v1/__pycache__/config.cpython-312.pyc | Bin 0 -> 8410 bytes .../__pycache__/dataclasses.cpython-312.pyc | Bin 0 -> 22780 bytes .../datetime_parse.cpython-312.pyc | Bin 0 -> 10356 bytes .../v1/__pycache__/decorator.cpython-312.pyc | Bin 0 -> 13939 bytes .../__pycache__/env_settings.cpython-312.pyc | Bin 0 -> 17746 bytes .../error_wrappers.cpython-312.pyc | Bin 0 -> 8939 bytes .../v1/__pycache__/errors.cpython-312.pyc | Bin 0 -> 29608 bytes .../v1/__pycache__/fields.cpython-312.pyc | Bin 0 -> 57437 bytes .../v1/__pycache__/generics.cpython-312.pyc | Bin 0 -> 17003 bytes .../v1/__pycache__/json.cpython-312.pyc | Bin 0 -> 5240 bytes .../v1/__pycache__/main.cpython-312.pyc | Bin 0 -> 48280 bytes .../v1/__pycache__/mypy.cpython-312.pyc | Bin 0 -> 46443 bytes .../v1/__pycache__/networks.cpython-312.pyc | Bin 0 -> 29569 bytes .../v1/__pycache__/parse.cpython-312.pyc | Bin 0 -> 2757 bytes .../v1/__pycache__/schema.cpython-312.pyc | Bin 0 -> 48509 bytes .../v1/__pycache__/tools.cpython-312.pyc | Bin 0 -> 3890 bytes .../v1/__pycache__/types.cpython-312.pyc | Bin 0 -> 48512 bytes .../v1/__pycache__/typing.cpython-312.pyc | Bin 0 -> 22668 bytes .../v1/__pycache__/utils.cpython-312.pyc | Bin 0 -> 35294 bytes .../v1/__pycache__/validators.cpython-312.pyc | Bin 0 -> 30908 bytes .../v1/__pycache__/version.cpython-312.pyc | Bin 0 -> 1969 bytes .../pydantic/v1/_hypothesis_plugin.py | 391 + .../pydantic/v1/annotated_types.py | 72 + .../pydantic/v1/class_validators.py | 361 + .../site-packages/pydantic/v1/color.py | 494 + .../site-packages/pydantic/v1/config.py | 191 + .../site-packages/pydantic/v1/dataclasses.py | 500 + .../pydantic/v1/datetime_parse.py | 248 + .../site-packages/pydantic/v1/decorator.py | 264 + .../site-packages/pydantic/v1/env_settings.py | 350 + .../pydantic/v1/error_wrappers.py | 161 + .../site-packages/pydantic/v1/errors.py | 646 ++ .../site-packages/pydantic/v1/fields.py | 1253 +++ .../site-packages/pydantic/v1/generics.py | 400 + .../site-packages/pydantic/v1/json.py | 112 + .../site-packages/pydantic/v1/main.py | 1113 +++ .../site-packages/pydantic/v1/mypy.py | 949 ++ .../site-packages/pydantic/v1/networks.py | 747 ++ .../site-packages/pydantic/v1/parse.py | 66 + .../site-packages/pydantic/v1/py.typed | 0 .../site-packages/pydantic/v1/schema.py | 1163 +++ .../site-packages/pydantic/v1/tools.py | 92 + .../site-packages/pydantic/v1/types.py | 1205 +++ .../site-packages/pydantic/v1/typing.py | 614 ++ .../site-packages/pydantic/v1/utils.py | 806 ++ .../site-packages/pydantic/v1/validators.py | 768 ++ .../site-packages/pydantic/v1/version.py | 38 + .../pydantic/validate_call_decorator.py | 116 + .../site-packages/pydantic/validators.py | 5 + .../site-packages/pydantic/version.py | 113 + .../site-packages/pydantic/warnings.py | 122 + .../pydantic_core-2.41.5.dist-info/INSTALLER | 1 + .../pydantic_core-2.41.5.dist-info/METADATA | 180 + .../pydantic_core-2.41.5.dist-info/RECORD | 12 + .../pydantic_core-2.41.5.dist-info/WHEEL | 4 + .../licenses/LICENSE | 21 + .../site-packages/pydantic_core/__init__.py | 171 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 3162 bytes .../__pycache__/core_schema.cpython-312.pyc | Bin 0 -> 155149 bytes ...antic_core.cpython-312-x86_64-linux-gnu.so | Bin 0 -> 4883472 bytes .../pydantic_core/_pydantic_core.pyi | 1046 ++ .../pydantic_core/core_schema.py | 4435 +++++++++ .../site-packages/pydantic_core/py.typed | 0 .../starlette-1.0.0.dist-info/INSTALLER | 1 + .../starlette-1.0.0.dist-info/METADATA | 177 + .../starlette-1.0.0.dist-info/RECORD | 74 + .../starlette-1.0.0.dist-info/WHEEL | 4 + .../licenses/LICENSE.md | 27 + .../site-packages/starlette/__init__.py | 1 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 223 bytes .../_exception_handler.cpython-312.pyc | Bin 0 -> 3088 bytes .../__pycache__/_utils.cpython-312.pyc | Bin 0 -> 5130 bytes .../__pycache__/applications.cpython-312.pyc | Bin 0 -> 7296 bytes .../authentication.cpython-312.pyc | Bin 0 -> 7736 bytes .../__pycache__/background.cpython-312.pyc | Bin 0 -> 2550 bytes .../__pycache__/concurrency.cpython-312.pyc | Bin 0 -> 3220 bytes .../__pycache__/config.cpython-312.pyc | Bin 0 -> 7533 bytes .../__pycache__/convertors.cpython-312.pyc | Bin 0 -> 4776 bytes .../datastructures.cpython-312.pyc | Bin 0 -> 40308 bytes .../__pycache__/endpoints.cpython-312.pyc | Bin 0 -> 7960 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 2408 bytes .../__pycache__/formparsers.cpython-312.pyc | Bin 0 -> 14443 bytes .../__pycache__/requests.cpython-312.pyc | Bin 0 -> 16910 bytes .../__pycache__/responses.cpython-312.pyc | Bin 0 -> 31200 bytes .../__pycache__/routing.cpython-312.pyc | Bin 0 -> 38571 bytes .../__pycache__/schemas.cpython-312.pyc | Bin 0 -> 7092 bytes .../__pycache__/staticfiles.cpython-312.pyc | Bin 0 -> 11620 bytes .../__pycache__/status.cpython-312.pyc | Bin 0 -> 5194 bytes .../__pycache__/templating.cpython-312.pyc | Bin 0 -> 7122 bytes .../__pycache__/testclient.cpython-312.pyc | Bin 0 -> 33228 bytes .../__pycache__/types.cpython-312.pyc | Bin 0 -> 1329 bytes .../__pycache__/websockets.cpython-312.pyc | Bin 0 -> 11861 bytes .../starlette/_exception_handler.py | 65 + .../site-packages/starlette/_utils.py | 105 + .../site-packages/starlette/applications.py | 118 + .../site-packages/starlette/authentication.py | 142 + .../site-packages/starlette/background.py | 36 + .../site-packages/starlette/concurrency.py | 57 + .../site-packages/starlette/config.py | 140 + .../site-packages/starlette/convertors.py | 89 + .../site-packages/starlette/datastructures.py | 706 ++ .../site-packages/starlette/endpoints.py | 123 + .../site-packages/starlette/exceptions.py | 33 + .../site-packages/starlette/formparsers.py | 276 + .../starlette/middleware/__init__.py | 37 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 2541 bytes .../authentication.cpython-312.pyc | Bin 0 -> 2908 bytes .../__pycache__/base.cpython-312.pyc | Bin 0 -> 11898 bytes .../__pycache__/cors.cpython-312.pyc | Bin 0 -> 7863 bytes .../__pycache__/errors.cpython-312.pyc | Bin 0 -> 9949 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 4119 bytes .../__pycache__/gzip.cpython-312.pyc | Bin 0 -> 8824 bytes .../__pycache__/httpsredirect.cpython-312.pyc | Bin 0 -> 1783 bytes .../__pycache__/sessions.cpython-312.pyc | Bin 0 -> 7262 bytes .../__pycache__/trustedhost.cpython-312.pyc | Bin 0 -> 3161 bytes .../__pycache__/wsgi.cpython-312.pyc | Bin 0 -> 8650 bytes .../starlette/middleware/authentication.py | 52 + .../starlette/middleware/base.py | 244 + .../starlette/middleware/cors.py | 179 + .../starlette/middleware/errors.py | 259 + .../starlette/middleware/exceptions.py | 73 + .../starlette/middleware/gzip.py | 145 + .../starlette/middleware/httpsredirect.py | 19 + .../starlette/middleware/sessions.py | 125 + .../starlette/middleware/trustedhost.py | 60 + .../starlette/middleware/wsgi.py | 154 + .../site-packages/starlette/py.typed | 0 .../site-packages/starlette/requests.py | 337 + .../site-packages/starlette/responses.py | 568 ++ .../site-packages/starlette/routing.py | 747 ++ .../site-packages/starlette/schemas.py | 148 + .../site-packages/starlette/staticfiles.py | 220 + .../site-packages/starlette/status.py | 209 + .../site-packages/starlette/templating.py | 156 + .../site-packages/starlette/testclient.py | 739 ++ .../site-packages/starlette/types.py | 26 + .../site-packages/starlette/websockets.py | 196 + .../INSTALLER | 1 + .../METADATA | 72 + .../typing_extensions-4.15.0.dist-info/RECORD | 7 + .../typing_extensions-4.15.0.dist-info/WHEEL | 4 + .../licenses/LICENSE | 279 + .../site-packages/typing_extensions.py | 4317 ++++++++ .../INSTALLER | 1 + .../METADATA | 49 + .../typing_inspection-0.4.2.dist-info/RECORD | 13 + .../typing_inspection-0.4.2.dist-info/WHEEL | 4 + .../licenses/LICENSE | 21 + .../typing_inspection/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 205 bytes .../__pycache__/introspection.cpython-312.pyc | Bin 0 -> 17809 bytes .../typing_objects.cpython-312.pyc | Bin 0 -> 17386 bytes .../typing_inspection/introspection.py | 587 ++ .../site-packages/typing_inspection/py.typed | 0 .../typing_inspection/typing_objects.py | 607 ++ .../typing_inspection/typing_objects.pyi | 417 + .../uvicorn-0.44.0.dist-info/INSTALLER | 1 + .../uvicorn-0.44.0.dist-info/METADATA | 191 + .../uvicorn-0.44.0.dist-info/RECORD | 89 + .../uvicorn-0.44.0.dist-info/REQUESTED | 0 .../uvicorn-0.44.0.dist-info/WHEEL | 4 + .../uvicorn-0.44.0.dist-info/entry_points.txt | 2 + .../licenses/LICENSE.md | 27 + .../site-packages/uvicorn/__init__.py | 5 + .../site-packages/uvicorn/__main__.py | 4 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 393 bytes .../__pycache__/__main__.cpython-312.pyc | Bin 0 -> 313 bytes .../__pycache__/_compat.cpython-312.pyc | Bin 0 -> 4029 bytes .../__pycache__/_subprocess.cpython-312.pyc | Bin 0 -> 2956 bytes .../__pycache__/_types.cpython-312.pyc | Bin 0 -> 11419 bytes .../__pycache__/config.cpython-312.pyc | Bin 0 -> 26055 bytes .../__pycache__/importer.cpython-312.pyc | Bin 0 -> 1791 bytes .../__pycache__/logging.cpython-312.pyc | Bin 0 -> 7817 bytes .../uvicorn/__pycache__/main.cpython-312.pyc | Bin 0 -> 21384 bytes .../__pycache__/server.cpython-312.pyc | Bin 0 -> 17303 bytes .../__pycache__/workers.cpython-312.pyc | Bin 0 -> 6579 bytes .../site-packages/uvicorn/_compat.py | 91 + .../site-packages/uvicorn/_subprocess.py | 84 + .../site-packages/uvicorn/_types.py | 274 + .../site-packages/uvicorn/config.py | 551 + .../site-packages/uvicorn/importer.py | 34 + .../uvicorn/lifespan/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 204 bytes .../lifespan/__pycache__/off.cpython-312.pyc | Bin 0 -> 993 bytes .../lifespan/__pycache__/on.cpython-312.pyc | Bin 0 -> 7953 bytes .../site-packages/uvicorn/lifespan/off.py | 17 + .../site-packages/uvicorn/lifespan/on.py | 137 + .../site-packages/uvicorn/logging.py | 117 + .../site-packages/uvicorn/loops/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 201 bytes .../loops/__pycache__/asyncio.cpython-312.pyc | Bin 0 -> 733 bytes .../loops/__pycache__/auto.cpython-312.pyc | Bin 0 -> 833 bytes .../loops/__pycache__/uvloop.cpython-312.pyc | Bin 0 -> 590 bytes .../site-packages/uvicorn/loops/asyncio.py | 11 + .../site-packages/uvicorn/loops/auto.py | 17 + .../site-packages/uvicorn/loops/uvloop.py | 10 + .../python3.12/site-packages/uvicorn/main.py | 630 ++ .../uvicorn/middleware/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 206 bytes .../__pycache__/asgi2.cpython-312.pyc | Bin 0 -> 1016 bytes .../message_logger.cpython-312.pyc | Bin 0 -> 4412 bytes .../__pycache__/proxy_headers.cpython-312.pyc | Bin 0 -> 5827 bytes .../__pycache__/wsgi.cpython-312.pyc | Bin 0 -> 9956 bytes .../site-packages/uvicorn/middleware/asgi2.py | 15 + .../uvicorn/middleware/message_logger.py | 87 + .../uvicorn/middleware/proxy_headers.py | 142 + .../site-packages/uvicorn/middleware/wsgi.py | 199 + .../uvicorn/protocols/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 205 bytes .../__pycache__/utils.cpython-312.pyc | Bin 0 -> 3157 bytes .../uvicorn/protocols/http/__init__.py | 0 .../http/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 210 bytes .../http/__pycache__/auto.cpython-312.pyc | Bin 0 -> 621 bytes .../__pycache__/flow_control.cpython-312.pyc | Bin 0 -> 3051 bytes .../http/__pycache__/h11_impl.cpython-312.pyc | Bin 0 -> 27760 bytes .../httptools_impl.cpython-312.pyc | Bin 0 -> 29756 bytes .../uvicorn/protocols/http/auto.py | 15 + .../uvicorn/protocols/http/flow_control.py | 54 + .../uvicorn/protocols/http/h11_impl.py | 545 + .../uvicorn/protocols/http/httptools_impl.py | 576 ++ .../site-packages/uvicorn/protocols/utils.py | 62 + .../uvicorn/protocols/websockets/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 216 bytes .../__pycache__/auto.cpython-312.pyc | Bin 0 -> 825 bytes .../websockets_impl.cpython-312.pyc | Bin 0 -> 19955 bytes .../websockets_sansio_impl.cpython-312.pyc | Bin 0 -> 28747 bytes .../__pycache__/wsproto_impl.cpython-312.pyc | Bin 0 -> 20541 bytes .../uvicorn/protocols/websockets/auto.py | 21 + .../protocols/websockets/websockets_impl.py | 372 + .../websockets/websockets_sansio_impl.py | 477 + .../protocols/websockets/wsproto_impl.py | 360 + .../python3.12/site-packages/uvicorn/py.typed | 1 + .../site-packages/uvicorn/server.py | 346 + .../uvicorn/supervisors/__init__.py | 16 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 770 bytes .../__pycache__/basereload.cpython-312.pyc | Bin 0 -> 7057 bytes .../__pycache__/multiprocess.cpython-312.pyc | Bin 0 -> 13499 bytes .../__pycache__/statreload.cpython-312.pyc | Bin 0 -> 2851 bytes .../watchfilesreload.cpython-312.pyc | Bin 0 -> 4295 bytes .../uvicorn/supervisors/basereload.py | 125 + .../uvicorn/supervisors/multiprocess.py | 223 + .../uvicorn/supervisors/statreload.py | 52 + .../uvicorn/supervisors/watchfilesreload.py | 86 + .../site-packages/uvicorn/workers.py | 111 + venv/lib64 | 1 + venv/pyvenv.cfg | 5 + 1882 files changed, 350270 insertions(+) create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 app/main.py create mode 100644 k8s.yaml create mode 100644 requirements.txt create mode 100644 skaffold.yaml create mode 100644 venv/bin/Activate.ps1 create mode 100644 venv/bin/activate create mode 100644 venv/bin/activate.csh create mode 100644 venv/bin/activate.fish create mode 100755 venv/bin/fastapi create mode 100755 venv/bin/httpx create mode 100755 venv/bin/pip create mode 100755 venv/bin/pip3 create mode 100755 venv/bin/pip3.12 create mode 120000 venv/bin/python create mode 120000 venv/bin/python3 create mode 120000 venv/bin/python3.12 create mode 100755 venv/bin/uvicorn create mode 100644 venv/lib/python3.12/site-packages/__pycache__/typing_extensions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/annotated_doc-0.0.4.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/annotated_doc-0.0.4.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/annotated_doc-0.0.4.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/annotated_doc-0.0.4.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/annotated_doc-0.0.4.dist-info/entry_points.txt create mode 100644 venv/lib/python3.12/site-packages/annotated_doc-0.0.4.dist-info/licenses/LICENSE create mode 100644 venv/lib/python3.12/site-packages/annotated_doc/__init__.py create mode 100644 venv/lib/python3.12/site-packages/annotated_doc/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/annotated_doc/__pycache__/main.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/annotated_doc/main.py create mode 100644 venv/lib/python3.12/site-packages/annotated_doc/py.typed create mode 100644 venv/lib/python3.12/site-packages/annotated_types-0.7.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/annotated_types-0.7.0.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/annotated_types-0.7.0.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/annotated_types-0.7.0.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/annotated_types-0.7.0.dist-info/licenses/LICENSE create mode 100644 venv/lib/python3.12/site-packages/annotated_types/__init__.py create mode 100644 venv/lib/python3.12/site-packages/annotated_types/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/annotated_types/__pycache__/test_cases.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/annotated_types/py.typed create mode 100644 venv/lib/python3.12/site-packages/annotated_types/test_cases.py create mode 100644 venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/entry_points.txt create mode 100644 venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/licenses/LICENSE create mode 100644 venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/top_level.txt create mode 100644 venv/lib/python3.12/site-packages/anyio/__init__.py create mode 100644 venv/lib/python3.12/site-packages/anyio/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/__pycache__/from_thread.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/__pycache__/functools.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/__pycache__/lowlevel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/__pycache__/pytest_plugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/__pycache__/to_interpreter.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/__pycache__/to_process.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/__pycache__/to_thread.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/_backends/__init__.py create mode 100644 venv/lib/python3.12/site-packages/anyio/_backends/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/_backends/__pycache__/_asyncio.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/_backends/__pycache__/_trio.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/_backends/_asyncio.py create mode 100644 venv/lib/python3.12/site-packages/anyio/_backends/_trio.py create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/__init__.py create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_asyncio_selector_thread.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_contextmanagers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_eventloop.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_exceptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_fileio.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_resources.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_signals.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_sockets.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_streams.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_subprocesses.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_synchronization.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_tasks.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_tempfile.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_testing.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_typedattr.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/_asyncio_selector_thread.py create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/_contextmanagers.py create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/_eventloop.py create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/_exceptions.py create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/_fileio.py create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/_resources.py create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/_signals.py create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/_sockets.py create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/_streams.py create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/_subprocesses.py create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/_synchronization.py create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/_tasks.py create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/_tempfile.py create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/_testing.py create mode 100644 venv/lib/python3.12/site-packages/anyio/_core/_typedattr.py create mode 100644 venv/lib/python3.12/site-packages/anyio/abc/__init__.py create mode 100644 venv/lib/python3.12/site-packages/anyio/abc/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/abc/__pycache__/_eventloop.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/abc/__pycache__/_resources.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/abc/__pycache__/_sockets.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/abc/__pycache__/_streams.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/abc/__pycache__/_subprocesses.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/abc/__pycache__/_tasks.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/abc/__pycache__/_testing.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/abc/_eventloop.py create mode 100644 venv/lib/python3.12/site-packages/anyio/abc/_resources.py create mode 100644 venv/lib/python3.12/site-packages/anyio/abc/_sockets.py create mode 100644 venv/lib/python3.12/site-packages/anyio/abc/_streams.py create mode 100644 venv/lib/python3.12/site-packages/anyio/abc/_subprocesses.py create mode 100644 venv/lib/python3.12/site-packages/anyio/abc/_tasks.py create mode 100644 venv/lib/python3.12/site-packages/anyio/abc/_testing.py create mode 100644 venv/lib/python3.12/site-packages/anyio/from_thread.py create mode 100644 venv/lib/python3.12/site-packages/anyio/functools.py create mode 100644 venv/lib/python3.12/site-packages/anyio/lowlevel.py create mode 100644 venv/lib/python3.12/site-packages/anyio/py.typed create mode 100644 venv/lib/python3.12/site-packages/anyio/pytest_plugin.py create mode 100644 venv/lib/python3.12/site-packages/anyio/streams/__init__.py create mode 100644 venv/lib/python3.12/site-packages/anyio/streams/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/streams/__pycache__/buffered.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/streams/__pycache__/file.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/streams/__pycache__/memory.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/streams/__pycache__/stapled.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/streams/__pycache__/text.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/streams/__pycache__/tls.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/anyio/streams/buffered.py create mode 100644 venv/lib/python3.12/site-packages/anyio/streams/file.py create mode 100644 venv/lib/python3.12/site-packages/anyio/streams/memory.py create mode 100644 venv/lib/python3.12/site-packages/anyio/streams/stapled.py create mode 100644 venv/lib/python3.12/site-packages/anyio/streams/text.py create mode 100644 venv/lib/python3.12/site-packages/anyio/streams/tls.py create mode 100644 venv/lib/python3.12/site-packages/anyio/to_interpreter.py create mode 100644 venv/lib/python3.12/site-packages/anyio/to_process.py create mode 100644 venv/lib/python3.12/site-packages/anyio/to_thread.py create mode 100644 venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/licenses/LICENSE create mode 100644 venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/top_level.txt create mode 100644 venv/lib/python3.12/site-packages/certifi/__init__.py create mode 100644 venv/lib/python3.12/site-packages/certifi/__main__.py create mode 100644 venv/lib/python3.12/site-packages/certifi/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/certifi/__pycache__/__main__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/certifi/__pycache__/core.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/certifi/cacert.pem create mode 100644 venv/lib/python3.12/site-packages/certifi/core.py create mode 100644 venv/lib/python3.12/site-packages/certifi/py.typed create mode 100644 venv/lib/python3.12/site-packages/click-8.3.2.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/click-8.3.2.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/click-8.3.2.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/click-8.3.2.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/click-8.3.2.dist-info/licenses/LICENSE.txt create mode 100644 venv/lib/python3.12/site-packages/click/__init__.py create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/_compat.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/_termui_impl.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/_textwrap.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/_utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/_winconsole.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/core.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/decorators.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/exceptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/formatting.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/globals.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/parser.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/shell_completion.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/termui.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/testing.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/types.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/_compat.py create mode 100644 venv/lib/python3.12/site-packages/click/_termui_impl.py create mode 100644 venv/lib/python3.12/site-packages/click/_textwrap.py create mode 100644 venv/lib/python3.12/site-packages/click/_utils.py create mode 100644 venv/lib/python3.12/site-packages/click/_winconsole.py create mode 100644 venv/lib/python3.12/site-packages/click/core.py create mode 100644 venv/lib/python3.12/site-packages/click/decorators.py create mode 100644 venv/lib/python3.12/site-packages/click/exceptions.py create mode 100644 venv/lib/python3.12/site-packages/click/formatting.py create mode 100644 venv/lib/python3.12/site-packages/click/globals.py create mode 100644 venv/lib/python3.12/site-packages/click/parser.py create mode 100644 venv/lib/python3.12/site-packages/click/py.typed create mode 100644 venv/lib/python3.12/site-packages/click/shell_completion.py create mode 100644 venv/lib/python3.12/site-packages/click/termui.py create mode 100644 venv/lib/python3.12/site-packages/click/testing.py create mode 100644 venv/lib/python3.12/site-packages/click/types.py create mode 100644 venv/lib/python3.12/site-packages/click/utils.py create mode 100644 venv/lib/python3.12/site-packages/fastapi-0.135.3.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/fastapi-0.135.3.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/fastapi-0.135.3.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/fastapi-0.135.3.dist-info/REQUESTED create mode 100644 venv/lib/python3.12/site-packages/fastapi-0.135.3.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/fastapi-0.135.3.dist-info/entry_points.txt create mode 100644 venv/lib/python3.12/site-packages/fastapi-0.135.3.dist-info/licenses/LICENSE create mode 100644 venv/lib/python3.12/site-packages/fastapi/.agents/skills/fastapi/SKILL.md create mode 100644 venv/lib/python3.12/site-packages/fastapi/.agents/skills/fastapi/references/dependencies.md create mode 100644 venv/lib/python3.12/site-packages/fastapi/.agents/skills/fastapi/references/other-tools.md create mode 100644 venv/lib/python3.12/site-packages/fastapi/.agents/skills/fastapi/references/streaming.md create mode 100644 venv/lib/python3.12/site-packages/fastapi/__init__.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/__main__.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/__main__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/applications.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/background.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/cli.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/concurrency.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/datastructures.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/encoders.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/exception_handlers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/exceptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/logger.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/param_functions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/params.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/requests.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/responses.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/routing.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/sse.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/staticfiles.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/templating.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/testclient.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/types.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/__pycache__/websockets.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/_compat/__init__.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/_compat/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/_compat/__pycache__/shared.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/_compat/__pycache__/v2.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/_compat/shared.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/_compat/v2.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/applications.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/background.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/cli.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/concurrency.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/datastructures.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/dependencies/__init__.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/dependencies/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/dependencies/__pycache__/models.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/dependencies/__pycache__/utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/dependencies/models.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/dependencies/utils.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/encoders.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/exception_handlers.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/exceptions.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/logger.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/middleware/__init__.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/middleware/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/middleware/__pycache__/asyncexitstack.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/middleware/__pycache__/cors.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/middleware/__pycache__/gzip.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/middleware/__pycache__/httpsredirect.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/middleware/__pycache__/trustedhost.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/middleware/__pycache__/wsgi.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/middleware/asyncexitstack.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/middleware/cors.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/middleware/gzip.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/middleware/httpsredirect.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/middleware/trustedhost.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/middleware/wsgi.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/openapi/__init__.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/openapi/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/openapi/__pycache__/constants.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/openapi/__pycache__/docs.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/openapi/__pycache__/models.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/openapi/__pycache__/utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/openapi/constants.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/openapi/docs.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/openapi/models.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/openapi/utils.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/param_functions.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/params.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/py.typed create mode 100644 venv/lib/python3.12/site-packages/fastapi/requests.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/responses.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/routing.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/security/__init__.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/security/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/security/__pycache__/api_key.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/security/__pycache__/base.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/security/__pycache__/http.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/security/__pycache__/oauth2.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/security/__pycache__/open_id_connect_url.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/security/__pycache__/utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/fastapi/security/api_key.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/security/base.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/security/http.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/security/oauth2.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/security/open_id_connect_url.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/security/utils.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/sse.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/staticfiles.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/templating.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/testclient.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/types.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/utils.py create mode 100644 venv/lib/python3.12/site-packages/fastapi/websockets.py create mode 100644 venv/lib/python3.12/site-packages/h11-0.16.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/h11-0.16.0.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/h11-0.16.0.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/h11-0.16.0.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/h11-0.16.0.dist-info/licenses/LICENSE.txt create mode 100644 venv/lib/python3.12/site-packages/h11-0.16.0.dist-info/top_level.txt create mode 100644 venv/lib/python3.12/site-packages/h11/__init__.py create mode 100644 venv/lib/python3.12/site-packages/h11/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/h11/__pycache__/_abnf.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/h11/__pycache__/_connection.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/h11/__pycache__/_events.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/h11/__pycache__/_headers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/h11/__pycache__/_readers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/h11/__pycache__/_receivebuffer.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/h11/__pycache__/_state.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/h11/__pycache__/_util.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/h11/__pycache__/_version.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/h11/__pycache__/_writers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/h11/_abnf.py create mode 100644 venv/lib/python3.12/site-packages/h11/_connection.py create mode 100644 venv/lib/python3.12/site-packages/h11/_events.py create mode 100644 venv/lib/python3.12/site-packages/h11/_headers.py create mode 100644 venv/lib/python3.12/site-packages/h11/_readers.py create mode 100644 venv/lib/python3.12/site-packages/h11/_receivebuffer.py create mode 100644 venv/lib/python3.12/site-packages/h11/_state.py create mode 100644 venv/lib/python3.12/site-packages/h11/_util.py create mode 100644 venv/lib/python3.12/site-packages/h11/_version.py create mode 100644 venv/lib/python3.12/site-packages/h11/_writers.py create mode 100644 venv/lib/python3.12/site-packages/h11/py.typed create mode 100644 venv/lib/python3.12/site-packages/httpcore-1.0.9.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/httpcore-1.0.9.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/httpcore-1.0.9.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/httpcore-1.0.9.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/httpcore-1.0.9.dist-info/licenses/LICENSE.md create mode 100644 venv/lib/python3.12/site-packages/httpcore/__init__.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/__pycache__/_api.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/__pycache__/_exceptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/__pycache__/_models.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/__pycache__/_ssl.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/__pycache__/_synchronization.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/__pycache__/_trace.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/__pycache__/_utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_api.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_async/__init__.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_async/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_async/__pycache__/connection.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_async/__pycache__/connection_pool.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_async/__pycache__/http11.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_async/__pycache__/http2.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_async/__pycache__/http_proxy.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_async/__pycache__/interfaces.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_async/__pycache__/socks_proxy.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_async/connection.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_async/connection_pool.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_async/http11.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_async/http2.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_async/http_proxy.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_async/interfaces.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_async/socks_proxy.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_backends/__init__.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_backends/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_backends/__pycache__/anyio.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_backends/__pycache__/auto.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_backends/__pycache__/base.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_backends/__pycache__/mock.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_backends/__pycache__/sync.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_backends/__pycache__/trio.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_backends/anyio.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_backends/auto.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_backends/base.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_backends/mock.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_backends/sync.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_backends/trio.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_exceptions.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_models.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_ssl.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_sync/__init__.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_sync/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_sync/__pycache__/connection.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_sync/__pycache__/connection_pool.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_sync/__pycache__/http11.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_sync/__pycache__/http2.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_sync/__pycache__/http_proxy.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_sync/__pycache__/interfaces.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_sync/__pycache__/socks_proxy.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpcore/_sync/connection.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_sync/connection_pool.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_sync/http11.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_sync/http2.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_sync/http_proxy.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_sync/interfaces.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_sync/socks_proxy.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_synchronization.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_trace.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/_utils.py create mode 100644 venv/lib/python3.12/site-packages/httpcore/py.typed create mode 100644 venv/lib/python3.12/site-packages/httpx-0.28.1.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/httpx-0.28.1.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/httpx-0.28.1.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/httpx-0.28.1.dist-info/REQUESTED create mode 100644 venv/lib/python3.12/site-packages/httpx-0.28.1.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/httpx-0.28.1.dist-info/entry_points.txt create mode 100644 venv/lib/python3.12/site-packages/httpx-0.28.1.dist-info/licenses/LICENSE.md create mode 100644 venv/lib/python3.12/site-packages/httpx/__init__.py create mode 100644 venv/lib/python3.12/site-packages/httpx/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/__pycache__/__version__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/__pycache__/_api.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/__pycache__/_auth.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/__pycache__/_client.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/__pycache__/_config.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/__pycache__/_content.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/__pycache__/_decoders.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/__pycache__/_exceptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/__pycache__/_main.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/__pycache__/_models.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/__pycache__/_multipart.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/__pycache__/_status_codes.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/__pycache__/_types.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/__pycache__/_urlparse.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/__pycache__/_urls.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/__pycache__/_utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/__version__.py create mode 100644 venv/lib/python3.12/site-packages/httpx/_api.py create mode 100644 venv/lib/python3.12/site-packages/httpx/_auth.py create mode 100644 venv/lib/python3.12/site-packages/httpx/_client.py create mode 100644 venv/lib/python3.12/site-packages/httpx/_config.py create mode 100644 venv/lib/python3.12/site-packages/httpx/_content.py create mode 100644 venv/lib/python3.12/site-packages/httpx/_decoders.py create mode 100644 venv/lib/python3.12/site-packages/httpx/_exceptions.py create mode 100644 venv/lib/python3.12/site-packages/httpx/_main.py create mode 100644 venv/lib/python3.12/site-packages/httpx/_models.py create mode 100644 venv/lib/python3.12/site-packages/httpx/_multipart.py create mode 100644 venv/lib/python3.12/site-packages/httpx/_status_codes.py create mode 100644 venv/lib/python3.12/site-packages/httpx/_transports/__init__.py create mode 100644 venv/lib/python3.12/site-packages/httpx/_transports/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/_transports/__pycache__/asgi.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/_transports/__pycache__/base.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/_transports/__pycache__/default.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/_transports/__pycache__/mock.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/_transports/__pycache__/wsgi.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/httpx/_transports/asgi.py create mode 100644 venv/lib/python3.12/site-packages/httpx/_transports/base.py create mode 100644 venv/lib/python3.12/site-packages/httpx/_transports/default.py create mode 100644 venv/lib/python3.12/site-packages/httpx/_transports/mock.py create mode 100644 venv/lib/python3.12/site-packages/httpx/_transports/wsgi.py create mode 100644 venv/lib/python3.12/site-packages/httpx/_types.py create mode 100644 venv/lib/python3.12/site-packages/httpx/_urlparse.py create mode 100644 venv/lib/python3.12/site-packages/httpx/_urls.py create mode 100644 venv/lib/python3.12/site-packages/httpx/_utils.py create mode 100644 venv/lib/python3.12/site-packages/httpx/py.typed create mode 100644 venv/lib/python3.12/site-packages/idna-3.11.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/idna-3.11.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/idna-3.11.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/idna-3.11.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/idna-3.11.dist-info/licenses/LICENSE.md create mode 100644 venv/lib/python3.12/site-packages/idna/__init__.py create mode 100644 venv/lib/python3.12/site-packages/idna/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/idna/__pycache__/codec.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/idna/__pycache__/compat.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/idna/__pycache__/core.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/idna/__pycache__/idnadata.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/idna/__pycache__/intranges.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/idna/__pycache__/package_data.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/idna/__pycache__/uts46data.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/idna/codec.py create mode 100644 venv/lib/python3.12/site-packages/idna/compat.py create mode 100644 venv/lib/python3.12/site-packages/idna/core.py create mode 100644 venv/lib/python3.12/site-packages/idna/idnadata.py create mode 100644 venv/lib/python3.12/site-packages/idna/intranges.py create mode 100644 venv/lib/python3.12/site-packages/idna/package_data.py create mode 100644 venv/lib/python3.12/site-packages/idna/py.typed create mode 100644 venv/lib/python3.12/site-packages/idna/uts46data.py create mode 100644 venv/lib/python3.12/site-packages/pip-24.0.dist-info/AUTHORS.txt create mode 100644 venv/lib/python3.12/site-packages/pip-24.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/pip-24.0.dist-info/LICENSE.txt create mode 100644 venv/lib/python3.12/site-packages/pip-24.0.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/pip-24.0.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/pip-24.0.dist-info/REQUESTED create mode 100644 venv/lib/python3.12/site-packages/pip-24.0.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/pip-24.0.dist-info/entry_points.txt create mode 100644 venv/lib/python3.12/site-packages/pip-24.0.dist-info/top_level.txt create mode 100644 venv/lib/python3.12/site-packages/pip/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/__main__.py create mode 100644 venv/lib/python3.12/site-packages/pip/__pip-runner__.py create mode 100644 venv/lib/python3.12/site-packages/pip/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/__pycache__/__main__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/__pycache__/__pip-runner__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/__pycache__/build_env.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/__pycache__/cache.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/__pycache__/configuration.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/__pycache__/exceptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/__pycache__/main.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/__pycache__/pyproject.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/build_env.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cache.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/main.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/parser.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/autocompletion.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/base_command.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/cmdoptions.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/command_context.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/main.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/main_parser.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/parser.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/progress_bars.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/req_command.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/spinners.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/status_codes.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/cache.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/check.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/completion.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/debug.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/download.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/hash.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/help.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/index.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/inspect.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/install.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/list.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/search.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/show.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/cache.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/check.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/completion.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/configuration.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/debug.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/download.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/freeze.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/hash.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/help.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/index.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/inspect.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/install.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/list.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/search.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/show.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/uninstall.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/wheel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/configuration.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/distributions/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/distributions/__pycache__/base.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/distributions/base.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/distributions/installed.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/distributions/sdist.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/distributions/wheel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/exceptions.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/index/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/index/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/index/__pycache__/collector.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/index/__pycache__/sources.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/index/collector.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/index/package_finder.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/index/sources.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/locations/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/locations/__pycache__/base.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/locations/_distutils.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/locations/_sysconfig.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/locations/base.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/main.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/__pycache__/_json.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/__pycache__/base.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/_json.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/base.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/importlib/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/importlib/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/importlib/__pycache__/_compat.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/importlib/__pycache__/_dists.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/importlib/__pycache__/_envs.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/importlib/_compat.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/importlib/_dists.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/importlib/_envs.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/pkg_resources.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/candidate.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/format_control.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/index.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/installation_report.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/link.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/scheme.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/target_python.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/wheel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/candidate.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/direct_url.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/format_control.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/index.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/installation_report.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/link.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/scheme.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/search_scope.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/selection_prefs.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/target_python.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/wheel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/auth.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/cache.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/download.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/session.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/auth.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/cache.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/download.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/lazy_wheel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/session.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/utils.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/xmlrpc.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/__pycache__/check.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/build_tracker.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/metadata_editable.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/wheel_editable.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/build_tracker.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/metadata.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/metadata_editable.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/metadata_legacy.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/wheel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/wheel_editable.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/wheel_legacy.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/check.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/freeze.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/install/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/install/editable_legacy.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/install/wheel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/prepare.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/pyproject.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/__pycache__/constructors.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/__pycache__/req_file.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/__pycache__/req_install.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/__pycache__/req_set.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/constructors.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/req_file.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/req_install.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/req_set.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/req_uninstall.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/__pycache__/base.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/base.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/legacy/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/legacy/__pycache__/resolver.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/legacy/resolver.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/base.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/candidates.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/factory.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/provider.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/reporter.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/requirements.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/resolver.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/self_outdated_check.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/_jaraco_text.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/_log.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/compat.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/datetime.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/logging.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/misc.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/models.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/urls.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/_jaraco_text.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/_log.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/appdirs.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/compat.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/compatibility_tags.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/datetime.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/deprecation.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/direct_url_helpers.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/egg_link.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/encoding.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/entrypoints.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/filesystem.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/filetypes.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/glibc.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/hashes.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/logging.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/misc.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/models.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/packaging.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/setuptools_build.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/subprocess.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/temp_dir.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/unpacking.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/urls.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/virtualenv.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/wheel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/git.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/bazaar.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/git.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/mercurial.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/subversion.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/versioncontrol.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/wheel_builder.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/__pycache__/six.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/__pycache__/typing_extensions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/_cmd.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/adapter.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/cache.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/caches/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/controller.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/filewrapper.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/heuristics.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/serialize.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/wrapper.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/certifi/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/certifi/__main__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/certifi/cacert.pem create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/certifi/core.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachinedict.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/johabfreq.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/johabprober.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/macromanprober.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/resultdict.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/utf1632prober.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/big5freq.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/big5prober.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/chardistribution.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/charsetgroupprober.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/charsetprober.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/cli/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/cli/chardetect.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/codingstatemachine.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/codingstatemachinedict.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/cp949prober.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/enums.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/escprober.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/escsm.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/eucjpprober.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/euckrfreq.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/euckrprober.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/euctwfreq.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/euctwprober.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/gb2312freq.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/gb2312prober.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/hebrewprober.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/jisfreq.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/johabfreq.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/johabprober.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/jpcntx.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/langbulgarianmodel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/langgreekmodel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/langhebrewmodel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/langhungarianmodel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/langrussianmodel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/langthaimodel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/langturkishmodel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/latin1prober.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/macromanprober.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/mbcharsetprober.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/mbcsgroupprober.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/mbcssm.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/metadata/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/metadata/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/metadata/__pycache__/languages.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/metadata/languages.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/resultdict.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/sbcharsetprober.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/sbcsgroupprober.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/sjisprober.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/universaldetector.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/utf1632prober.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/utf8prober.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/chardet/version.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/ansi.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/ansitowin32.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/initialise.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/tests/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/tests/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/tests/__pycache__/ansi_test.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/tests/__pycache__/ansitowin32_test.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/tests/__pycache__/initialise_test.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/tests/__pycache__/isatty_test.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/tests/__pycache__/utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/tests/__pycache__/winterm_test.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/tests/ansi_test.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/tests/ansitowin32_test.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/tests/initialise_test.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/tests/isatty_test.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/tests/utils.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/tests/winterm_test.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/win32.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/colorama/winterm.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/compat.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/database.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/index.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/locators.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/manifest.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/markers.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/metadata.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/resources.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/scripts.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/util.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/version.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/wheel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distro/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distro/__main__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distro/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distro/__pycache__/__main__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distro/__pycache__/distro.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distro/distro.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/core.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/codec.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/compat.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/core.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/idnadata.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/intranges.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/package_data.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/uts46data.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/msgpack/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/msgpack/__pycache__/ext.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/msgpack/exceptions.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/msgpack/ext.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/msgpack/fallback.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__about__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/_manylinux.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/_manylinux.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/_musllinux.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/_structures.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/markers.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/requirements.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/specifiers.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/tags.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/utils.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/version.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pkg_resources/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__main__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/__main__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/android.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/api.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/macos.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/unix.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/version.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/windows.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/android.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/api.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/macos.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/unix.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/version.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/windows.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__main__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/__main__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/cmdline.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/console.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/filter.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/formatter.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/lexer.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/modeline.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/plugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/regexopt.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/scanner.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/sphinxext.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/style.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/token.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/unistring.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/util.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/cmdline.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/console.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/filter.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/filters/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/filters/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatter.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/_mapping.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/bbcode.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/groff.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/html.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/img.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/irc.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/latex.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/other.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/pangomarkup.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/rtf.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/svg.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal256.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/_mapping.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/bbcode.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/groff.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/html.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/img.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/irc.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/latex.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/other.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/pangomarkup.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/rtf.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/svg.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/terminal.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/terminal256.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/lexer.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/lexers/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/lexers/__pycache__/python.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/lexers/_mapping.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/lexers/python.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/modeline.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/plugin.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/regexopt.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/scanner.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/sphinxext.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/style.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/styles/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/styles/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/token.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/unistring.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/util.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/actions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/common.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/core.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/exceptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/helpers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/results.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/testing.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/unicode.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/util.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/actions.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/common.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/core.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/diagram/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/diagram/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/exceptions.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/helpers.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/results.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/testing.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/unicode.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/util.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/__pycache__/_compat.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/__pycache__/_impl.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_compat.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_impl.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/__pycache__/_in_process.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/api.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/help.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/models.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__version__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/_internal_utils.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/adapters.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/api.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/auth.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/certs.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/compat.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/cookies.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/exceptions.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/help.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/hooks.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/models.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/packages.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/sessions.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/status_codes.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/structures.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/utils.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/__pycache__/providers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/__pycache__/reporters.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/__pycache__/resolvers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/__pycache__/structs.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/compat/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/compat/collections_abc.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/providers.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/reporters.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/resolvers.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/structs.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__main__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/__main__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_cell_widths.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_emoji_codes.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_emoji_replace.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_export_format.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_extension.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_fileno.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_inspect.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_log_render.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_loop.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_null_file.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_palettes.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_pick.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_ratio.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_spinners.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_stack.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_timer.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_win32_console.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_windows.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_windows_renderer.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_wrap.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/abc.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/align.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/ansi.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/bar.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/box.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/cells.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/color.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/color_triplet.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/columns.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/console.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/constrain.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/containers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/control.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/default_styles.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/diagnose.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/emoji.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/errors.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/file_proxy.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/filesize.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/highlighter.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/json.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/jupyter.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/layout.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/live.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/live_render.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/logging.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/markup.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/measure.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/padding.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/pager.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/palette.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/panel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/pretty.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/progress.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/progress_bar.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/prompt.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/protocol.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/region.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/repr.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/rule.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/scope.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/screen.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/segment.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/spinner.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/status.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/style.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/styled.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/syntax.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/table.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/terminal_theme.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/text.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/theme.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/themes.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/traceback.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/tree.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_cell_widths.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_emoji_codes.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_emoji_replace.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_export_format.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_extension.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_fileno.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_inspect.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_log_render.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_loop.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_null_file.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_palettes.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_pick.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_ratio.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_spinners.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_stack.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_timer.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_win32_console.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_windows.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_windows_renderer.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_wrap.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/abc.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/align.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/ansi.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/bar.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/box.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/cells.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/color.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/color_triplet.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/columns.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/console.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/constrain.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/containers.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/control.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/default_styles.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/diagnose.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/emoji.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/errors.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/file_proxy.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/filesize.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/highlighter.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/json.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/jupyter.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/layout.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/live.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/live_render.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/logging.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/markup.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/measure.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/padding.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/pager.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/palette.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/panel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/pretty.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/progress.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/progress_bar.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/prompt.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/protocol.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/region.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/repr.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/rule.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/scope.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/screen.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/segment.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/spinner.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/status.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/style.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/styled.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/syntax.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/table.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/terminal_theme.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/text.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/theme.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/themes.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/traceback.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/tree.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/six.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/_asyncio.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/_utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/after.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/before.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/before_sleep.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/nap.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/retry.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/stop.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/tornadoweb.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/wait.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tenacity/_asyncio.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tenacity/_utils.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tenacity/after.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tenacity/before.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tenacity/before_sleep.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tenacity/nap.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tenacity/retry.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tenacity/stop.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tenacity/tornadoweb.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tenacity/wait.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tomli/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tomli/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tomli/__pycache__/_parser.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tomli/__pycache__/_re.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tomli/__pycache__/_types.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tomli/_parser.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tomli/_re.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tomli/_types.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/__pycache__/_api.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/__pycache__/_macos.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/__pycache__/_openssl.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/__pycache__/_ssl_constants.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/__pycache__/_windows.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/_api.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/_macos.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/_openssl.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/_ssl_constants.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/_windows.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/typing_extensions.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/_version.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/_collections.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/_version.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/connection.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/connectionpool.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/appengine.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/securetransport.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/socks.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/exceptions.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/fields.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/filepost.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/weakref_finalize.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/weakref_finalize.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/six.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/poolmanager.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/request.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/response.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/proxy.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/connection.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/proxy.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/queue.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/request.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/response.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/retry.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/ssl_.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/ssltransport.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/timeout.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/url.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/wait.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/vendor.txt create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/webencodings/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/webencodings/labels.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/webencodings/mklabels.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/webencodings/tests.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/webencodings/x_user_defined.py create mode 100644 venv/lib/python3.12/site-packages/pip/py.typed create mode 100644 venv/lib/python3.12/site-packages/pydantic-2.12.5.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/pydantic-2.12.5.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/pydantic-2.12.5.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/pydantic-2.12.5.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/pydantic-2.12.5.dist-info/licenses/LICENSE create mode 100644 venv/lib/python3.12/site-packages/pydantic/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/_migration.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/alias_generators.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/aliases.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/annotated_handlers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/class_validators.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/color.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/config.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/dataclasses.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/datetime_parse.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/decorator.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/env_settings.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/error_wrappers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/errors.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/fields.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/functional_serializers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/functional_validators.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/generics.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/json.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/json_schema.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/main.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/mypy.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/networks.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/parse.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/root_model.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/schema.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/tools.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/type_adapter.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/types.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/typing.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/validate_call_decorator.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/validators.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/version.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/__pycache__/warnings.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_config.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_core_metadata.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_core_utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_dataclasses.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_decorators.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_decorators_v1.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_discriminated_union.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_docs_extraction.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_fields.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_forward_ref.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_generate_schema.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_generics.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_git.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_import_utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_internal_dataclass.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_known_annotated_metadata.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_mock_val_ser.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_model_construction.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_namespace_utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_repr.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_schema_gather.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_schema_generation_shared.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_serializers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_signature.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_typing_extra.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_validate_call.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/__pycache__/_validators.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_config.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_core_metadata.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_core_utils.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_dataclasses.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_decorators.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_decorators_v1.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_discriminated_union.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_docs_extraction.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_fields.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_forward_ref.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_generate_schema.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_generics.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_git.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_import_utils.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_internal_dataclass.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_known_annotated_metadata.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_mock_val_ser.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_model_construction.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_namespace_utils.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_repr.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_schema_gather.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_schema_generation_shared.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_serializers.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_signature.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_typing_extra.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_utils.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_validate_call.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_internal/_validators.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/_migration.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/alias_generators.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/aliases.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/annotated_handlers.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/class_validators.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/color.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/config.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/dataclasses.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/datetime_parse.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/decorator.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/deprecated/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/deprecated/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/deprecated/__pycache__/class_validators.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/deprecated/__pycache__/config.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/deprecated/__pycache__/copy_internals.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/deprecated/__pycache__/decorator.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/deprecated/__pycache__/json.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/deprecated/__pycache__/parse.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/deprecated/__pycache__/tools.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/deprecated/class_validators.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/deprecated/config.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/deprecated/copy_internals.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/deprecated/decorator.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/deprecated/json.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/deprecated/parse.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/deprecated/tools.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/env_settings.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/error_wrappers.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/errors.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/experimental/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/experimental/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/experimental/__pycache__/arguments_schema.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/experimental/__pycache__/missing_sentinel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/experimental/__pycache__/pipeline.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/experimental/arguments_schema.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/experimental/missing_sentinel.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/experimental/pipeline.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/fields.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/functional_serializers.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/functional_validators.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/generics.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/json.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/json_schema.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/main.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/mypy.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/networks.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/parse.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/plugin/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/plugin/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/plugin/__pycache__/_loader.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/plugin/__pycache__/_schema_validator.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/plugin/_loader.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/plugin/_schema_validator.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/py.typed create mode 100644 venv/lib/python3.12/site-packages/pydantic/root_model.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/schema.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/tools.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/type_adapter.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/types.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/typing.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/utils.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/_hypothesis_plugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/annotated_types.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/class_validators.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/color.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/config.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/dataclasses.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/datetime_parse.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/decorator.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/env_settings.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/error_wrappers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/errors.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/fields.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/generics.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/json.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/main.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/mypy.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/networks.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/parse.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/schema.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/tools.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/types.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/typing.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/validators.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/__pycache__/version.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/_hypothesis_plugin.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/annotated_types.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/class_validators.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/color.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/config.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/dataclasses.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/datetime_parse.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/decorator.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/env_settings.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/error_wrappers.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/errors.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/fields.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/generics.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/json.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/main.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/mypy.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/networks.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/parse.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/py.typed create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/schema.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/tools.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/types.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/typing.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/utils.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/validators.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/v1/version.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/validate_call_decorator.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/validators.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/version.py create mode 100644 venv/lib/python3.12/site-packages/pydantic/warnings.py create mode 100644 venv/lib/python3.12/site-packages/pydantic_core-2.41.5.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/pydantic_core-2.41.5.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/pydantic_core-2.41.5.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/pydantic_core-2.41.5.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/pydantic_core-2.41.5.dist-info/licenses/LICENSE create mode 100644 venv/lib/python3.12/site-packages/pydantic_core/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pydantic_core/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pydantic_core/__pycache__/core_schema.cpython-312.pyc create mode 100755 venv/lib/python3.12/site-packages/pydantic_core/_pydantic_core.cpython-312-x86_64-linux-gnu.so create mode 100644 venv/lib/python3.12/site-packages/pydantic_core/_pydantic_core.pyi create mode 100644 venv/lib/python3.12/site-packages/pydantic_core/core_schema.py create mode 100644 venv/lib/python3.12/site-packages/pydantic_core/py.typed create mode 100644 venv/lib/python3.12/site-packages/starlette-1.0.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/starlette-1.0.0.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/starlette-1.0.0.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/starlette-1.0.0.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/starlette-1.0.0.dist-info/licenses/LICENSE.md create mode 100644 venv/lib/python3.12/site-packages/starlette/__init__.py create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/_exception_handler.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/_utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/applications.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/authentication.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/background.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/concurrency.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/config.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/convertors.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/datastructures.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/endpoints.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/exceptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/formparsers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/requests.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/responses.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/routing.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/schemas.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/staticfiles.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/status.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/templating.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/testclient.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/types.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/__pycache__/websockets.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/_exception_handler.py create mode 100644 venv/lib/python3.12/site-packages/starlette/_utils.py create mode 100644 venv/lib/python3.12/site-packages/starlette/applications.py create mode 100644 venv/lib/python3.12/site-packages/starlette/authentication.py create mode 100644 venv/lib/python3.12/site-packages/starlette/background.py create mode 100644 venv/lib/python3.12/site-packages/starlette/concurrency.py create mode 100644 venv/lib/python3.12/site-packages/starlette/config.py create mode 100644 venv/lib/python3.12/site-packages/starlette/convertors.py create mode 100644 venv/lib/python3.12/site-packages/starlette/datastructures.py create mode 100644 venv/lib/python3.12/site-packages/starlette/endpoints.py create mode 100644 venv/lib/python3.12/site-packages/starlette/exceptions.py create mode 100644 venv/lib/python3.12/site-packages/starlette/formparsers.py create mode 100644 venv/lib/python3.12/site-packages/starlette/middleware/__init__.py create mode 100644 venv/lib/python3.12/site-packages/starlette/middleware/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/middleware/__pycache__/authentication.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/middleware/__pycache__/base.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/middleware/__pycache__/cors.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/middleware/__pycache__/errors.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/middleware/__pycache__/exceptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/middleware/__pycache__/gzip.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/middleware/__pycache__/httpsredirect.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/middleware/__pycache__/sessions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/middleware/__pycache__/trustedhost.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/middleware/__pycache__/wsgi.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/starlette/middleware/authentication.py create mode 100644 venv/lib/python3.12/site-packages/starlette/middleware/base.py create mode 100644 venv/lib/python3.12/site-packages/starlette/middleware/cors.py create mode 100644 venv/lib/python3.12/site-packages/starlette/middleware/errors.py create mode 100644 venv/lib/python3.12/site-packages/starlette/middleware/exceptions.py create mode 100644 venv/lib/python3.12/site-packages/starlette/middleware/gzip.py create mode 100644 venv/lib/python3.12/site-packages/starlette/middleware/httpsredirect.py create mode 100644 venv/lib/python3.12/site-packages/starlette/middleware/sessions.py create mode 100644 venv/lib/python3.12/site-packages/starlette/middleware/trustedhost.py create mode 100644 venv/lib/python3.12/site-packages/starlette/middleware/wsgi.py create mode 100644 venv/lib/python3.12/site-packages/starlette/py.typed create mode 100644 venv/lib/python3.12/site-packages/starlette/requests.py create mode 100644 venv/lib/python3.12/site-packages/starlette/responses.py create mode 100644 venv/lib/python3.12/site-packages/starlette/routing.py create mode 100644 venv/lib/python3.12/site-packages/starlette/schemas.py create mode 100644 venv/lib/python3.12/site-packages/starlette/staticfiles.py create mode 100644 venv/lib/python3.12/site-packages/starlette/status.py create mode 100644 venv/lib/python3.12/site-packages/starlette/templating.py create mode 100644 venv/lib/python3.12/site-packages/starlette/testclient.py create mode 100644 venv/lib/python3.12/site-packages/starlette/types.py create mode 100644 venv/lib/python3.12/site-packages/starlette/websockets.py create mode 100644 venv/lib/python3.12/site-packages/typing_extensions-4.15.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/typing_extensions-4.15.0.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/typing_extensions-4.15.0.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/typing_extensions-4.15.0.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/typing_extensions-4.15.0.dist-info/licenses/LICENSE create mode 100644 venv/lib/python3.12/site-packages/typing_extensions.py create mode 100644 venv/lib/python3.12/site-packages/typing_inspection-0.4.2.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/typing_inspection-0.4.2.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/typing_inspection-0.4.2.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/typing_inspection-0.4.2.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/typing_inspection-0.4.2.dist-info/licenses/LICENSE create mode 100644 venv/lib/python3.12/site-packages/typing_inspection/__init__.py create mode 100644 venv/lib/python3.12/site-packages/typing_inspection/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/typing_inspection/__pycache__/introspection.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/typing_inspection/__pycache__/typing_objects.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/typing_inspection/introspection.py create mode 100644 venv/lib/python3.12/site-packages/typing_inspection/py.typed create mode 100644 venv/lib/python3.12/site-packages/typing_inspection/typing_objects.py create mode 100644 venv/lib/python3.12/site-packages/typing_inspection/typing_objects.pyi create mode 100644 venv/lib/python3.12/site-packages/uvicorn-0.44.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/uvicorn-0.44.0.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/uvicorn-0.44.0.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/uvicorn-0.44.0.dist-info/REQUESTED create mode 100644 venv/lib/python3.12/site-packages/uvicorn-0.44.0.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/uvicorn-0.44.0.dist-info/entry_points.txt create mode 100644 venv/lib/python3.12/site-packages/uvicorn-0.44.0.dist-info/licenses/LICENSE.md create mode 100644 venv/lib/python3.12/site-packages/uvicorn/__init__.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/__main__.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/__pycache__/__main__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/__pycache__/_compat.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/__pycache__/_subprocess.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/__pycache__/_types.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/__pycache__/config.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/__pycache__/importer.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/__pycache__/logging.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/__pycache__/main.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/__pycache__/server.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/__pycache__/workers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/_compat.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/_subprocess.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/_types.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/config.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/importer.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/lifespan/__init__.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/lifespan/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/lifespan/__pycache__/off.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/lifespan/__pycache__/on.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/lifespan/off.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/lifespan/on.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/logging.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/loops/__init__.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/loops/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/loops/__pycache__/asyncio.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/loops/__pycache__/auto.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/loops/__pycache__/uvloop.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/loops/asyncio.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/loops/auto.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/loops/uvloop.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/main.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/middleware/__init__.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/middleware/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/middleware/__pycache__/asgi2.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/middleware/__pycache__/message_logger.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/middleware/__pycache__/proxy_headers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/middleware/__pycache__/wsgi.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/middleware/asgi2.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/middleware/message_logger.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/middleware/wsgi.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/__init__.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/__pycache__/utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/http/__init__.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/http/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/http/__pycache__/auto.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/http/__pycache__/flow_control.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/http/__pycache__/h11_impl.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/http/__pycache__/httptools_impl.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/http/auto.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/http/flow_control.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/http/h11_impl.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/http/httptools_impl.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/utils.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/websockets/__init__.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/websockets/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/websockets/__pycache__/auto.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/websockets/__pycache__/websockets_impl.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/websockets/__pycache__/websockets_sansio_impl.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/websockets/__pycache__/wsproto_impl.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/websockets/auto.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/websockets/websockets_impl.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/websockets/websockets_sansio_impl.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/protocols/websockets/wsproto_impl.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/py.typed create mode 100644 venv/lib/python3.12/site-packages/uvicorn/server.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/supervisors/__init__.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/supervisors/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/supervisors/__pycache__/basereload.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/supervisors/__pycache__/multiprocess.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/supervisors/__pycache__/statreload.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/supervisors/__pycache__/watchfilesreload.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/uvicorn/supervisors/basereload.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/supervisors/multiprocess.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/supervisors/statreload.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/supervisors/watchfilesreload.py create mode 100644 venv/lib/python3.12/site-packages/uvicorn/workers.py create mode 120000 venv/lib64 create mode 100644 venv/pyvenv.cfg diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0654a2a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,19 @@ +FROM python:3.12-slim + +WORKDIR /app + +# Install dependencies for Selenium and Chrome +RUN apt-get update && apt-get install -y \ + wget \ + gnupg \ + unzip \ + curl \ + && rm -rf /var/lib/apt/lists/* + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +COPY app/ ./app/ + +EXPOSE 8000 +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..7ce3a72 --- /dev/null +++ b/README.md @@ -0,0 +1,26 @@ +# GISP Registry Scraper (API-Direct) + +This project provides a robust, high-performance API for searching the Russian Industry portal (gisp.gov.ru). It bypasses brittle UI automation (Selenium) by interacting directly with the portal's internal REST API. + +## Features +- **Fast & Reliable**: Bypasses browser rendering and DOM-scraping. +- **Filtering**: Allows querying by registry number without default UI filter constraints (like date range). +- **Lightweight**: No need for Selenium Grid or heavy headless browsers. + +## API Usage +- **Endpoint**: `/scrape/{registry_number}` +- **Example**: `GET /scrape/10084557` + +## Setup +1. **Environment**: Ensure you have Python 3.12+. +2. **Install Dependencies**: + ```bash + pip install fastapi uvicorn httpx + ``` +3. **Run the App**: + ```bash + uvicorn app.main:app --host 0.0.0.0 --port 8000 + ``` + +## Why API-Direct? +The GISP portal uses a complex DevExtreme grid that is prone to race conditions and default date filters. By targeting the `/pub/prod/b/` endpoint directly, we eliminate the need for containerized browser nodes and significantly reduce scraping latency. diff --git a/app/main.py b/app/main.py new file mode 100644 index 0000000..d2849cf --- /dev/null +++ b/app/main.py @@ -0,0 +1,52 @@ +import httpx +from fastapi import FastAPI, HTTPException + +app = FastAPI(title="GISP Scraper API (API-Direct)") + +# The API endpoint identified from network inspection +API_URL = "https://gisp.gov.ru/pp719v2/pub/prod/b/" + +async def fetch_gisp_data(registry_number: str): + # Constructing the filter payload based on what we saw in the Network tab + # We will remove the restrictive date filters (res_valid_till, etc.) + payload = { + "opt": { + "sort": None, + "requireTotalCount": True, + "searchOperation": "contains", + "searchValue": None, + "skip": 0, + "take": 10, + "userData": {}, + "filter": ["product_reg_number_2023", "contains", registry_number] + } + } + + async with httpx.AsyncClient() as client: + try: + response = await client.post(API_URL, json=payload, timeout=30.0) + response.raise_for_status() + data = response.json() + + # GISP usually returns { "data": [ ... ], "totalCount": N } + if "data" in data and len(data["data"]) > 0: + # Return the URL or specific entry found + # Based on the DevExtreme schema, we might need a specific ID to form the URL + return data["data"] + return None + except Exception as e: + print(f"API scraping error: {e}") + return None + +@app.get("/scrape/{registry_number:path}") +async def get_product_link(registry_number: str): + results = await fetch_gisp_data(registry_number) + if not results: + raise HTTPException(status_code=404, detail="Product not found or scraping failed") + + # We can refine this to return the specific URL or the whole result object + return {"registry_number": registry_number, "results": results} + +@app.get("/health") +def health(): + return {"status": "ok"} diff --git a/k8s.yaml b/k8s.yaml new file mode 100644 index 0000000..eb2373a --- /dev/null +++ b/k8s.yaml @@ -0,0 +1,117 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: selenium-hub +spec: + replicas: 1 + selector: + matchLabels: + app: selenium-hub + template: + metadata: + labels: + app: selenium-hub + spec: + tolerations: + - key: "node.kubernetes.io/disk-pressure" + operator: "Exists" + effect: "NoSchedule" + containers: + - name: selenium-hub + image: selenium/hub:latest + ports: + - containerPort: 4444 +--- +apiVersion: v1 +kind: Service +metadata: + name: selenium-hub +spec: + selector: + app: selenium-hub + ports: + - port: 4444 + name: http + targetPort: 4444 + - port: 4442 + name: publish + targetPort: 4442 + - port: 4443 + name: subscribe + targetPort: 4443 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: selenium-node-chrome +spec: + replicas: 1 + selector: + matchLabels: + app: selenium-node-chrome + template: + metadata: + labels: + app: selenium-node-chrome + spec: + tolerations: + - key: "node.kubernetes.io/disk-pressure" + operator: "Exists" + effect: "NoSchedule" + containers: + - name: selenium-node-chrome + image: selenium/node-chrome:latest + env: + - name: SE_EVENT_BUS_HOST + value: "selenium-hub" + - name: SE_EVENT_BUS_PUBLISH_PORT + value: "4442" + - name: SE_EVENT_BUS_SUBSCRIBE_PORT + value: "4443" + volumeMounts: + - name: dshm + mountPath: /dev/shm + volumes: + - name: dshm + emptyDir: + medium: Memory +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gisp-scraper +spec: + replicas: 1 + selector: + matchLabels: + app: gisp-scraper + template: + metadata: + labels: + app: gisp-scraper + spec: + tolerations: + - key: "node.kubernetes.io/disk-pressure" + operator: "Exists" + effect: "NoSchedule" + containers: + - name: gisp-scraper + image: git.danilkolesnikov.ru/flash/gisp-scraper:latest + ports: + - containerPort: 8000 + env: + - name: SELENIUM_HUB_URL + value: "http://selenium-hub:4444/wd/hub" +--- +apiVersion: v1 +kind: Service +metadata: + name: gisp-scraper +spec: + selector: + app: gisp-scraper + ports: + - protocol: TCP + port: 80 + targetPort: 8000 + type: ClusterIP diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..d23d558 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +fastapi +uvicorn +httpx diff --git a/skaffold.yaml b/skaffold.yaml new file mode 100644 index 0000000..8b8e076 --- /dev/null +++ b/skaffold.yaml @@ -0,0 +1,16 @@ +apiVersion: skaffold/v4beta11 +kind: Config +metadata: + name: gisp-scraper +build: + artifacts: + - image: git.danilkolesnikov.ru/flash/gisp-scraper + docker: + dockerfile: Dockerfile + local: + push: true +manifests: + rawYaml: + - k8s.yaml +deploy: + kubectl: {} diff --git a/venv/bin/Activate.ps1 b/venv/bin/Activate.ps1 new file mode 100644 index 0000000..b49d77b --- /dev/null +++ b/venv/bin/Activate.ps1 @@ -0,0 +1,247 @@ +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +For more information on Execution Policies: +https://go.microsoft.com/fwlink/?LinkID=135170 + +#> +Param( + [Parameter(Mandatory = $false)] + [String] + $VenvDir, + [Parameter(Mandatory = $false)] + [String] + $Prompt +) + +<# Function declarations --------------------------------------------------- #> + +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT + } + + # The prior PYTHONHOME: + if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { + Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME + Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME + } + + # The prior PATH: + if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { + Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH + Remove-Item -Path Env:_OLD_VIRTUAL_PATH + } + + # Just remove the VIRTUAL_ENV altogether: + if (Test-Path -Path Env:VIRTUAL_ENV) { + Remove-Item -Path env:VIRTUAL_ENV + } + + # Just remove VIRTUAL_ENV_PROMPT altogether. + if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { + Remove-Item -Path env:VIRTUAL_ENV_PROMPT + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +<# +.Description +Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the +given folder, and returns them in a map. + +For each line in the pyvenv.cfg file, if that line can be parsed into exactly +two strings separated by `=` (with any amount of whitespace surrounding the =) +then it is considered a `key = value` line. The left hand string is the key, +the right hand is the value. + +If the value starts with a `'` or a `"` then the first and last character is +stripped from the value before being captured. + +.Parameter ConfigDir +Path to the directory that contains the `pyvenv.cfg` file. +#> +function Get-PyVenvConfig( + [String] + $ConfigDir +) { + Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" + + # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). + $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue + + # An empty map will be returned if no config file is found. + $pyvenvConfig = @{ } + + if ($pyvenvConfigPath) { + + Write-Verbose "File exists, parse `key = value` lines" + $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath + + $pyvenvConfigContent | ForEach-Object { + $keyval = $PSItem -split "\s*=\s*", 2 + if ($keyval[0] -and $keyval[1]) { + $val = $keyval[1] + + # Remove extraneous quotations around a string value. + if ("'""".Contains($val.Substring(0, 1))) { + $val = $val.Substring(1, $val.Length - 2) + } + + $pyvenvConfig[$keyval[0]] = $val + Write-Verbose "Adding Key: '$($keyval[0])'='$val'" + } + } + } + return $pyvenvConfig +} + + +<# Begin Activate script --------------------------------------------------- #> + +# Determine the containing directory of this script +$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition +$VenvExecDir = Get-Item -Path $VenvExecPath + +Write-Verbose "Activation script is located in path: '$VenvExecPath'" +Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" +Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" + +# Set values required in priority: CmdLine, ConfigFile, Default +# First, get the location of the virtual environment, it might not be +# VenvExecDir if specified on the command line. +if ($VenvDir) { + Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" +} +else { + Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." + $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") + Write-Verbose "VenvDir=$VenvDir" +} + +# Next, read the `pyvenv.cfg` file to determine any required value such +# as `prompt`. +$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir + +# Next, set the prompt from the command line, or the config file, or +# just use the name of the virtual environment folder. +if ($Prompt) { + Write-Verbose "Prompt specified as argument, using '$Prompt'" +} +else { + Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" + if ($pyvenvCfg -and $pyvenvCfg['prompt']) { + Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" + $Prompt = $pyvenvCfg['prompt']; + } + else { + Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)" + Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" + $Prompt = Split-Path -Path $venvDir -Leaf + } +} + +Write-Verbose "Prompt = '$Prompt'" +Write-Verbose "VenvDir='$VenvDir'" + +# Deactivate any currently active virtual environment, but leave the +# deactivate function in place. +deactivate -nondestructive + +# Now set the environment variable VIRTUAL_ENV, used by many tools to determine +# that there is an activated venv. +$env:VIRTUAL_ENV = $VenvDir + +if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { + + Write-Verbose "Setting prompt to '$Prompt'" + + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT { "" } + Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT + New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt + + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " + _OLD_VIRTUAL_PROMPT + } + $env:VIRTUAL_ENV_PROMPT = $Prompt +} + +# Clear PYTHONHOME +if (Test-Path -Path Env:PYTHONHOME) { + Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME + Remove-Item -Path Env:PYTHONHOME +} + +# Add the venv to the PATH +Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH +$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" diff --git a/venv/bin/activate b/venv/bin/activate new file mode 100644 index 0000000..b684ba1 --- /dev/null +++ b/venv/bin/activate @@ -0,0 +1,70 @@ +# This file must be used with "source bin/activate" *from bash* +# You cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # Call hash to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + hash -r 2> /dev/null + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + unset VIRTUAL_ENV_PROMPT + if [ ! "${1:-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +# on Windows, a path can contain colons and backslashes and has to be converted: +if [ "${OSTYPE:-}" = "cygwin" ] || [ "${OSTYPE:-}" = "msys" ] ; then + # transform D:\path\to\venv to /d/path/to/venv on MSYS + # and to /cygdrive/d/path/to/venv on Cygwin + export VIRTUAL_ENV=$(cygpath /home/danil/.openclaw/workspace/gisp-scraper/venv) +else + # use the path as-is + export VIRTUAL_ENV=/home/danil/.openclaw/workspace/gisp-scraper/venv +fi + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/"bin":$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + PS1='(venv) '"${PS1:-}" + export PS1 + VIRTUAL_ENV_PROMPT='(venv) ' + export VIRTUAL_ENV_PROMPT +fi + +# Call hash to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +hash -r 2> /dev/null diff --git a/venv/bin/activate.csh b/venv/bin/activate.csh new file mode 100644 index 0000000..d5d7e8c --- /dev/null +++ b/venv/bin/activate.csh @@ -0,0 +1,27 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. + +# Created by Davide Di Blasi . +# Ported to Python 3.3 venv by Andrew Svetlov + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV /home/danil/.openclaw/workspace/gisp-scraper/venv + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/"bin":$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + set prompt = '(venv) '"$prompt" + setenv VIRTUAL_ENV_PROMPT '(venv) ' +endif + +alias pydoc python -m pydoc + +rehash diff --git a/venv/bin/activate.fish b/venv/bin/activate.fish new file mode 100644 index 0000000..b682c18 --- /dev/null +++ b/venv/bin/activate.fish @@ -0,0 +1,69 @@ +# This file must be used with "source /bin/activate.fish" *from fish* +# (https://fishshell.com/). You cannot run it directly. + +function deactivate -d "Exit virtual environment and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + set -e _OLD_FISH_PROMPT_OVERRIDE + # prevents error when using nested fish instances (Issue #93858) + if functions -q _old_fish_prompt + functions -e fish_prompt + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + end + + set -e VIRTUAL_ENV + set -e VIRTUAL_ENV_PROMPT + if test "$argv[1]" != "nondestructive" + # Self-destruct! + functions -e deactivate + end +end + +# Unset irrelevant variables. +deactivate nondestructive + +set -gx VIRTUAL_ENV /home/danil/.openclaw/workspace/gisp-scraper/venv + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/"bin $PATH + +# Unset PYTHONHOME if set. +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # fish uses a function instead of an env var to generate the prompt. + + # Save the current fish_prompt function as the function _old_fish_prompt. + functions -c fish_prompt _old_fish_prompt + + # With the original prompt function renamed, we can override with our own. + function fish_prompt + # Save the return status of the last command. + set -l old_status $status + + # Output the venv prompt; color taken from the blue of the Python logo. + printf "%s%s%s" (set_color 4B8BBE) '(venv) ' (set_color normal) + + # Restore the return status of the previous command. + echo "exit $old_status" | . + # Output the original/"old" prompt. + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" + set -gx VIRTUAL_ENV_PROMPT '(venv) ' +end diff --git a/venv/bin/fastapi b/venv/bin/fastapi new file mode 100755 index 0000000..972bd72 --- /dev/null +++ b/venv/bin/fastapi @@ -0,0 +1,8 @@ +#!/home/danil/.openclaw/workspace/gisp-scraper/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from fastapi.cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/httpx b/venv/bin/httpx new file mode 100755 index 0000000..a702e3d --- /dev/null +++ b/venv/bin/httpx @@ -0,0 +1,8 @@ +#!/home/danil/.openclaw/workspace/gisp-scraper/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from httpx import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/pip b/venv/bin/pip new file mode 100755 index 0000000..17db0ac --- /dev/null +++ b/venv/bin/pip @@ -0,0 +1,8 @@ +#!/home/danil/.openclaw/workspace/gisp-scraper/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/pip3 b/venv/bin/pip3 new file mode 100755 index 0000000..17db0ac --- /dev/null +++ b/venv/bin/pip3 @@ -0,0 +1,8 @@ +#!/home/danil/.openclaw/workspace/gisp-scraper/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/pip3.12 b/venv/bin/pip3.12 new file mode 100755 index 0000000..17db0ac --- /dev/null +++ b/venv/bin/pip3.12 @@ -0,0 +1,8 @@ +#!/home/danil/.openclaw/workspace/gisp-scraper/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/python b/venv/bin/python new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/venv/bin/python @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/venv/bin/python3 b/venv/bin/python3 new file mode 120000 index 0000000..ae65fda --- /dev/null +++ b/venv/bin/python3 @@ -0,0 +1 @@ +/usr/bin/python3 \ No newline at end of file diff --git a/venv/bin/python3.12 b/venv/bin/python3.12 new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/venv/bin/python3.12 @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/venv/bin/uvicorn b/venv/bin/uvicorn new file mode 100755 index 0000000..cd532c4 --- /dev/null +++ b/venv/bin/uvicorn @@ -0,0 +1,8 @@ +#!/home/danil/.openclaw/workspace/gisp-scraper/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from uvicorn.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/lib/python3.12/site-packages/__pycache__/typing_extensions.cpython-312.pyc b/venv/lib/python3.12/site-packages/__pycache__/typing_extensions.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..db1943a6eba7bdd227509149262adb12ea7f6cf1 GIT binary patch literal 163763 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

l=5_Skmpk3Ezr+%l!v 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 mP{v}=K +License-Expression: MIT +License-File: LICENSE +Classifier: Intended Audience :: Information Technology +Classifier: Intended Audience :: System Administrators +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python +Classifier: Topic :: Internet +Classifier: Topic :: Software Development :: Libraries :: Application Frameworks +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Software Development :: Libraries +Classifier: Topic :: Software Development +Classifier: Typing :: Typed +Classifier: Development Status :: 4 - Beta +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Project-URL: Homepage, https://github.com/fastapi/annotated-doc +Project-URL: Documentation, https://github.com/fastapi/annotated-doc +Project-URL: Repository, https://github.com/fastapi/annotated-doc +Project-URL: Issues, https://github.com/fastapi/annotated-doc/issues +Project-URL: Changelog, https://github.com/fastapi/annotated-doc/release-notes.md +Requires-Python: >=3.8 +Description-Content-Type: text/markdown + +# Annotated Doc + +Document parameters, class attributes, return types, and variables inline, with `Annotated`. + + + Test + + + Coverage + + + Package version + + + Supported Python versions + + +## Installation + +```bash +pip install annotated-doc +``` + +Or with `uv`: + +```Python +uv add annotated-doc +``` + +## Usage + +Import `Doc` and pass a single literal string with the documentation for the specific parameter, class attribute, return type, or variable. + +For example, to document a parameter `name` in a function `hi` you could do: + +```Python +from typing import Annotated + +from annotated_doc import Doc + +def hi(name: Annotated[str, Doc("Who to say hi to")]) -> None: + print(f"Hi, {name}!") +``` + +You can also use it to document class attributes: + +```Python +from typing import Annotated + +from annotated_doc import Doc + +class User: + name: Annotated[str, Doc("The user's name")] + age: Annotated[int, Doc("The user's age")] +``` + +The same way, you could document return types and variables, or anything that could have a type annotation with `Annotated`. + +## Who Uses This + +`annotated-doc` was made for: + +* [FastAPI](https://fastapi.tiangolo.com/) +* [Typer](https://typer.tiangolo.com/) +* [SQLModel](https://sqlmodel.tiangolo.com/) +* [Asyncer](https://asyncer.tiangolo.com/) + +`annotated-doc` is supported by [griffe-typingdoc](https://github.com/mkdocstrings/griffe-typingdoc), which powers reference documentation like the one in the [FastAPI Reference](https://fastapi.tiangolo.com/reference/). + +## Reasons not to use `annotated-doc` + +You are already comfortable with one of the existing docstring formats, like: + +* Sphinx +* numpydoc +* Google +* Keras + +Your team is already comfortable using them. + +You prefer having the documentation about parameters all together in a docstring, separated from the code defining them. + +You care about a specific set of users, using one specific editor, and that editor already has support for the specific docstring format you use. + +## Reasons to use `annotated-doc` + +* No micro-syntax to learn for newcomers, it’s **just Python** syntax. +* **Editing** would be already fully supported by default by any editor (current or future) supporting Python syntax, including syntax errors, syntax highlighting, etc. +* **Rendering** would be relatively straightforward to implement by static tools (tools that don't need runtime execution), as the information can be extracted from the AST they normally already create. +* **Deduplication of information**: the name of a parameter would be defined in a single place, not duplicated inside of a docstring. +* **Elimination** of the possibility of having **inconsistencies** when removing a parameter or class variable and **forgetting to remove** its documentation. +* **Minimization** of the probability of adding a new parameter or class variable and **forgetting to add its documentation**. +* **Elimination** of the possibility of having **inconsistencies** between the **name** of a parameter in the **signature** and the name in the docstring when it is renamed. +* **Access** to the documentation string for each symbol at **runtime**, including existing (older) Python versions. +* A more formalized way to document other symbols, like type aliases, that could use Annotated. +* **Support** for apps using FastAPI, Typer and others. +* **AI Accessibility**: AI tools will have an easier way understanding each parameter as the distance from documentation to parameter is much closer. + +## History + +I ([@tiangolo](https://github.com/tiangolo)) originally wanted for this to be part of the Python standard library (in [PEP 727](https://peps.python.org/pep-0727/)), but the proposal was withdrawn as there was a fair amount of negative feedback and opposition. + +The conclusion was that this was better done as an external effort, in a third-party library. + +So, here it is, with a simpler approach, as a third-party library, in a way that can be used by others, starting with FastAPI and friends. + +## License + +This project is licensed under the terms of the MIT license. diff --git a/venv/lib/python3.12/site-packages/annotated_doc-0.0.4.dist-info/RECORD b/venv/lib/python3.12/site-packages/annotated_doc-0.0.4.dist-info/RECORD new file mode 100644 index 0000000..549e005 --- /dev/null +++ b/venv/lib/python3.12/site-packages/annotated_doc-0.0.4.dist-info/RECORD @@ -0,0 +1,11 @@ +annotated_doc-0.0.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +annotated_doc-0.0.4.dist-info/METADATA,sha256=Irm5KJua33dY2qKKAjJ-OhKaVBVIfwFGej_dSe3Z1TU,6566 +annotated_doc-0.0.4.dist-info/RECORD,, +annotated_doc-0.0.4.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90 +annotated_doc-0.0.4.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34 +annotated_doc-0.0.4.dist-info/licenses/LICENSE,sha256=__Fwd5pqy_ZavbQFwIfxzuF4ZpHkqWpANFF-SlBKDN8,1086 +annotated_doc/__init__.py,sha256=VuyxxUe80kfEyWnOrCx_Bk8hybo3aKo6RYBlkBBYW8k,52 +annotated_doc/__pycache__/__init__.cpython-312.pyc,, +annotated_doc/__pycache__/main.cpython-312.pyc,, +annotated_doc/main.py,sha256=5Zfvxv80SwwLqpRW73AZyZyiM4bWma9QWRbp_cgD20s,1075 +annotated_doc/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/venv/lib/python3.12/site-packages/annotated_doc-0.0.4.dist-info/WHEEL b/venv/lib/python3.12/site-packages/annotated_doc-0.0.4.dist-info/WHEEL new file mode 100644 index 0000000..045c8ac --- /dev/null +++ b/venv/lib/python3.12/site-packages/annotated_doc-0.0.4.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: pdm-backend (2.4.5) +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/venv/lib/python3.12/site-packages/annotated_doc-0.0.4.dist-info/entry_points.txt b/venv/lib/python3.12/site-packages/annotated_doc-0.0.4.dist-info/entry_points.txt new file mode 100644 index 0000000..c3ad472 --- /dev/null +++ b/venv/lib/python3.12/site-packages/annotated_doc-0.0.4.dist-info/entry_points.txt @@ -0,0 +1,4 @@ +[console_scripts] + +[gui_scripts] + diff --git a/venv/lib/python3.12/site-packages/annotated_doc-0.0.4.dist-info/licenses/LICENSE b/venv/lib/python3.12/site-packages/annotated_doc-0.0.4.dist-info/licenses/LICENSE new file mode 100644 index 0000000..7a25446 --- /dev/null +++ b/venv/lib/python3.12/site-packages/annotated_doc-0.0.4.dist-info/licenses/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2025 Sebastián Ramírez + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/venv/lib/python3.12/site-packages/annotated_doc/__init__.py b/venv/lib/python3.12/site-packages/annotated_doc/__init__.py new file mode 100644 index 0000000..a0152a7 --- /dev/null +++ b/venv/lib/python3.12/site-packages/annotated_doc/__init__.py @@ -0,0 +1,3 @@ +from .main import Doc as Doc + +__version__ = "0.0.4" diff --git a/venv/lib/python3.12/site-packages/annotated_doc/__pycache__/__init__.cpython-312.pyc b/venv/lib/python3.12/site-packages/annotated_doc/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..947b3b585f0adc7bd1ad6059b488850f71e86961 GIT binary patch literal 265 zcmXv|J5B>J5VhAqe4?ca9T(Ulo&YHk6*UJ)V;Ostwc@ocd)a6ykT?Zr;4GYgm5`9A z=#bK-!Yjcm-n=(&G&65yc|tOtX76U1>(^-hQT&PBEQ=SSiKdn`bVVuA#j5C8HTkAF zs_4LOy?Q)Y@C9GqRcx3v(zwWSHcW-+Fec-j5U*r6uH4s9`vyTvXDo0Z&?zgou=R11 zf>a1=lfpcyC<8|5&~;$VJ%qlky}RNUmyk@0^E|qdYfK=W^Q~-A3+)vMVVr4&;Gy3i hT{m7oSiFhH`SAE`Dl`2sO6dnV|2#c=p2ox6`2|M2Ng4nE literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/annotated_doc/__pycache__/main.cpython-312.pyc b/venv/lib/python3.12/site-packages/annotated_doc/__pycache__/main.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1ed9b69a573107de9ec13795b57876786a605023 GIT binary patch literal 1913 zcmZux&2Jk;6rc639mh>D5Vzt(pmD0SHuZ-}FKLA;A*E0*7E-B@g3x-rGmf`e?`&t* z2`&NkkORlw5(y#Yz=5b2{tqsW0Hv&Y;~xkF2`MMuoApP7I$F(pZ{FK^zxOr2EG`xZ ztZz$y_%|Fv{zPH2KsM|24Iq0YLp~;)>=JH0&7_KTGR#zMFBQ^#`p;eSk09$7C+it* zt=l{!9By-`>+tNZv!3O)aJm_u13m}*9Po3%=XqYtgIoZ+d5|v*ooXSm*QCc{@Vh3u zekf?%6O>DD&=+CMVqb<-b}6IrFcOr7p&TC$v>$HJ_J`?-;O!cXCGCg;9j}2Focba4 z0;V-(ajg8#AQrktyMxd(7qgJlzKDC0(}*bstWcm=A|9xaZn0nh=F|xYzel<YZ4Dw~PsltY# zzq!BiG^!9pzU|LaGZ`ahx#MO$x5tmwXT) zzu>wL2P_zC=3Jb1IJRMu)dg^)UWF~OVN4Y!Jjuz<1L4Jq(}6cpVW%7tg literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/annotated_doc/main.py b/venv/lib/python3.12/site-packages/annotated_doc/main.py new file mode 100644 index 0000000..7063c59 --- /dev/null +++ b/venv/lib/python3.12/site-packages/annotated_doc/main.py @@ -0,0 +1,36 @@ +class Doc: + """Define the documentation of a type annotation using `Annotated`, to be + used in class attributes, function and method parameters, return values, + and variables. + + The value should be a positional-only string literal to allow static tools + like editors and documentation generators to use it. + + This complements docstrings. + + The string value passed is available in the attribute `documentation`. + + Example: + + ```Python + from typing import Annotated + from annotated_doc import Doc + + def hi(name: Annotated[str, Doc("Who to say hi to")]) -> None: + print(f"Hi, {name}!") + ``` + """ + + def __init__(self, documentation: str, /) -> None: + self.documentation = documentation + + def __repr__(self) -> str: + return f"Doc({self.documentation!r})" + + def __hash__(self) -> int: + return hash(self.documentation) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, Doc): + return NotImplemented + return self.documentation == other.documentation diff --git a/venv/lib/python3.12/site-packages/annotated_doc/py.typed b/venv/lib/python3.12/site-packages/annotated_doc/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.12/site-packages/annotated_types-0.7.0.dist-info/INSTALLER b/venv/lib/python3.12/site-packages/annotated_types-0.7.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.12/site-packages/annotated_types-0.7.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.12/site-packages/annotated_types-0.7.0.dist-info/METADATA b/venv/lib/python3.12/site-packages/annotated_types-0.7.0.dist-info/METADATA new file mode 100644 index 0000000..3ac05cf --- /dev/null +++ b/venv/lib/python3.12/site-packages/annotated_types-0.7.0.dist-info/METADATA @@ -0,0 +1,295 @@ +Metadata-Version: 2.3 +Name: annotated-types +Version: 0.7.0 +Summary: Reusable constraint types to use with typing.Annotated +Project-URL: Homepage, https://github.com/annotated-types/annotated-types +Project-URL: Source, https://github.com/annotated-types/annotated-types +Project-URL: Changelog, https://github.com/annotated-types/annotated-types/releases +Author-email: Adrian Garcia Badaracco <1755071+adriangb@users.noreply.github.com>, Samuel Colvin , Zac Hatfield-Dodds +License-File: LICENSE +Classifier: Development Status :: 4 - Beta +Classifier: Environment :: Console +Classifier: Environment :: MacOS X +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: Information Technology +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: POSIX :: Linux +Classifier: Operating System :: Unix +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Typing :: Typed +Requires-Python: >=3.8 +Requires-Dist: typing-extensions>=4.0.0; python_version < '3.9' +Description-Content-Type: text/markdown + +# annotated-types + +[![CI](https://github.com/annotated-types/annotated-types/workflows/CI/badge.svg?event=push)](https://github.com/annotated-types/annotated-types/actions?query=event%3Apush+branch%3Amain+workflow%3ACI) +[![pypi](https://img.shields.io/pypi/v/annotated-types.svg)](https://pypi.python.org/pypi/annotated-types) +[![versions](https://img.shields.io/pypi/pyversions/annotated-types.svg)](https://github.com/annotated-types/annotated-types) +[![license](https://img.shields.io/github/license/annotated-types/annotated-types.svg)](https://github.com/annotated-types/annotated-types/blob/main/LICENSE) + +[PEP-593](https://peps.python.org/pep-0593/) added `typing.Annotated` as a way of +adding context-specific metadata to existing types, and specifies that +`Annotated[T, x]` _should_ be treated as `T` by any tool or library without special +logic for `x`. + +This package provides metadata objects which can be used to represent common +constraints such as upper and lower bounds on scalar values and collection sizes, +a `Predicate` marker for runtime checks, and +descriptions of how we intend these metadata to be interpreted. In some cases, +we also note alternative representations which do not require this package. + +## Install + +```bash +pip install annotated-types +``` + +## Examples + +```python +from typing import Annotated +from annotated_types import Gt, Len, Predicate + +class MyClass: + age: Annotated[int, Gt(18)] # Valid: 19, 20, ... + # Invalid: 17, 18, "19", 19.0, ... + factors: list[Annotated[int, Predicate(is_prime)]] # Valid: 2, 3, 5, 7, 11, ... + # Invalid: 4, 8, -2, 5.0, "prime", ... + + my_list: Annotated[list[int], Len(0, 10)] # Valid: [], [10, 20, 30, 40, 50] + # Invalid: (1, 2), ["abc"], [0] * 20 +``` + +## Documentation + +_While `annotated-types` avoids runtime checks for performance, users should not +construct invalid combinations such as `MultipleOf("non-numeric")` or `Annotated[int, Len(3)]`. +Downstream implementors may choose to raise an error, emit a warning, silently ignore +a metadata item, etc., if the metadata objects described below are used with an +incompatible type - or for any other reason!_ + +### Gt, Ge, Lt, Le + +Express inclusive and/or exclusive bounds on orderable values - which may be numbers, +dates, times, strings, sets, etc. Note that the boundary value need not be of the +same type that was annotated, so long as they can be compared: `Annotated[int, Gt(1.5)]` +is fine, for example, and implies that the value is an integer x such that `x > 1.5`. + +We suggest that implementors may also interpret `functools.partial(operator.le, 1.5)` +as being equivalent to `Gt(1.5)`, for users who wish to avoid a runtime dependency on +the `annotated-types` package. + +To be explicit, these types have the following meanings: + +* `Gt(x)` - value must be "Greater Than" `x` - equivalent to exclusive minimum +* `Ge(x)` - value must be "Greater than or Equal" to `x` - equivalent to inclusive minimum +* `Lt(x)` - value must be "Less Than" `x` - equivalent to exclusive maximum +* `Le(x)` - value must be "Less than or Equal" to `x` - equivalent to inclusive maximum + +### Interval + +`Interval(gt, ge, lt, le)` allows you to specify an upper and lower bound with a single +metadata object. `None` attributes should be ignored, and non-`None` attributes +treated as per the single bounds above. + +### MultipleOf + +`MultipleOf(multiple_of=x)` might be interpreted in two ways: + +1. Python semantics, implying `value % multiple_of == 0`, or +2. [JSONschema semantics](https://json-schema.org/draft/2020-12/json-schema-validation.html#rfc.section.6.2.1), + where `int(value / multiple_of) == value / multiple_of`. + +We encourage users to be aware of these two common interpretations and their +distinct behaviours, especially since very large or non-integer numbers make +it easy to cause silent data corruption due to floating-point imprecision. + +We encourage libraries to carefully document which interpretation they implement. + +### MinLen, MaxLen, Len + +`Len()` implies that `min_length <= len(value) <= max_length` - lower and upper bounds are inclusive. + +As well as `Len()` which can optionally include upper and lower bounds, we also +provide `MinLen(x)` and `MaxLen(y)` which are equivalent to `Len(min_length=x)` +and `Len(max_length=y)` respectively. + +`Len`, `MinLen`, and `MaxLen` may be used with any type which supports `len(value)`. + +Examples of usage: + +* `Annotated[list, MaxLen(10)]` (or `Annotated[list, Len(max_length=10))`) - list must have a length of 10 or less +* `Annotated[str, MaxLen(10)]` - string must have a length of 10 or less +* `Annotated[list, MinLen(3))` (or `Annotated[list, Len(min_length=3))`) - list must have a length of 3 or more +* `Annotated[list, Len(4, 6)]` - list must have a length of 4, 5, or 6 +* `Annotated[list, Len(8, 8)]` - list must have a length of exactly 8 + +#### Changed in v0.4.0 + +* `min_inclusive` has been renamed to `min_length`, no change in meaning +* `max_exclusive` has been renamed to `max_length`, upper bound is now **inclusive** instead of **exclusive** +* The recommendation that slices are interpreted as `Len` has been removed due to ambiguity and different semantic + meaning of the upper bound in slices vs. `Len` + +See [issue #23](https://github.com/annotated-types/annotated-types/issues/23) for discussion. + +### Timezone + +`Timezone` can be used with a `datetime` or a `time` to express which timezones +are allowed. `Annotated[datetime, Timezone(None)]` must be a naive datetime. +`Timezone[...]` ([literal ellipsis](https://docs.python.org/3/library/constants.html#Ellipsis)) +expresses that any timezone-aware datetime is allowed. You may also pass a specific +timezone string or [`tzinfo`](https://docs.python.org/3/library/datetime.html#tzinfo-objects) +object such as `Timezone(timezone.utc)` or `Timezone("Africa/Abidjan")` to express that you only +allow a specific timezone, though we note that this is often a symptom of fragile design. + +#### Changed in v0.x.x + +* `Timezone` accepts [`tzinfo`](https://docs.python.org/3/library/datetime.html#tzinfo-objects) objects instead of + `timezone`, extending compatibility to [`zoneinfo`](https://docs.python.org/3/library/zoneinfo.html) and third party libraries. + +### Unit + +`Unit(unit: str)` expresses that the annotated numeric value is the magnitude of +a quantity with the specified unit. For example, `Annotated[float, Unit("m/s")]` +would be a float representing a velocity in meters per second. + +Please note that `annotated_types` itself makes no attempt to parse or validate +the unit string in any way. That is left entirely to downstream libraries, +such as [`pint`](https://pint.readthedocs.io) or +[`astropy.units`](https://docs.astropy.org/en/stable/units/). + +An example of how a library might use this metadata: + +```python +from annotated_types import Unit +from typing import Annotated, TypeVar, Callable, Any, get_origin, get_args + +# given a type annotated with a unit: +Meters = Annotated[float, Unit("m")] + + +# you can cast the annotation to a specific unit type with any +# callable that accepts a string and returns the desired type +T = TypeVar("T") +def cast_unit(tp: Any, unit_cls: Callable[[str], T]) -> T | None: + if get_origin(tp) is Annotated: + for arg in get_args(tp): + if isinstance(arg, Unit): + return unit_cls(arg.unit) + return None + + +# using `pint` +import pint +pint_unit = cast_unit(Meters, pint.Unit) + + +# using `astropy.units` +import astropy.units as u +astropy_unit = cast_unit(Meters, u.Unit) +``` + +### Predicate + +`Predicate(func: Callable)` expresses that `func(value)` is truthy for valid values. +Users should prefer the statically inspectable metadata above, but if you need +the full power and flexibility of arbitrary runtime predicates... here it is. + +For some common constraints, we provide generic types: + +* `IsLower = Annotated[T, Predicate(str.islower)]` +* `IsUpper = Annotated[T, Predicate(str.isupper)]` +* `IsDigit = Annotated[T, Predicate(str.isdigit)]` +* `IsFinite = Annotated[T, Predicate(math.isfinite)]` +* `IsNotFinite = Annotated[T, Predicate(Not(math.isfinite))]` +* `IsNan = Annotated[T, Predicate(math.isnan)]` +* `IsNotNan = Annotated[T, Predicate(Not(math.isnan))]` +* `IsInfinite = Annotated[T, Predicate(math.isinf)]` +* `IsNotInfinite = Annotated[T, Predicate(Not(math.isinf))]` + +so that you can write e.g. `x: IsFinite[float] = 2.0` instead of the longer +(but exactly equivalent) `x: Annotated[float, Predicate(math.isfinite)] = 2.0`. + +Some libraries might have special logic to handle known or understandable predicates, +for example by checking for `str.isdigit` and using its presence to both call custom +logic to enforce digit-only strings, and customise some generated external schema. +Users are therefore encouraged to avoid indirection like `lambda s: s.lower()`, in +favor of introspectable methods such as `str.lower` or `re.compile("pattern").search`. + +To enable basic negation of commonly used predicates like `math.isnan` without introducing introspection that makes it impossible for implementers to introspect the predicate we provide a `Not` wrapper that simply negates the predicate in an introspectable manner. Several of the predicates listed above are created in this manner. + +We do not specify what behaviour should be expected for predicates that raise +an exception. For example `Annotated[int, Predicate(str.isdigit)]` might silently +skip invalid constraints, or statically raise an error; or it might try calling it +and then propagate or discard the resulting +`TypeError: descriptor 'isdigit' for 'str' objects doesn't apply to a 'int' object` +exception. We encourage libraries to document the behaviour they choose. + +### Doc + +`doc()` can be used to add documentation information in `Annotated`, for function and method parameters, variables, class attributes, return types, and any place where `Annotated` can be used. + +It expects a value that can be statically analyzed, as the main use case is for static analysis, editors, documentation generators, and similar tools. + +It returns a `DocInfo` class with a single attribute `documentation` containing the value passed to `doc()`. + +This is the early adopter's alternative form of the [`typing-doc` proposal](https://github.com/tiangolo/fastapi/blob/typing-doc/typing_doc.md). + +### Integrating downstream types with `GroupedMetadata` + +Implementers may choose to provide a convenience wrapper that groups multiple pieces of metadata. +This can help reduce verbosity and cognitive overhead for users. +For example, an implementer like Pydantic might provide a `Field` or `Meta` type that accepts keyword arguments and transforms these into low-level metadata: + +```python +from dataclasses import dataclass +from typing import Iterator +from annotated_types import GroupedMetadata, Ge + +@dataclass +class Field(GroupedMetadata): + ge: int | None = None + description: str | None = None + + def __iter__(self) -> Iterator[object]: + # Iterating over a GroupedMetadata object should yield annotated-types + # constraint metadata objects which describe it as fully as possible, + # and may include other unknown objects too. + if self.ge is not None: + yield Ge(self.ge) + if self.description is not None: + yield Description(self.description) +``` + +Libraries consuming annotated-types constraints should check for `GroupedMetadata` and unpack it by iterating over the object and treating the results as if they had been "unpacked" in the `Annotated` type. The same logic should be applied to the [PEP 646 `Unpack` type](https://peps.python.org/pep-0646/), so that `Annotated[T, Field(...)]`, `Annotated[T, Unpack[Field(...)]]` and `Annotated[T, *Field(...)]` are all treated consistently. + +Libraries consuming annotated-types should also ignore any metadata they do not recongize that came from unpacking a `GroupedMetadata`, just like they ignore unrecognized metadata in `Annotated` itself. + +Our own `annotated_types.Interval` class is a `GroupedMetadata` which unpacks itself into `Gt`, `Lt`, etc., so this is not an abstract concern. Similarly, `annotated_types.Len` is a `GroupedMetadata` which unpacks itself into `MinLen` (optionally) and `MaxLen`. + +### Consuming metadata + +We intend to not be prescriptive as to _how_ the metadata and constraints are used, but as an example of how one might parse constraints from types annotations see our [implementation in `test_main.py`](https://github.com/annotated-types/annotated-types/blob/f59cf6d1b5255a0fe359b93896759a180bec30ae/tests/test_main.py#L94-L103). + +It is up to the implementer to determine how this metadata is used. +You could use the metadata for runtime type checking, for generating schemas or to generate example data, amongst other use cases. + +## Design & History + +This package was designed at the PyCon 2022 sprints by the maintainers of Pydantic +and Hypothesis, with the goal of making it as easy as possible for end-users to +provide more informative annotations for use by runtime libraries. + +It is deliberately minimal, and following PEP-593 allows considerable downstream +discretion in what (if anything!) they choose to support. Nonetheless, we expect +that staying simple and covering _only_ the most common use-cases will give users +and maintainers the best experience we can. If you'd like more constraints for your +types - follow our lead, by defining them and documenting them downstream! diff --git a/venv/lib/python3.12/site-packages/annotated_types-0.7.0.dist-info/RECORD b/venv/lib/python3.12/site-packages/annotated_types-0.7.0.dist-info/RECORD new file mode 100644 index 0000000..a66e278 --- /dev/null +++ b/venv/lib/python3.12/site-packages/annotated_types-0.7.0.dist-info/RECORD @@ -0,0 +1,10 @@ +annotated_types-0.7.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +annotated_types-0.7.0.dist-info/METADATA,sha256=7ltqxksJJ0wCYFGBNIQCWTlWQGeAH0hRFdnK3CB895E,15046 +annotated_types-0.7.0.dist-info/RECORD,, +annotated_types-0.7.0.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87 +annotated_types-0.7.0.dist-info/licenses/LICENSE,sha256=_hBJiEsaDZNCkB6I4H8ykl0ksxIdmXK2poBfuYJLCV0,1083 +annotated_types/__init__.py,sha256=RynLsRKUEGI0KimXydlD1fZEfEzWwDo0Uon3zOKhG1Q,13819 +annotated_types/__pycache__/__init__.cpython-312.pyc,, +annotated_types/__pycache__/test_cases.cpython-312.pyc,, +annotated_types/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +annotated_types/test_cases.py,sha256=zHFX6EpcMbGJ8FzBYDbO56bPwx_DYIVSKbZM-4B3_lg,6421 diff --git a/venv/lib/python3.12/site-packages/annotated_types-0.7.0.dist-info/WHEEL b/venv/lib/python3.12/site-packages/annotated_types-0.7.0.dist-info/WHEEL new file mode 100644 index 0000000..516596c --- /dev/null +++ b/venv/lib/python3.12/site-packages/annotated_types-0.7.0.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: hatchling 1.24.2 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/venv/lib/python3.12/site-packages/annotated_types-0.7.0.dist-info/licenses/LICENSE b/venv/lib/python3.12/site-packages/annotated_types-0.7.0.dist-info/licenses/LICENSE new file mode 100644 index 0000000..d99323a --- /dev/null +++ b/venv/lib/python3.12/site-packages/annotated_types-0.7.0.dist-info/licenses/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2022 the contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/venv/lib/python3.12/site-packages/annotated_types/__init__.py b/venv/lib/python3.12/site-packages/annotated_types/__init__.py new file mode 100644 index 0000000..74e0dee --- /dev/null +++ b/venv/lib/python3.12/site-packages/annotated_types/__init__.py @@ -0,0 +1,432 @@ +import math +import sys +import types +from dataclasses import dataclass +from datetime import tzinfo +from typing import TYPE_CHECKING, Any, Callable, Iterator, Optional, SupportsFloat, SupportsIndex, TypeVar, Union + +if sys.version_info < (3, 8): + from typing_extensions import Protocol, runtime_checkable +else: + from typing import Protocol, runtime_checkable + +if sys.version_info < (3, 9): + from typing_extensions import Annotated, Literal +else: + from typing import Annotated, Literal + +if sys.version_info < (3, 10): + EllipsisType = type(Ellipsis) + KW_ONLY = {} + SLOTS = {} +else: + from types import EllipsisType + + KW_ONLY = {"kw_only": True} + SLOTS = {"slots": True} + + +__all__ = ( + 'BaseMetadata', + 'GroupedMetadata', + 'Gt', + 'Ge', + 'Lt', + 'Le', + 'Interval', + 'MultipleOf', + 'MinLen', + 'MaxLen', + 'Len', + 'Timezone', + 'Predicate', + 'LowerCase', + 'UpperCase', + 'IsDigits', + 'IsFinite', + 'IsNotFinite', + 'IsNan', + 'IsNotNan', + 'IsInfinite', + 'IsNotInfinite', + 'doc', + 'DocInfo', + '__version__', +) + +__version__ = '0.7.0' + + +T = TypeVar('T') + + +# arguments that start with __ are considered +# positional only +# see https://peps.python.org/pep-0484/#positional-only-arguments + + +class SupportsGt(Protocol): + def __gt__(self: T, __other: T) -> bool: + ... + + +class SupportsGe(Protocol): + def __ge__(self: T, __other: T) -> bool: + ... + + +class SupportsLt(Protocol): + def __lt__(self: T, __other: T) -> bool: + ... + + +class SupportsLe(Protocol): + def __le__(self: T, __other: T) -> bool: + ... + + +class SupportsMod(Protocol): + def __mod__(self: T, __other: T) -> T: + ... + + +class SupportsDiv(Protocol): + def __div__(self: T, __other: T) -> T: + ... + + +class BaseMetadata: + """Base class for all metadata. + + This exists mainly so that implementers + can do `isinstance(..., BaseMetadata)` while traversing field annotations. + """ + + __slots__ = () + + +@dataclass(frozen=True, **SLOTS) +class Gt(BaseMetadata): + """Gt(gt=x) implies that the value must be greater than x. + + It can be used with any type that supports the ``>`` operator, + including numbers, dates and times, strings, sets, and so on. + """ + + gt: SupportsGt + + +@dataclass(frozen=True, **SLOTS) +class Ge(BaseMetadata): + """Ge(ge=x) implies that the value must be greater than or equal to x. + + It can be used with any type that supports the ``>=`` operator, + including numbers, dates and times, strings, sets, and so on. + """ + + ge: SupportsGe + + +@dataclass(frozen=True, **SLOTS) +class Lt(BaseMetadata): + """Lt(lt=x) implies that the value must be less than x. + + It can be used with any type that supports the ``<`` operator, + including numbers, dates and times, strings, sets, and so on. + """ + + lt: SupportsLt + + +@dataclass(frozen=True, **SLOTS) +class Le(BaseMetadata): + """Le(le=x) implies that the value must be less than or equal to x. + + It can be used with any type that supports the ``<=`` operator, + including numbers, dates and times, strings, sets, and so on. + """ + + le: SupportsLe + + +@runtime_checkable +class GroupedMetadata(Protocol): + """A grouping of multiple objects, like typing.Unpack. + + `GroupedMetadata` on its own is not metadata and has no meaning. + All of the constraints and metadata should be fully expressable + in terms of the `BaseMetadata`'s returned by `GroupedMetadata.__iter__()`. + + Concrete implementations should override `GroupedMetadata.__iter__()` + to add their own metadata. + For example: + + >>> @dataclass + >>> class Field(GroupedMetadata): + >>> gt: float | None = None + >>> description: str | None = None + ... + >>> def __iter__(self) -> Iterable[object]: + >>> if self.gt is not None: + >>> yield Gt(self.gt) + >>> if self.description is not None: + >>> yield Description(self.gt) + + Also see the implementation of `Interval` below for an example. + + Parsers should recognize this and unpack it so that it can be used + both with and without unpacking: + + - `Annotated[int, Field(...)]` (parser must unpack Field) + - `Annotated[int, *Field(...)]` (PEP-646) + """ # noqa: trailing-whitespace + + @property + def __is_annotated_types_grouped_metadata__(self) -> Literal[True]: + return True + + def __iter__(self) -> Iterator[object]: + ... + + if not TYPE_CHECKING: + __slots__ = () # allow subclasses to use slots + + def __init_subclass__(cls, *args: Any, **kwargs: Any) -> None: + # Basic ABC like functionality without the complexity of an ABC + super().__init_subclass__(*args, **kwargs) + if cls.__iter__ is GroupedMetadata.__iter__: + raise TypeError("Can't subclass GroupedMetadata without implementing __iter__") + + def __iter__(self) -> Iterator[object]: # noqa: F811 + raise NotImplementedError # more helpful than "None has no attribute..." type errors + + +@dataclass(frozen=True, **KW_ONLY, **SLOTS) +class Interval(GroupedMetadata): + """Interval can express inclusive or exclusive bounds with a single object. + + It accepts keyword arguments ``gt``, ``ge``, ``lt``, and/or ``le``, which + are interpreted the same way as the single-bound constraints. + """ + + gt: Union[SupportsGt, None] = None + ge: Union[SupportsGe, None] = None + lt: Union[SupportsLt, None] = None + le: Union[SupportsLe, None] = None + + def __iter__(self) -> Iterator[BaseMetadata]: + """Unpack an Interval into zero or more single-bounds.""" + if self.gt is not None: + yield Gt(self.gt) + if self.ge is not None: + yield Ge(self.ge) + if self.lt is not None: + yield Lt(self.lt) + if self.le is not None: + yield Le(self.le) + + +@dataclass(frozen=True, **SLOTS) +class MultipleOf(BaseMetadata): + """MultipleOf(multiple_of=x) might be interpreted in two ways: + + 1. Python semantics, implying ``value % multiple_of == 0``, or + 2. JSONschema semantics, where ``int(value / multiple_of) == value / multiple_of`` + + We encourage users to be aware of these two common interpretations, + and libraries to carefully document which they implement. + """ + + multiple_of: Union[SupportsDiv, SupportsMod] + + +@dataclass(frozen=True, **SLOTS) +class MinLen(BaseMetadata): + """ + MinLen() implies minimum inclusive length, + e.g. ``len(value) >= min_length``. + """ + + min_length: Annotated[int, Ge(0)] + + +@dataclass(frozen=True, **SLOTS) +class MaxLen(BaseMetadata): + """ + MaxLen() implies maximum inclusive length, + e.g. ``len(value) <= max_length``. + """ + + max_length: Annotated[int, Ge(0)] + + +@dataclass(frozen=True, **SLOTS) +class Len(GroupedMetadata): + """ + Len() implies that ``min_length <= len(value) <= max_length``. + + Upper bound may be omitted or ``None`` to indicate no upper length bound. + """ + + min_length: Annotated[int, Ge(0)] = 0 + max_length: Optional[Annotated[int, Ge(0)]] = None + + def __iter__(self) -> Iterator[BaseMetadata]: + """Unpack a Len into zone or more single-bounds.""" + if self.min_length > 0: + yield MinLen(self.min_length) + if self.max_length is not None: + yield MaxLen(self.max_length) + + +@dataclass(frozen=True, **SLOTS) +class Timezone(BaseMetadata): + """Timezone(tz=...) requires a datetime to be aware (or ``tz=None``, naive). + + ``Annotated[datetime, Timezone(None)]`` must be a naive datetime. + ``Timezone[...]`` (the ellipsis literal) expresses that the datetime must be + tz-aware but any timezone is allowed. + + You may also pass a specific timezone string or tzinfo object such as + ``Timezone(timezone.utc)`` or ``Timezone("Africa/Abidjan")`` to express that + you only allow a specific timezone, though we note that this is often + a symptom of poor design. + """ + + tz: Union[str, tzinfo, EllipsisType, None] + + +@dataclass(frozen=True, **SLOTS) +class Unit(BaseMetadata): + """Indicates that the value is a physical quantity with the specified unit. + + It is intended for usage with numeric types, where the value represents the + magnitude of the quantity. For example, ``distance: Annotated[float, Unit('m')]`` + or ``speed: Annotated[float, Unit('m/s')]``. + + Interpretation of the unit string is left to the discretion of the consumer. + It is suggested to follow conventions established by python libraries that work + with physical quantities, such as + + - ``pint`` : + - ``astropy.units``: + + For indicating a quantity with a certain dimensionality but without a specific unit + it is recommended to use square brackets, e.g. `Annotated[float, Unit('[time]')]`. + Note, however, ``annotated_types`` itself makes no use of the unit string. + """ + + unit: str + + +@dataclass(frozen=True, **SLOTS) +class Predicate(BaseMetadata): + """``Predicate(func: Callable)`` implies `func(value)` is truthy for valid values. + + Users should prefer statically inspectable metadata, but if you need the full + power and flexibility of arbitrary runtime predicates... here it is. + + We provide a few predefined predicates for common string constraints: + ``IsLower = Predicate(str.islower)``, ``IsUpper = Predicate(str.isupper)``, and + ``IsDigits = Predicate(str.isdigit)``. Users are encouraged to use methods which + can be given special handling, and avoid indirection like ``lambda s: s.lower()``. + + Some libraries might have special logic to handle certain predicates, e.g. by + checking for `str.isdigit` and using its presence to both call custom logic to + enforce digit-only strings, and customise some generated external schema. + + We do not specify what behaviour should be expected for predicates that raise + an exception. For example `Annotated[int, Predicate(str.isdigit)]` might silently + skip invalid constraints, or statically raise an error; or it might try calling it + and then propagate or discard the resulting exception. + """ + + func: Callable[[Any], bool] + + def __repr__(self) -> str: + if getattr(self.func, "__name__", "") == "": + return f"{self.__class__.__name__}({self.func!r})" + if isinstance(self.func, (types.MethodType, types.BuiltinMethodType)) and ( + namespace := getattr(self.func.__self__, "__name__", None) + ): + return f"{self.__class__.__name__}({namespace}.{self.func.__name__})" + if isinstance(self.func, type(str.isascii)): # method descriptor + return f"{self.__class__.__name__}({self.func.__qualname__})" + return f"{self.__class__.__name__}({self.func.__name__})" + + +@dataclass +class Not: + func: Callable[[Any], bool] + + def __call__(self, __v: Any) -> bool: + return not self.func(__v) + + +_StrType = TypeVar("_StrType", bound=str) + +LowerCase = Annotated[_StrType, Predicate(str.islower)] +""" +Return True if the string is a lowercase string, False otherwise. + +A string is lowercase if all cased characters in the string are lowercase and there is at least one cased character in the string. +""" # noqa: E501 +UpperCase = Annotated[_StrType, Predicate(str.isupper)] +""" +Return True if the string is an uppercase string, False otherwise. + +A string is uppercase if all cased characters in the string are uppercase and there is at least one cased character in the string. +""" # noqa: E501 +IsDigit = Annotated[_StrType, Predicate(str.isdigit)] +IsDigits = IsDigit # type: ignore # plural for backwards compatibility, see #63 +""" +Return True if the string is a digit string, False otherwise. + +A string is a digit string if all characters in the string are digits and there is at least one character in the string. +""" # noqa: E501 +IsAscii = Annotated[_StrType, Predicate(str.isascii)] +""" +Return True if all characters in the string are ASCII, False otherwise. + +ASCII characters have code points in the range U+0000-U+007F. Empty string is ASCII too. +""" + +_NumericType = TypeVar('_NumericType', bound=Union[SupportsFloat, SupportsIndex]) +IsFinite = Annotated[_NumericType, Predicate(math.isfinite)] +"""Return True if x is neither an infinity nor a NaN, and False otherwise.""" +IsNotFinite = Annotated[_NumericType, Predicate(Not(math.isfinite))] +"""Return True if x is one of infinity or NaN, and False otherwise""" +IsNan = Annotated[_NumericType, Predicate(math.isnan)] +"""Return True if x is a NaN (not a number), and False otherwise.""" +IsNotNan = Annotated[_NumericType, Predicate(Not(math.isnan))] +"""Return True if x is anything but NaN (not a number), and False otherwise.""" +IsInfinite = Annotated[_NumericType, Predicate(math.isinf)] +"""Return True if x is a positive or negative infinity, and False otherwise.""" +IsNotInfinite = Annotated[_NumericType, Predicate(Not(math.isinf))] +"""Return True if x is neither a positive or negative infinity, and False otherwise.""" + +try: + from typing_extensions import DocInfo, doc # type: ignore [attr-defined] +except ImportError: + + @dataclass(frozen=True, **SLOTS) + class DocInfo: # type: ignore [no-redef] + """ " + The return value of doc(), mainly to be used by tools that want to extract the + Annotated documentation at runtime. + """ + + documentation: str + """The documentation string passed to doc().""" + + def doc( + documentation: str, + ) -> DocInfo: + """ + Add documentation to a type annotation inside of Annotated. + + For example: + + >>> def hi(name: Annotated[int, doc("The name of the user")]) -> None: ... + """ + return DocInfo(documentation) diff --git a/venv/lib/python3.12/site-packages/annotated_types/__pycache__/__init__.cpython-312.pyc b/venv/lib/python3.12/site-packages/annotated_types/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d4bbf35c9f299ad927b71bd4a96e792515e835a9 GIT binary patch literal 18634 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/annotated_types/__pycache__/test_cases.cpython-312.pyc b/venv/lib/python3.12/site-packages/annotated_types/__pycache__/test_cases.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8a1c454f922b486cdd26a3f9461b9cdc763bc9ea GIT binary patch literal 13253 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/annotated_types/py.typed b/venv/lib/python3.12/site-packages/annotated_types/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.12/site-packages/annotated_types/test_cases.py b/venv/lib/python3.12/site-packages/annotated_types/test_cases.py new file mode 100644 index 0000000..d9164d6 --- /dev/null +++ b/venv/lib/python3.12/site-packages/annotated_types/test_cases.py @@ -0,0 +1,151 @@ +import math +import sys +from datetime import date, datetime, timedelta, timezone +from decimal import Decimal +from typing import Any, Dict, Iterable, Iterator, List, NamedTuple, Set, Tuple + +if sys.version_info < (3, 9): + from typing_extensions import Annotated +else: + from typing import Annotated + +import annotated_types as at + + +class Case(NamedTuple): + """ + A test case for `annotated_types`. + """ + + annotation: Any + valid_cases: Iterable[Any] + invalid_cases: Iterable[Any] + + +def cases() -> Iterable[Case]: + # Gt, Ge, Lt, Le + yield Case(Annotated[int, at.Gt(4)], (5, 6, 1000), (4, 0, -1)) + yield Case(Annotated[float, at.Gt(0.5)], (0.6, 0.7, 0.8, 0.9), (0.5, 0.0, -0.1)) + yield Case( + Annotated[datetime, at.Gt(datetime(2000, 1, 1))], + [datetime(2000, 1, 2), datetime(2000, 1, 3)], + [datetime(2000, 1, 1), datetime(1999, 12, 31)], + ) + yield Case( + Annotated[datetime, at.Gt(date(2000, 1, 1))], + [date(2000, 1, 2), date(2000, 1, 3)], + [date(2000, 1, 1), date(1999, 12, 31)], + ) + yield Case( + Annotated[datetime, at.Gt(Decimal('1.123'))], + [Decimal('1.1231'), Decimal('123')], + [Decimal('1.123'), Decimal('0')], + ) + + yield Case(Annotated[int, at.Ge(4)], (4, 5, 6, 1000, 4), (0, -1)) + yield Case(Annotated[float, at.Ge(0.5)], (0.5, 0.6, 0.7, 0.8, 0.9), (0.4, 0.0, -0.1)) + yield Case( + Annotated[datetime, at.Ge(datetime(2000, 1, 1))], + [datetime(2000, 1, 2), datetime(2000, 1, 3)], + [datetime(1998, 1, 1), datetime(1999, 12, 31)], + ) + + yield Case(Annotated[int, at.Lt(4)], (0, -1), (4, 5, 6, 1000, 4)) + yield Case(Annotated[float, at.Lt(0.5)], (0.4, 0.0, -0.1), (0.5, 0.6, 0.7, 0.8, 0.9)) + yield Case( + Annotated[datetime, at.Lt(datetime(2000, 1, 1))], + [datetime(1999, 12, 31), datetime(1999, 12, 31)], + [datetime(2000, 1, 2), datetime(2000, 1, 3)], + ) + + yield Case(Annotated[int, at.Le(4)], (4, 0, -1), (5, 6, 1000)) + yield Case(Annotated[float, at.Le(0.5)], (0.5, 0.0, -0.1), (0.6, 0.7, 0.8, 0.9)) + yield Case( + Annotated[datetime, at.Le(datetime(2000, 1, 1))], + [datetime(2000, 1, 1), datetime(1999, 12, 31)], + [datetime(2000, 1, 2), datetime(2000, 1, 3)], + ) + + # Interval + yield Case(Annotated[int, at.Interval(gt=4)], (5, 6, 1000), (4, 0, -1)) + yield Case(Annotated[int, at.Interval(gt=4, lt=10)], (5, 6), (4, 10, 1000, 0, -1)) + yield Case(Annotated[float, at.Interval(ge=0.5, le=1)], (0.5, 0.9, 1), (0.49, 1.1)) + yield Case( + Annotated[datetime, at.Interval(gt=datetime(2000, 1, 1), le=datetime(2000, 1, 3))], + [datetime(2000, 1, 2), datetime(2000, 1, 3)], + [datetime(2000, 1, 1), datetime(2000, 1, 4)], + ) + + yield Case(Annotated[int, at.MultipleOf(multiple_of=3)], (0, 3, 9), (1, 2, 4)) + yield Case(Annotated[float, at.MultipleOf(multiple_of=0.5)], (0, 0.5, 1, 1.5), (0.4, 1.1)) + + # lengths + + yield Case(Annotated[str, at.MinLen(3)], ('123', '1234', 'x' * 10), ('', '1', '12')) + yield Case(Annotated[str, at.Len(3)], ('123', '1234', 'x' * 10), ('', '1', '12')) + yield Case(Annotated[List[int], at.MinLen(3)], ([1, 2, 3], [1, 2, 3, 4], [1] * 10), ([], [1], [1, 2])) + yield Case(Annotated[List[int], at.Len(3)], ([1, 2, 3], [1, 2, 3, 4], [1] * 10), ([], [1], [1, 2])) + + yield Case(Annotated[str, at.MaxLen(4)], ('', '1234'), ('12345', 'x' * 10)) + yield Case(Annotated[str, at.Len(0, 4)], ('', '1234'), ('12345', 'x' * 10)) + yield Case(Annotated[List[str], at.MaxLen(4)], ([], ['a', 'bcdef'], ['a', 'b', 'c']), (['a'] * 5, ['b'] * 10)) + yield Case(Annotated[List[str], at.Len(0, 4)], ([], ['a', 'bcdef'], ['a', 'b', 'c']), (['a'] * 5, ['b'] * 10)) + + yield Case(Annotated[str, at.Len(3, 5)], ('123', '12345'), ('', '1', '12', '123456', 'x' * 10)) + yield Case(Annotated[str, at.Len(3, 3)], ('123',), ('12', '1234')) + + yield Case(Annotated[Dict[int, int], at.Len(2, 3)], [{1: 1, 2: 2}], [{}, {1: 1}, {1: 1, 2: 2, 3: 3, 4: 4}]) + yield Case(Annotated[Set[int], at.Len(2, 3)], ({1, 2}, {1, 2, 3}), (set(), {1}, {1, 2, 3, 4})) + yield Case(Annotated[Tuple[int, ...], at.Len(2, 3)], ((1, 2), (1, 2, 3)), ((), (1,), (1, 2, 3, 4))) + + # Timezone + + yield Case( + Annotated[datetime, at.Timezone(None)], [datetime(2000, 1, 1)], [datetime(2000, 1, 1, tzinfo=timezone.utc)] + ) + yield Case( + Annotated[datetime, at.Timezone(...)], [datetime(2000, 1, 1, tzinfo=timezone.utc)], [datetime(2000, 1, 1)] + ) + yield Case( + Annotated[datetime, at.Timezone(timezone.utc)], + [datetime(2000, 1, 1, tzinfo=timezone.utc)], + [datetime(2000, 1, 1), datetime(2000, 1, 1, tzinfo=timezone(timedelta(hours=6)))], + ) + yield Case( + Annotated[datetime, at.Timezone('Europe/London')], + [datetime(2000, 1, 1, tzinfo=timezone(timedelta(0), name='Europe/London'))], + [datetime(2000, 1, 1), datetime(2000, 1, 1, tzinfo=timezone(timedelta(hours=6)))], + ) + + # Quantity + + yield Case(Annotated[float, at.Unit(unit='m')], (5, 4.2), ('5m', '4.2m')) + + # predicate types + + yield Case(at.LowerCase[str], ['abc', 'foobar'], ['', 'A', 'Boom']) + yield Case(at.UpperCase[str], ['ABC', 'DEFO'], ['', 'a', 'abc', 'AbC']) + yield Case(at.IsDigit[str], ['123'], ['', 'ab', 'a1b2']) + yield Case(at.IsAscii[str], ['123', 'foo bar'], ['£100', '😊', 'whatever 👀']) + + yield Case(Annotated[int, at.Predicate(lambda x: x % 2 == 0)], [0, 2, 4], [1, 3, 5]) + + yield Case(at.IsFinite[float], [1.23], [math.nan, math.inf, -math.inf]) + yield Case(at.IsNotFinite[float], [math.nan, math.inf], [1.23]) + yield Case(at.IsNan[float], [math.nan], [1.23, math.inf]) + yield Case(at.IsNotNan[float], [1.23, math.inf], [math.nan]) + yield Case(at.IsInfinite[float], [math.inf], [math.nan, 1.23]) + yield Case(at.IsNotInfinite[float], [math.nan, 1.23], [math.inf]) + + # check stacked predicates + yield Case(at.IsInfinite[Annotated[float, at.Predicate(lambda x: x > 0)]], [math.inf], [-math.inf, 1.23, math.nan]) + + # doc + yield Case(Annotated[int, at.doc("A number")], [1, 2], []) + + # custom GroupedMetadata + class MyCustomGroupedMetadata(at.GroupedMetadata): + def __iter__(self) -> Iterator[at.Predicate]: + yield at.Predicate(lambda x: float(x).is_integer()) + + yield Case(Annotated[float, MyCustomGroupedMetadata()], [0, 2.0], [0.01, 1.5]) diff --git a/venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/INSTALLER b/venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/METADATA b/venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/METADATA new file mode 100644 index 0000000..2de1cd5 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/METADATA @@ -0,0 +1,105 @@ +Metadata-Version: 2.4 +Name: anyio +Version: 4.13.0 +Summary: High-level concurrency and networking framework on top of asyncio or Trio +Author-email: Alex Grönholm +License-Expression: MIT +Project-URL: Documentation, https://anyio.readthedocs.io/en/latest/ +Project-URL: Changelog, https://anyio.readthedocs.io/en/stable/versionhistory.html +Project-URL: Source code, https://github.com/agronholm/anyio +Project-URL: Issue tracker, https://github.com/agronholm/anyio/issues +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Framework :: AnyIO +Classifier: Typing :: Typed +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Requires-Python: >=3.10 +Description-Content-Type: text/x-rst +License-File: LICENSE +Requires-Dist: exceptiongroup>=1.0.2; python_version < "3.11" +Requires-Dist: idna>=2.8 +Requires-Dist: typing_extensions>=4.5; python_version < "3.13" +Provides-Extra: trio +Requires-Dist: trio>=0.32.0; extra == "trio" +Dynamic: license-file + +.. image:: https://github.com/agronholm/anyio/actions/workflows/test.yml/badge.svg + :target: https://github.com/agronholm/anyio/actions/workflows/test.yml + :alt: Build Status +.. image:: https://coveralls.io/repos/github/agronholm/anyio/badge.svg?branch=master + :target: https://coveralls.io/github/agronholm/anyio?branch=master + :alt: Code Coverage +.. image:: https://readthedocs.org/projects/anyio/badge/?version=latest + :target: https://anyio.readthedocs.io/en/latest/?badge=latest + :alt: Documentation +.. image:: https://badges.gitter.im/gitterHQ/gitter.svg + :target: https://gitter.im/python-trio/AnyIO + :alt: Gitter chat +.. image:: https://tidelift.com/badges/package/pypi/anyio + :target: https://tidelift.com/subscription/pkg/pypi-anyio + :alt: Tidelift + +AnyIO is an asynchronous networking and concurrency library that works on top of either asyncio_ or +Trio_. It implements Trio-like `structured concurrency`_ (SC) on top of asyncio and works in harmony +with the native SC of Trio itself. + +Applications and libraries written against AnyIO's API will run unmodified on either asyncio_ or +Trio_. AnyIO can also be adopted into a library or application incrementally – bit by bit, no full +refactoring necessary. It will blend in with the native libraries of your chosen backend. + +To find out why you might want to use AnyIO's APIs instead of asyncio's, you can read about it +`here `_. + +Documentation +------------- + +View full documentation at: https://anyio.readthedocs.io/ + +Features +-------- + +AnyIO offers the following functionality: + +* Task groups (nurseries_ in trio terminology) +* High-level networking (TCP, UDP and UNIX sockets) + + * `Happy eyeballs`_ algorithm for TCP connections (more robust than that of asyncio on Python + 3.8) + * async/await style UDP sockets (unlike asyncio where you still have to use Transports and + Protocols) + +* A versatile API for byte streams and object streams +* Inter-task synchronization and communication (locks, conditions, events, semaphores, object + streams) +* Worker threads +* Subprocesses +* Subinterpreter support for code parallelization (on Python 3.13 and later) +* Asynchronous file I/O (using worker threads) +* Signal handling +* Asynchronous version of the functools_ module + +AnyIO also comes with its own pytest_ plugin which also supports asynchronous fixtures. +It even works with the popular Hypothesis_ library. + +.. _asyncio: https://docs.python.org/3/library/asyncio.html +.. _Trio: https://github.com/python-trio/trio +.. _structured concurrency: https://en.wikipedia.org/wiki/Structured_concurrency +.. _nurseries: https://trio.readthedocs.io/en/stable/reference-core.html#nurseries-and-spawning +.. _Happy eyeballs: https://en.wikipedia.org/wiki/Happy_Eyeballs +.. _pytest: https://docs.pytest.org/en/latest/ +.. _functools: https://docs.python.org/3/library/functools.html +.. _Hypothesis: https://hypothesis.works/ + +Security contact information +---------------------------- + +To report a security vulnerability, please use the `Tidelift security contact`_. +Tidelift will coordinate the fix and disclosure. + +.. _Tidelift security contact: https://tidelift.com/security diff --git a/venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/RECORD b/venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/RECORD new file mode 100644 index 0000000..e5f678c --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/RECORD @@ -0,0 +1,92 @@ +anyio-4.13.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +anyio-4.13.0.dist-info/METADATA,sha256=F0EYfiPlmTRwmJN2JktNxJg1GNnl0wHhzOWmz7pFvjM,4513 +anyio-4.13.0.dist-info/RECORD,, +anyio-4.13.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91 +anyio-4.13.0.dist-info/entry_points.txt,sha256=_d6Yu6uiaZmNe0CydowirE9Cmg7zUL2g08tQpoS3Qvc,39 +anyio-4.13.0.dist-info/licenses/LICENSE,sha256=U2GsncWPLvX9LpsJxoKXwX8ElQkJu8gCO9uC6s8iwrA,1081 +anyio-4.13.0.dist-info/top_level.txt,sha256=QglSMiWX8_5dpoVAEIHdEYzvqFMdSYWmCj6tYw2ITkQ,6 +anyio/__init__.py,sha256=7iDVqMUprUuKNY91FuoKqayAhR-OY136YDPI6P78HHk,6170 +anyio/__pycache__/__init__.cpython-312.pyc,, +anyio/__pycache__/from_thread.cpython-312.pyc,, +anyio/__pycache__/functools.cpython-312.pyc,, +anyio/__pycache__/lowlevel.cpython-312.pyc,, +anyio/__pycache__/pytest_plugin.cpython-312.pyc,, +anyio/__pycache__/to_interpreter.cpython-312.pyc,, +anyio/__pycache__/to_process.cpython-312.pyc,, +anyio/__pycache__/to_thread.cpython-312.pyc,, +anyio/_backends/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +anyio/_backends/__pycache__/__init__.cpython-312.pyc,, +anyio/_backends/__pycache__/_asyncio.cpython-312.pyc,, +anyio/_backends/__pycache__/_trio.cpython-312.pyc,, +anyio/_backends/_asyncio.py,sha256=kuqlg2sBUsFdgY80xSDAw60Gx_4WNCl9iSL5XlY6lCU,99476 +anyio/_backends/_trio.py,sha256=l9U-TsKRxzmTQxSMvOhn0bNeFn_iRx3Ho30jvR5Bdu0,41366 +anyio/_core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +anyio/_core/__pycache__/__init__.cpython-312.pyc,, +anyio/_core/__pycache__/_asyncio_selector_thread.cpython-312.pyc,, +anyio/_core/__pycache__/_contextmanagers.cpython-312.pyc,, +anyio/_core/__pycache__/_eventloop.cpython-312.pyc,, +anyio/_core/__pycache__/_exceptions.cpython-312.pyc,, +anyio/_core/__pycache__/_fileio.cpython-312.pyc,, +anyio/_core/__pycache__/_resources.cpython-312.pyc,, +anyio/_core/__pycache__/_signals.cpython-312.pyc,, +anyio/_core/__pycache__/_sockets.cpython-312.pyc,, +anyio/_core/__pycache__/_streams.cpython-312.pyc,, +anyio/_core/__pycache__/_subprocesses.cpython-312.pyc,, +anyio/_core/__pycache__/_synchronization.cpython-312.pyc,, +anyio/_core/__pycache__/_tasks.cpython-312.pyc,, +anyio/_core/__pycache__/_tempfile.cpython-312.pyc,, +anyio/_core/__pycache__/_testing.cpython-312.pyc,, +anyio/_core/__pycache__/_typedattr.cpython-312.pyc,, +anyio/_core/_asyncio_selector_thread.py,sha256=2PdxFM3cs02Kp6BSppbvmRT7q7asreTW5FgBxEsflBo,5626 +anyio/_core/_contextmanagers.py,sha256=YInBCabiEeS-UaP_Jdxa1CaFC71ETPW8HZTHIM8Rsc8,7215 +anyio/_core/_eventloop.py,sha256=c2EdcBX-xnKwxPcC4Pjn3_qG9I-x4IWFO2R9RqCGjM4,6448 +anyio/_core/_exceptions.py,sha256=Y3aq-Wxd7Q2HqwSg7nZPvRsHEuGazv_qeet6gqEBdPk,4407 +anyio/_core/_fileio.py,sha256=CKi1gFNiW2G4knWeBE7He7-rptQwgYjDUWfG8DSlvLs,25665 +anyio/_core/_resources.py,sha256=NbmU5O5UX3xEyACnkmYX28Fmwdl-f-ny0tHym26e0w0,435 +anyio/_core/_signals.py,sha256=mjTBB2hTKNPRlU0IhnijeQedpWOGERDiMjSlJQsFrug,1016 +anyio/_core/_sockets.py,sha256=RBXHcUqZt5gg_-OOfgHVv8uq2FSKk1uVUzTdpjBoI1o,34977 +anyio/_core/_streams.py,sha256=FczFwIgDpnkK0bODWJXMpsUJYdvAD04kaUaGzJU8DK0,1806 +anyio/_core/_subprocesses.py,sha256=tkmkPKEkEaiMD8C9WRZBlmgjOYRDRbZdte6e-unay2E,7916 +anyio/_core/_synchronization.py,sha256=9G3fvRsPNrrWJ_Z6gD_80wXq8I8qgAyhwM8PvHQnT2c,21061 +anyio/_core/_tasks.py,sha256=pVB7K6AAulzUM8YgXAeqNZG44nSyZ1bYJjH8GznC00I,5435 +anyio/_core/_tempfile.py,sha256=jE2w59FRF3yRo4vjkjfZF2YcqsBZvc66VWRwrJGDYGk,19624 +anyio/_core/_testing.py,sha256=u7MPqGXwpTxqI7hclSdNA30z2GH1Nw258uwKvy_RfBg,2340 +anyio/_core/_typedattr.py,sha256=P4ozZikn3-DbpoYcvyghS_FOYAgbmUxeoU8-L_07pZM,2508 +anyio/abc/__init__.py,sha256=6mWhcl_pGXhrgZVHP_TCfMvIXIOp9mroEFM90fYCU_U,2869 +anyio/abc/__pycache__/__init__.cpython-312.pyc,, +anyio/abc/__pycache__/_eventloop.cpython-312.pyc,, +anyio/abc/__pycache__/_resources.cpython-312.pyc,, +anyio/abc/__pycache__/_sockets.cpython-312.pyc,, +anyio/abc/__pycache__/_streams.cpython-312.pyc,, +anyio/abc/__pycache__/_subprocesses.cpython-312.pyc,, +anyio/abc/__pycache__/_tasks.cpython-312.pyc,, +anyio/abc/__pycache__/_testing.cpython-312.pyc,, +anyio/abc/_eventloop.py,sha256=39lYnmtvoHaZw22sWBKOTA_zv7bamOnr8O49PqgDXdw,10629 +anyio/abc/_resources.py,sha256=DrYvkNN1hH6Uvv5_5uKySvDsnknGVDe8FCKfko0VtN8,783 +anyio/abc/_sockets.py,sha256=OmVDrfemVvF9c5K1tpBgQyV6fn5v0XyCExLAqBOGz9o,13124 +anyio/abc/_streams.py,sha256=HYvna1iZbWcwLROTO6IhLX79RTRLPShZMWe0sG1q54I,7481 +anyio/abc/_subprocesses.py,sha256=cumAPJTktOQtw63IqG0lDpyZqu_l1EElvQHMiwJgL08,2067 +anyio/abc/_tasks.py,sha256=KC7wrciE48AINOI-AhPutnFhe1ewfP7QnamFlDzqesQ,3721 +anyio/abc/_testing.py,sha256=tBJUzkSfOXJw23fe8qSJ03kJlShOYjjaEyFB6k6MYT8,1821 +anyio/from_thread.py,sha256=L-0w1HxJ6BSb-KuVi57k5Tkc3yzQrx3QK5tAxMPcY-0,19141 +anyio/functools.py,sha256=5AWM1iYTKkTzptvUhQDdLSh5GvbBW-vcs-SAUfIfA9A,12076 +anyio/lowlevel.py,sha256=AyKLVK3LaWSoK39LkCKxE4_GDMLKZBNqTrLUgk63y80,5158 +anyio/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +anyio/pytest_plugin.py,sha256=t6h4KJstqIxfxwTZ1YO8vpUVuB99nfCLltn0NHfatHo,12775 +anyio/streams/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +anyio/streams/__pycache__/__init__.cpython-312.pyc,, +anyio/streams/__pycache__/buffered.cpython-312.pyc,, +anyio/streams/__pycache__/file.cpython-312.pyc,, +anyio/streams/__pycache__/memory.cpython-312.pyc,, +anyio/streams/__pycache__/stapled.cpython-312.pyc,, +anyio/streams/__pycache__/text.cpython-312.pyc,, +anyio/streams/__pycache__/tls.cpython-312.pyc,, +anyio/streams/buffered.py,sha256=2R3PeJhe4EXrdYqz44Y6-Eg9R6DrmlsYrP36Ir43-po,6263 +anyio/streams/file.py,sha256=msnrotVKGMQomUu_Rj2qz9MvIdUp6d3JGr7MOEO8kV4,4428 +anyio/streams/memory.py,sha256=F0zwzvFJKAhX_LRZGoKzzqDC2oMM-f-yyTBrEYEGOaU,10740 +anyio/streams/stapled.py,sha256=T8Xqwf8K6EgURPxbt1N4i7A8BAk-gScv-GRhjLXIf_o,4390 +anyio/streams/text.py,sha256=BcVAGJw1VRvtIqnv-o0Rb0pwH7p8vwlvl21xHq522ag,5765 +anyio/streams/tls.py,sha256=DQVkXUvsTEYKkBO8dlVU7j_5H8QOtLy4sGi1Wrjqevo,15303 +anyio/to_interpreter.py,sha256=_mLngrMy97TMR6VbW4Y6YzDUk9ZuPcQMPlkuyRh3C9k,7100 +anyio/to_process.py,sha256=J7gAA_YOuoHqnpDAf5fm1Qu6kOmTzdFbiDNvnV755vk,9798 +anyio/to_thread.py,sha256=f6h_k2d743GBv9FhAnhM_YpTvWgIrzBy9cOE0eJ1UJw,2693 diff --git a/venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/WHEEL b/venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/WHEEL new file mode 100644 index 0000000..14a883f --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: setuptools (82.0.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/entry_points.txt b/venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/entry_points.txt new file mode 100644 index 0000000..44dd9bd --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[pytest11] +anyio = anyio.pytest_plugin diff --git a/venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/licenses/LICENSE b/venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/licenses/LICENSE new file mode 100644 index 0000000..104eebf --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/licenses/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2018 Alex Grönholm + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/top_level.txt b/venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/top_level.txt new file mode 100644 index 0000000..c77c069 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio-4.13.0.dist-info/top_level.txt @@ -0,0 +1 @@ +anyio diff --git a/venv/lib/python3.12/site-packages/anyio/__init__.py b/venv/lib/python3.12/site-packages/anyio/__init__.py new file mode 100644 index 0000000..d23c5a5 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/__init__.py @@ -0,0 +1,111 @@ +from __future__ import annotations + +from ._core._contextmanagers import AsyncContextManagerMixin as AsyncContextManagerMixin +from ._core._contextmanagers import ContextManagerMixin as ContextManagerMixin +from ._core._eventloop import current_time as current_time +from ._core._eventloop import get_all_backends as get_all_backends +from ._core._eventloop import get_available_backends as get_available_backends +from ._core._eventloop import get_cancelled_exc_class as get_cancelled_exc_class +from ._core._eventloop import run as run +from ._core._eventloop import sleep as sleep +from ._core._eventloop import sleep_forever as sleep_forever +from ._core._eventloop import sleep_until as sleep_until +from ._core._exceptions import BrokenResourceError as BrokenResourceError +from ._core._exceptions import BrokenWorkerInterpreter as BrokenWorkerInterpreter +from ._core._exceptions import BrokenWorkerProcess as BrokenWorkerProcess +from ._core._exceptions import BusyResourceError as BusyResourceError +from ._core._exceptions import ClosedResourceError as ClosedResourceError +from ._core._exceptions import ConnectionFailed as ConnectionFailed +from ._core._exceptions import DelimiterNotFound as DelimiterNotFound +from ._core._exceptions import EndOfStream as EndOfStream +from ._core._exceptions import IncompleteRead as IncompleteRead +from ._core._exceptions import NoEventLoopError as NoEventLoopError +from ._core._exceptions import RunFinishedError as RunFinishedError +from ._core._exceptions import TypedAttributeLookupError as TypedAttributeLookupError +from ._core._exceptions import WouldBlock as WouldBlock +from ._core._fileio import AsyncFile as AsyncFile +from ._core._fileio import Path as Path +from ._core._fileio import open_file as open_file +from ._core._fileio import wrap_file as wrap_file +from ._core._resources import aclose_forcefully as aclose_forcefully +from ._core._signals import open_signal_receiver as open_signal_receiver +from ._core._sockets import TCPConnectable as TCPConnectable +from ._core._sockets import UNIXConnectable as UNIXConnectable +from ._core._sockets import as_connectable as as_connectable +from ._core._sockets import connect_tcp as connect_tcp +from ._core._sockets import connect_unix as connect_unix +from ._core._sockets import create_connected_udp_socket as create_connected_udp_socket +from ._core._sockets import ( + create_connected_unix_datagram_socket as create_connected_unix_datagram_socket, +) +from ._core._sockets import create_tcp_listener as create_tcp_listener +from ._core._sockets import create_udp_socket as create_udp_socket +from ._core._sockets import create_unix_datagram_socket as create_unix_datagram_socket +from ._core._sockets import create_unix_listener as create_unix_listener +from ._core._sockets import getaddrinfo as getaddrinfo +from ._core._sockets import getnameinfo as getnameinfo +from ._core._sockets import notify_closing as notify_closing +from ._core._sockets import wait_readable as wait_readable +from ._core._sockets import wait_socket_readable as wait_socket_readable +from ._core._sockets import wait_socket_writable as wait_socket_writable +from ._core._sockets import wait_writable as wait_writable +from ._core._streams import create_memory_object_stream as create_memory_object_stream +from ._core._subprocesses import open_process as open_process +from ._core._subprocesses import run_process as run_process +from ._core._synchronization import CapacityLimiter as CapacityLimiter +from ._core._synchronization import ( + CapacityLimiterStatistics as CapacityLimiterStatistics, +) +from ._core._synchronization import Condition as Condition +from ._core._synchronization import ConditionStatistics as ConditionStatistics +from ._core._synchronization import Event as Event +from ._core._synchronization import EventStatistics as EventStatistics +from ._core._synchronization import Lock as Lock +from ._core._synchronization import LockStatistics as LockStatistics +from ._core._synchronization import ResourceGuard as ResourceGuard +from ._core._synchronization import Semaphore as Semaphore +from ._core._synchronization import SemaphoreStatistics as SemaphoreStatistics +from ._core._tasks import TASK_STATUS_IGNORED as TASK_STATUS_IGNORED +from ._core._tasks import CancelScope as CancelScope +from ._core._tasks import create_task_group as create_task_group +from ._core._tasks import current_effective_deadline as current_effective_deadline +from ._core._tasks import fail_after as fail_after +from ._core._tasks import move_on_after as move_on_after +from ._core._tempfile import NamedTemporaryFile as NamedTemporaryFile +from ._core._tempfile import SpooledTemporaryFile as SpooledTemporaryFile +from ._core._tempfile import TemporaryDirectory as TemporaryDirectory +from ._core._tempfile import TemporaryFile as TemporaryFile +from ._core._tempfile import gettempdir as gettempdir +from ._core._tempfile import gettempdirb as gettempdirb +from ._core._tempfile import mkdtemp as mkdtemp +from ._core._tempfile import mkstemp as mkstemp +from ._core._testing import TaskInfo as TaskInfo +from ._core._testing import get_current_task as get_current_task +from ._core._testing import get_running_tasks as get_running_tasks +from ._core._testing import wait_all_tasks_blocked as wait_all_tasks_blocked +from ._core._typedattr import TypedAttributeProvider as TypedAttributeProvider +from ._core._typedattr import TypedAttributeSet as TypedAttributeSet +from ._core._typedattr import typed_attribute as typed_attribute + +# Re-export imports so they look like they live directly in this package +for __value in list(locals().values()): + if getattr(__value, "__module__", "").startswith("anyio."): + __value.__module__ = __name__ + + +del __value + + +def __getattr__(attr: str) -> type[BrokenWorkerInterpreter]: + """Support deprecated aliases.""" + if attr == "BrokenWorkerIntepreter": + import warnings + + warnings.warn( + "The 'BrokenWorkerIntepreter' alias is deprecated, use 'BrokenWorkerInterpreter' instead.", + DeprecationWarning, + stacklevel=2, + ) + return BrokenWorkerInterpreter + + raise AttributeError(f"module {__name__!r} has no attribute {attr!r}") diff --git a/venv/lib/python3.12/site-packages/anyio/__pycache__/__init__.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4932de5cb87cfd5c46cdbca2692e5b918fed5994 GIT binary patch literal 4642 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 U0$wj_L`B{Am36UuF<$Zi0zj#5TL1t6 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/anyio/__pycache__/from_thread.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/__pycache__/from_thread.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e7ac8ae68bab06b7e7a4fb68e09e0394733ae1f9 GIT binary patch literal 25885 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 Ih_e0v1svUd7ytkO literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/anyio/__pycache__/lowlevel.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/__pycache__/lowlevel.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..61da5e62da0c08a6abcf2b0cdf4c0bc7b9e470ae GIT binary patch literal 8008 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/anyio/__pycache__/pytest_plugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/__pycache__/pytest_plugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..04f81d39de2fee366dd5c776c2074cc18ad019ad GIT binary patch literal 16837 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 v(aJ2zQh~;wyVc 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 N2Oz4Pe-)hJ)6$ML z+r8C2D`kzK1Th~64msf*;18f2{s1`T&PB!tD^sWl1r*V3DVc)uiT8SDSF++Wv(ohI zp4YEmzu)h@?mtdXmkB&STKqWtDM)|A&iHXs!P@^6gu5glffbRS)v_!S-msmv7}^oCNu(&?~lzMlM99-c)M}#XU4uvl5pHA!8PYQs`PPDXD?*^icT8l0Q(2i`WbJ3L8YR z7k3qBfft3nFy`ty%q?AIQN%hC2f4UB?DKb+0@2xEO6;Mx(3xN5vB%J&*J1t|7Xb{; zUS)mehw<=QYOI#qvq62&#W}g8lG$1w^dp`Wz9T?+Eh#N~-{$c;i;~i}q`sn7_3|4v zJDF!4CITru`16_Yd6c+mYg|i;nZte-K7uP1;Q!}@So?QCc#Bv7{ATXQi<`M0TJcy9 z;E!|g**t;$p>q#s!efy*pGt(>%Y<9S@yJ2DNj9BLYt#NPe=j51dqA!qfR$h6?%F@g z=gHgT0{Nx$JA1>b71%XUDpPncsxBPQ94O6cXAn;;DIO1$pn&Fp({r!{6GN(4sKE{X zuFs8cwbWRL({NQt#mC!f_L*Wm6PPCK+|O8OT+F^faCDRQrG`yN!6JGPE!+@B_o>s4 za;Zt%?PWFK5U*I$ER2V@doJQ^9pe}3;K-qxXuyX< zR|Ecsoyl^y2~kQ52F*q=)&t-aG-f1)1PU1--IEXv^fcX^MoOsFRl?f4+xvr8z4j`#enMR%bYHa3dwwy@~AU0$*CL!h~D6p6gLmma%Z1su!F`9fKbWme_jlp=0Js#M*~y8q zFJ36Tl)RajwS3}WZA^_Vj4dV(=Dx-XjY&u!vqo3;cq3pUj2d-F58+2_qk*-1yUui%Q;VGt z$%EmB6UN$q1%$ig;53_@RPgoaGye8AAjKRw01Xr2w8a{o*2<&lhkVS^gm#8N5_3s- zG9SgD*MTERt{8K^6i?D!XGCqLWKK)@k#%I}7Wd;UG4Oc!zvQ7=4`_-ERLG>?l6{Ps z!fTuvFt693r;ovFi#%E+mFFM0OAp$;iT@>ji6eYn;BHccAZ@fF^hl0rP}V|L<& zCn@1o4|+Py;yKTUW4i8{+J~ht&0!lSp(3slg? zUp0>!Cc6*?wS+H>ssZA0>1#b13?hC>orf{Jx9Q)&Yh+uNwM)J*a%?xZRopKV%iSes zcFD85Go|rN1~YY&$Rf)A{OO-Rk>IKyj<|v3vZ3@&otu zR%uirr_Su0I=yrDOaF4uS%sbQOCuZFPu%B5d1yxk^32Im5v3BTK0lg5sZ3_hj8Ge9 T7iRXSL3;F#Rkprv8TbDObt literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/anyio/_backends/__pycache__/_asyncio.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/_backends/__pycache__/_asyncio.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9b11ccb5ec2c898ddc3c18e8daf9380b22540c3c GIT binary patch literal 138982 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/anyio/_backends/__pycache__/_trio.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/_backends/__pycache__/_trio.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..820b3eb2bac96b1796682f7a9048cf81e35daded GIT binary patch literal 71662 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 (3, 11): + from asyncio import Runner + from typing import TypeVarTuple, Unpack +else: + import contextvars + import enum + import signal + from asyncio import coroutines, events, exceptions, tasks + + from exceptiongroup import BaseExceptionGroup + from typing_extensions import TypeVarTuple, Unpack + + class _State(enum.Enum): + CREATED = "created" + INITIALIZED = "initialized" + CLOSED = "closed" + + class Runner: + # Copied from CPython 3.11 + def __init__( + self, + *, + debug: bool | None = None, + loop_factory: Callable[[], AbstractEventLoop] | None = None, + ): + self._state = _State.CREATED + self._debug = debug + self._loop_factory = loop_factory + self._loop: AbstractEventLoop | None = None + self._context = None + self._interrupt_count = 0 + self._set_event_loop = False + + def __enter__(self) -> Runner: + self._lazy_init() + return self + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: + self.close() + + def close(self) -> None: + """Shutdown and close event loop.""" + loop = self._loop + if self._state is not _State.INITIALIZED or loop is None: + return + try: + _cancel_all_tasks(loop) + loop.run_until_complete(loop.shutdown_asyncgens()) + if hasattr(loop, "shutdown_default_executor"): + loop.run_until_complete(loop.shutdown_default_executor()) + else: + loop.run_until_complete(_shutdown_default_executor(loop)) + finally: + if self._set_event_loop: + events.set_event_loop(None) + loop.close() + self._loop = None + self._state = _State.CLOSED + + def get_loop(self) -> AbstractEventLoop: + """Return embedded event loop.""" + self._lazy_init() + return self._loop + + def run(self, coro: Coroutine[T_Retval], *, context=None) -> T_Retval: + """Run a coroutine inside the embedded event loop.""" + if not coroutines.iscoroutine(coro): + raise ValueError(f"a coroutine was expected, got {coro!r}") + + if events._get_running_loop() is not None: + # fail fast with short traceback + raise RuntimeError( + "Runner.run() cannot be called from a running event loop" + ) + + self._lazy_init() + + if context is None: + context = self._context + task = context.run(self._loop.create_task, coro) + + if ( + threading.current_thread() is threading.main_thread() + and signal.getsignal(signal.SIGINT) is signal.default_int_handler + ): + sigint_handler = partial(self._on_sigint, main_task=task) + try: + signal.signal(signal.SIGINT, sigint_handler) + except ValueError: + # `signal.signal` may throw if `threading.main_thread` does + # not support signals (e.g. embedded interpreter with signals + # not registered - see gh-91880) + sigint_handler = None + else: + sigint_handler = None + + self._interrupt_count = 0 + try: + return self._loop.run_until_complete(task) + except exceptions.CancelledError: + if self._interrupt_count > 0: + uncancel = getattr(task, "uncancel", None) + if uncancel is not None and uncancel() == 0: + raise KeyboardInterrupt # noqa: B904 + raise # CancelledError + finally: + if ( + sigint_handler is not None + and signal.getsignal(signal.SIGINT) is sigint_handler + ): + signal.signal(signal.SIGINT, signal.default_int_handler) + + def _lazy_init(self) -> None: + if self._state is _State.CLOSED: + raise RuntimeError("Runner is closed") + if self._state is _State.INITIALIZED: + return + if self._loop_factory is None: + self._loop = events.new_event_loop() + if not self._set_event_loop: + # Call set_event_loop only once to avoid calling + # attach_loop multiple times on child watchers + events.set_event_loop(self._loop) + self._set_event_loop = True + else: + self._loop = self._loop_factory() + if self._debug is not None: + self._loop.set_debug(self._debug) + self._context = contextvars.copy_context() + self._state = _State.INITIALIZED + + def _on_sigint(self, signum, frame, main_task: asyncio.Task) -> None: + self._interrupt_count += 1 + if self._interrupt_count == 1 and not main_task.done(): + main_task.cancel() + # wakeup loop if it is blocked by select() with long timeout + self._loop.call_soon_threadsafe(lambda: None) + return + raise KeyboardInterrupt() + + def _cancel_all_tasks(loop: AbstractEventLoop) -> None: + to_cancel = tasks.all_tasks(loop) + if not to_cancel: + return + + for task in to_cancel: + task.cancel() + + loop.run_until_complete(tasks.gather(*to_cancel, return_exceptions=True)) + + for task in to_cancel: + if task.cancelled(): + continue + if task.exception() is not None: + loop.call_exception_handler( + { + "message": "unhandled exception during asyncio.run() shutdown", + "exception": task.exception(), + "task": task, + } + ) + + async def _shutdown_default_executor(loop: AbstractEventLoop) -> None: + """Schedule the shutdown of the default executor.""" + + def _do_shutdown(future: asyncio.futures.Future) -> None: + try: + loop._default_executor.shutdown(wait=True) # type: ignore[attr-defined] + loop.call_soon_threadsafe(future.set_result, None) + except Exception as ex: + loop.call_soon_threadsafe(future.set_exception, ex) + + loop._executor_shutdown_called = True + if loop._default_executor is None: + return + future = loop.create_future() + thread = threading.Thread(target=_do_shutdown, args=(future,)) + thread.start() + try: + await future + finally: + thread.join() + + +T_Retval = TypeVar("T_Retval") +T_contra = TypeVar("T_contra", contravariant=True) +PosArgsT = TypeVarTuple("PosArgsT") +P = ParamSpec("P") + +_root_task: RunVar[asyncio.Task | None] = RunVar("_root_task") + + +def find_root_task() -> asyncio.Task: + root_task = _root_task.get(None) + if root_task is not None and not root_task.done(): + return root_task + + # Look for a task that has been started via run_until_complete() + for task in all_tasks(): + if task._callbacks and not task.done(): + callbacks = [cb for cb, context in task._callbacks] + for cb in callbacks: + if ( + cb is _run_until_complete_cb + or getattr(cb, "__module__", None) == "uvloop.loop" + ): + _root_task.set(task) + return task + + # Look up the topmost task in the AnyIO task tree, if possible + task = cast(asyncio.Task, current_task()) + state = _task_states.get(task) + if state: + cancel_scope = state.cancel_scope + while cancel_scope and cancel_scope._parent_scope is not None: + cancel_scope = cancel_scope._parent_scope + + if cancel_scope is not None: + return cast(asyncio.Task, cancel_scope._host_task) + + return task + + +def get_callable_name(func: Callable) -> str: + module = getattr(func, "__module__", None) + qualname = getattr(func, "__qualname__", None) + return ".".join([x for x in (module, qualname) if x]) + + +# +# Event loop +# + +_run_vars: WeakKeyDictionary[asyncio.AbstractEventLoop, Any] = WeakKeyDictionary() + + +def _task_started(task: asyncio.Task) -> bool: + """Return ``True`` if the task has been started and has not finished.""" + # The task coro should never be None here, as we never add finished tasks to the + # task list + coro = task.get_coro() + assert coro is not None + try: + return getcoroutinestate(coro) in (CORO_RUNNING, CORO_SUSPENDED) + except AttributeError: + # task coro is async_genenerator_asend https://bugs.python.org/issue37771 + raise Exception(f"Cannot determine if task {task} has started or not") from None + + +# +# Timeouts and cancellation +# + + +def is_anyio_cancellation(exc: CancelledError) -> bool: + # Sometimes third party frameworks catch a CancelledError and raise a new one, so as + # a workaround we have to look at the previous ones in __context__ too for a + # matching cancel message + while True: + if ( + exc.args + and isinstance(exc.args[0], str) + and exc.args[0].startswith("Cancelled via cancel scope ") + ): + return True + + if isinstance(exc.__context__, CancelledError): + exc = exc.__context__ + continue + + return False + + +class CancelScope(BaseCancelScope): + def __new__( + cls, *, deadline: float = math.inf, shield: bool = False + ) -> CancelScope: + return object.__new__(cls) + + def __init__(self, deadline: float = math.inf, shield: bool = False): + self._deadline = deadline + self._shield = shield + self._parent_scope: CancelScope | None = None + self._child_scopes: set[CancelScope] = set() + self._cancel_called = False + self._cancel_reason: str | None = None + self._cancelled_caught = False + self._active = False + self._timeout_handle: asyncio.TimerHandle | None = None + self._cancel_handle: asyncio.Handle | None = None + self._tasks: set[asyncio.Task] = set() + self._host_task: asyncio.Task | None = None + if sys.version_info >= (3, 11): + self._pending_uncancellations: int | None = 0 + else: + self._pending_uncancellations = None + + def __enter__(self) -> CancelScope: + if self._active: + raise RuntimeError( + "Each CancelScope may only be used for a single 'with' block" + ) + + self._host_task = host_task = cast(asyncio.Task, current_task()) + self._tasks.add(host_task) + try: + task_state = _task_states[host_task] + except KeyError: + task_state = TaskState(None, self) + _task_states[host_task] = task_state + else: + self._parent_scope = task_state.cancel_scope + task_state.cancel_scope = self + if self._parent_scope is not None: + # If using an eager task factory, the parent scope may not even contain + # the host task + self._parent_scope._child_scopes.add(self) + self._parent_scope._tasks.discard(host_task) + + self._timeout() + self._active = True + + # Start cancelling the host task if the scope was cancelled before entering + if self._cancel_called: + self._deliver_cancellation(self) + + return self + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> bool: + del exc_tb + + if not self._active: + raise RuntimeError("This cancel scope is not active") + if current_task() is not self._host_task: + raise RuntimeError( + "Attempted to exit cancel scope in a different task than it was " + "entered in" + ) + + assert self._host_task is not None + host_task_state = _task_states.get(self._host_task) + if host_task_state is None or host_task_state.cancel_scope is not self: + raise RuntimeError( + "Attempted to exit a cancel scope that isn't the current tasks's " + "current cancel scope" + ) + + try: + self._active = False + if self._timeout_handle: + self._timeout_handle.cancel() + self._timeout_handle = None + + self._tasks.remove(self._host_task) + if self._parent_scope is not None: + self._parent_scope._child_scopes.remove(self) + self._parent_scope._tasks.add(self._host_task) + + host_task_state.cancel_scope = self._parent_scope + + # Restart the cancellation effort in the closest visible, cancelled parent + # scope if necessary + self._restart_cancellation_in_parent() + + # We only swallow the exception iff it was an AnyIO CancelledError, either + # directly as exc_val or inside an exception group and there are no cancelled + # parent cancel scopes visible to us here + if self._cancel_called and not self._parent_cancellation_is_visible_to_us: + # For each level-cancel() call made on the host task, call uncancel() + while self._pending_uncancellations: + self._host_task.uncancel() + self._pending_uncancellations -= 1 + + # Update cancelled_caught and check for exceptions we must not swallow + if isinstance(exc_val, BaseExceptionGroup): + cancelleds_caught, remaining = exc_val.split( + lambda exc: ( + isinstance(exc, CancelledError) + and is_anyio_cancellation(exc) + ) + ) + + if cancelleds_caught is None: + return False + + self._cancelled_caught = True + + if remaining is None: + return True + + context = remaining.__context__ + try: + # Preserve __cause__ and __suppress_context__ by avoiding `raise + # ... from ...` + raise remaining + finally: + # Preserve __context__ + remaining.__context__ = context + del context + else: + if isinstance(exc_val, CancelledError) and is_anyio_cancellation( + exc_val + ): + self._cancelled_caught = True + return True + else: + return False + else: + if self._pending_uncancellations: + assert self._parent_scope is not None + assert self._parent_scope._pending_uncancellations is not None + self._parent_scope._pending_uncancellations += ( + self._pending_uncancellations + ) + self._pending_uncancellations = 0 + + return False + finally: + self._host_task = None + del exc_val + + @property + def _effectively_cancelled(self) -> bool: + cancel_scope: CancelScope | None = self + while cancel_scope is not None: + if cancel_scope._cancel_called: + return True + + if cancel_scope.shield: + return False + + cancel_scope = cancel_scope._parent_scope + + return False + + @property + def _parent_cancellation_is_visible_to_us(self) -> bool: + return ( + self._parent_scope is not None + and not self.shield + and self._parent_scope._effectively_cancelled + ) + + def _timeout(self) -> None: + if self._deadline != math.inf: + loop = get_running_loop() + if loop.time() >= self._deadline: + self.cancel("deadline exceeded") + else: + self._timeout_handle = loop.call_at(self._deadline, self._timeout) + + def _deliver_cancellation(self, origin: CancelScope) -> bool: + """ + Deliver cancellation to directly contained tasks and nested cancel scopes. + + Schedule another run at the end if we still have tasks eligible for + cancellation. + + :param origin: the cancel scope that originated the cancellation + :return: ``True`` if the delivery needs to be retried on the next cycle + + """ + should_retry = False + current = current_task() + for task in self._tasks: + should_retry = True + if task._must_cancel: # type: ignore[attr-defined] + continue + + # The task is eligible for cancellation if it has started + if task is not current and (task is self._host_task or _task_started(task)): + waiter = task._fut_waiter # type: ignore[attr-defined] + if not isinstance(waiter, asyncio.Future) or not waiter.done(): + task.cancel(origin._cancel_reason) + if ( + task is origin._host_task + and origin._pending_uncancellations is not None + ): + origin._pending_uncancellations += 1 + + # Deliver cancellation to child scopes that aren't shielded or running their own + # cancellation callbacks + for scope in self._child_scopes: + if not scope._shield and not scope.cancel_called: + should_retry = scope._deliver_cancellation(origin) or should_retry + + # Schedule another callback if there are still tasks left + if origin is self: + if should_retry: + self._cancel_handle = get_running_loop().call_soon( + self._deliver_cancellation, origin + ) + else: + self._cancel_handle = None + + return should_retry + + def _restart_cancellation_in_parent(self) -> None: + """ + Restart the cancellation effort in the closest directly cancelled parent scope. + + """ + scope = self._parent_scope + while scope is not None: + if scope._cancel_called: + if scope._cancel_handle is None: + scope._deliver_cancellation(scope) + + break + + # No point in looking beyond any shielded scope + if scope._shield: + break + + scope = scope._parent_scope + + def cancel(self, reason: str | None = None) -> None: + if not self._cancel_called: + if self._timeout_handle: + self._timeout_handle.cancel() + self._timeout_handle = None + + self._cancel_called = True + self._cancel_reason = f"Cancelled via cancel scope {id(self):x}" + if task := current_task(): + self._cancel_reason += f" by {task}" + + if reason: + self._cancel_reason += f"; reason: {reason}" + + if self._host_task is not None: + self._deliver_cancellation(self) + + @property + def deadline(self) -> float: + return self._deadline + + @deadline.setter + def deadline(self, value: float) -> None: + self._deadline = float(value) + if self._timeout_handle is not None: + self._timeout_handle.cancel() + self._timeout_handle = None + + if self._active and not self._cancel_called: + self._timeout() + + @property + def cancel_called(self) -> bool: + return self._cancel_called + + @property + def cancelled_caught(self) -> bool: + return self._cancelled_caught + + @property + def shield(self) -> bool: + return self._shield + + @shield.setter + def shield(self, value: bool) -> None: + if self._shield != value: + self._shield = value + if not value: + self._restart_cancellation_in_parent() + + +# +# Task states +# + + +class TaskState: + """ + Encapsulates auxiliary task information that cannot be added to the Task instance + itself because there are no guarantees about its implementation. + """ + + __slots__ = "parent_id", "cancel_scope", "__weakref__" + + def __init__(self, parent_id: int | None, cancel_scope: CancelScope | None): + self.parent_id = parent_id + self.cancel_scope = cancel_scope + + +_task_states: WeakKeyDictionary[asyncio.Task, TaskState] = WeakKeyDictionary() + + +# +# Task groups +# + + +class _AsyncioTaskStatus(abc.TaskStatus): + def __init__(self, future: asyncio.Future, parent_id: int): + self._future = future + self._parent_id = parent_id + + def started(self, value: T_contra | None = None) -> None: + try: + self._future.set_result(value) + except asyncio.InvalidStateError: + if not self._future.cancelled(): + raise RuntimeError( + "called 'started' twice on the same task status" + ) from None + + task = cast(asyncio.Task, current_task()) + _task_states[task].parent_id = self._parent_id + + +if sys.version_info >= (3, 12): + _eager_task_factory_code: CodeType | None = asyncio.eager_task_factory.__code__ +else: + _eager_task_factory_code = None + + +class TaskGroup(abc.TaskGroup): + def __init__(self) -> None: + self.cancel_scope: CancelScope = CancelScope() + self._active = False + self._exceptions: list[BaseException] = [] + self._tasks: set[asyncio.Task] = set() + self._on_completed_fut: asyncio.Future[None] | None = None + + async def __aenter__(self) -> TaskGroup: + self.cancel_scope.__enter__() + self._active = True + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> bool: + try: + if exc_val is not None: + self.cancel_scope.cancel() + if not isinstance(exc_val, CancelledError): + self._exceptions.append(exc_val) + + loop = get_running_loop() + try: + if self._tasks: + with CancelScope() as wait_scope: + while self._tasks: + self._on_completed_fut = loop.create_future() + + try: + await self._on_completed_fut + except CancelledError as exc: + # Shield the scope against further cancellation attempts, + # as they're not productive (#695) + wait_scope.shield = True + self.cancel_scope.cancel() + + # Set exc_val from the cancellation exception if it was + # previously unset. However, we should not replace a native + # cancellation exception with one raise by a cancel scope. + if exc_val is None or ( + isinstance(exc_val, CancelledError) + and not is_anyio_cancellation(exc) + ): + exc_val = exc + + self._on_completed_fut = None + else: + # If there are no child tasks to wait on, run at least one checkpoint + # anyway + await AsyncIOBackend.cancel_shielded_checkpoint() + + self._active = False + if self._exceptions: + # The exception that got us here should already have been + # added to self._exceptions so it's ok to break exception + # chaining and avoid adding a "During handling of above..." + # for each nesting level. + raise BaseExceptionGroup( + "unhandled errors in a TaskGroup", self._exceptions + ) from None + elif exc_val: + raise exc_val + except BaseException as exc: + if self.cancel_scope.__exit__(type(exc), exc, exc.__traceback__): + return True + + raise + + return self.cancel_scope.__exit__(exc_type, exc_val, exc_tb) + finally: + del exc_val, exc_tb, self._exceptions + + def _spawn( + self, + func: Callable[[Unpack[PosArgsT]], Awaitable[Any]], + args: tuple[Unpack[PosArgsT]], + name: object, + task_status_future: asyncio.Future | None = None, + ) -> asyncio.Task: + def task_done(_task: asyncio.Task) -> None: + if sys.version_info >= (3, 14) and self.cancel_scope._host_task is not None: + asyncio.future_discard_from_awaited_by( + _task, self.cancel_scope._host_task + ) + + task_state = _task_states[_task] + assert task_state.cancel_scope is not None + assert _task in task_state.cancel_scope._tasks + task_state.cancel_scope._tasks.remove(_task) + self._tasks.remove(task) + del _task_states[_task] + + if self._on_completed_fut is not None and not self._tasks: + try: + self._on_completed_fut.set_result(None) + except asyncio.InvalidStateError: + pass + + try: + exc = _task.exception() + except CancelledError as e: + while isinstance(e.__context__, CancelledError): + e = e.__context__ + + exc = e + + if exc is not None: + # The future can only be in the cancelled state if the host task was + # cancelled, so return immediately instead of adding one more + # CancelledError to the exceptions list + if task_status_future is not None and task_status_future.cancelled(): + return + + if task_status_future is None or task_status_future.done(): + if not isinstance(exc, CancelledError): + self._exceptions.append(exc) + + if not self.cancel_scope._effectively_cancelled: + self.cancel_scope.cancel() + else: + task_status_future.set_exception(exc) + elif task_status_future is not None and not task_status_future.done(): + task_status_future.set_exception( + RuntimeError("Child exited without calling task_status.started()") + ) + + if not self._active: + raise RuntimeError( + "This task group is not active; no new tasks can be started." + ) + + kwargs = {} + if task_status_future: + parent_id = id(current_task()) + kwargs["task_status"] = _AsyncioTaskStatus( + task_status_future, id(self.cancel_scope._host_task) + ) + else: + parent_id = id(self.cancel_scope._host_task) + + coro = func(*args, **kwargs) + if not iscoroutine(coro): + prefix = f"{func.__module__}." if hasattr(func, "__module__") else "" + raise TypeError( + f"Expected {prefix}{func.__qualname__}() to return a coroutine, but " + f"the return value ({coro!r}) is not a coroutine object" + ) + + name = get_callable_name(func) if name is None else str(name) + loop = asyncio.get_running_loop() + if ( + (factory := loop.get_task_factory()) + and getattr(factory, "__code__", None) is _eager_task_factory_code + and (closure := getattr(factory, "__closure__", None)) + ): + custom_task_constructor = closure[0].cell_contents + task = custom_task_constructor(coro, loop=loop, name=name) + else: + task = create_task(coro, name=name) + + # Make the spawned task inherit the task group's cancel scope + _task_states[task] = TaskState( + parent_id=parent_id, cancel_scope=self.cancel_scope + ) + self.cancel_scope._tasks.add(task) + self._tasks.add(task) + if sys.version_info >= (3, 14) and self.cancel_scope._host_task is not None: + asyncio.future_add_to_awaited_by(task, self.cancel_scope._host_task) + + task.add_done_callback(task_done) + return task + + def start_soon( + self, + func: Callable[[Unpack[PosArgsT]], Awaitable[Any]], + *args: Unpack[PosArgsT], + name: object = None, + ) -> None: + self._spawn(func, args, name) + + async def start( + self, func: Callable[..., Awaitable[Any]], *args: object, name: object = None + ) -> Any: + future: asyncio.Future = asyncio.Future() + task = self._spawn(func, args, name, future) + + # If the task raises an exception after sending a start value without a switch + # point between, the task group is cancelled and this method never proceeds to + # process the completed future. That's why we have to have a shielded cancel + # scope here. + try: + return await future + except CancelledError: + # Cancel the task and wait for it to exit before returning + task.cancel() + with CancelScope(shield=True), suppress(CancelledError): + await task + + raise + + +# +# Threads +# + +_Retval_Queue_Type = tuple[T_Retval | None, BaseException | None] + + +class WorkerThread(Thread): + MAX_IDLE_TIME = 10 # seconds + + def __init__( + self, + root_task: asyncio.Task, + workers: set[WorkerThread], + idle_workers: deque[WorkerThread], + ): + super().__init__(name="AnyIO worker thread") + self.root_task = root_task + self.workers = workers + self.idle_workers = idle_workers + self.loop = root_task._loop + self.queue: Queue[ + tuple[Context, Callable, tuple, asyncio.Future, CancelScope] | None + ] = Queue(2) + self.idle_since = AsyncIOBackend.current_time() + self.stopping = False + + def _report_result( + self, future: asyncio.Future, result: Any, exc: BaseException | None + ) -> None: + self.idle_since = AsyncIOBackend.current_time() + if not self.stopping: + self.idle_workers.append(self) + + if not future.cancelled(): + if exc is not None: + if isinstance(exc, StopIteration): + new_exc = RuntimeError("coroutine raised StopIteration") + new_exc.__cause__ = exc + exc = new_exc + + future.set_exception(exc) + else: + future.set_result(result) + + def run(self) -> None: + with claim_worker_thread(AsyncIOBackend, self.loop): + while True: + item = self.queue.get() + if item is None: + # Shutdown command received + return + + context, func, args, future, cancel_scope = item + if not future.cancelled(): + result = None + exception: BaseException | None = None + threadlocals.current_cancel_scope = cancel_scope + try: + result = context.run(func, *args) + except BaseException as exc: + exception = exc + finally: + del threadlocals.current_cancel_scope + + if not self.loop.is_closed(): + self.loop.call_soon_threadsafe( + self._report_result, future, result, exception + ) + + del result, exception + + self.queue.task_done() + del item, context, func, args, future, cancel_scope + + def stop(self, f: asyncio.Task | None = None) -> None: + self.stopping = True + self.queue.put_nowait(None) + self.workers.discard(self) + try: + self.idle_workers.remove(self) + except ValueError: + pass + + +_threadpool_idle_workers: RunVar[deque[WorkerThread]] = RunVar( + "_threadpool_idle_workers" +) +_threadpool_workers: RunVar[set[WorkerThread]] = RunVar("_threadpool_workers") + + +# +# Subprocesses +# + + +@dataclass(eq=False) +class StreamReaderWrapper(abc.ByteReceiveStream): + _stream: asyncio.StreamReader + + async def receive(self, max_bytes: int = 65536) -> bytes: + data = await self._stream.read(max_bytes) + if data: + return data + else: + raise EndOfStream + + async def aclose(self) -> None: + self._stream.set_exception(ClosedResourceError()) + await AsyncIOBackend.checkpoint() + + +@dataclass(eq=False) +class StreamWriterWrapper(abc.ByteSendStream): + _stream: asyncio.StreamWriter + _closed: bool = field(init=False, default=False) + + async def send(self, item: bytes) -> None: + await AsyncIOBackend.checkpoint_if_cancelled() + stream_paused = self._stream._protocol._paused # type: ignore[attr-defined] + try: + self._stream.write(item) + await self._stream.drain() + except (ConnectionResetError, BrokenPipeError, RuntimeError) as exc: + # If closed by us and/or the peer: + # * on stdlib, drain() raises ConnectionResetError or BrokenPipeError + # * on uvloop and Winloop, write() eventually starts raising RuntimeError + if self._closed: + raise ClosedResourceError from exc + elif self._stream.is_closing(): + raise BrokenResourceError from exc + + raise + + if not stream_paused: + await AsyncIOBackend.cancel_shielded_checkpoint() + + async def aclose(self) -> None: + self._closed = True + self._stream.close() + await AsyncIOBackend.checkpoint() + + +@dataclass(eq=False) +class Process(abc.Process): + _process: asyncio.subprocess.Process + _stdin: StreamWriterWrapper | None + _stdout: StreamReaderWrapper | None + _stderr: StreamReaderWrapper | None + + async def aclose(self) -> None: + with CancelScope(shield=True) as scope: + if self._stdin: + await self._stdin.aclose() + if self._stdout: + await self._stdout.aclose() + if self._stderr: + await self._stderr.aclose() + + scope.shield = False + try: + await self.wait() + except BaseException: + scope.shield = True + self.kill() + await self.wait() + raise + + async def wait(self) -> int: + return await self._process.wait() + + def terminate(self) -> None: + self._process.terminate() + + def kill(self) -> None: + self._process.kill() + + def send_signal(self, signal: int) -> None: + self._process.send_signal(signal) + + @property + def pid(self) -> int: + return self._process.pid + + @property + def returncode(self) -> int | None: + return self._process.returncode + + @property + def stdin(self) -> abc.ByteSendStream | None: + return self._stdin + + @property + def stdout(self) -> abc.ByteReceiveStream | None: + return self._stdout + + @property + def stderr(self) -> abc.ByteReceiveStream | None: + return self._stderr + + +def _forcibly_shutdown_process_pool_on_exit( + workers: set[Process], _task: object +) -> None: + """ + Forcibly shuts down worker processes belonging to this event loop.""" + child_watcher: asyncio.AbstractChildWatcher | None = None # type: ignore[name-defined] + if sys.version_info < (3, 12): + try: + child_watcher = asyncio.get_event_loop_policy().get_child_watcher() + except NotImplementedError: + pass + + # Close as much as possible (w/o async/await) to avoid warnings + for process in workers.copy(): + if process.returncode is not None: + continue + + process._stdin._stream._transport.close() # type: ignore[union-attr] + process._stdout._stream._transport.close() # type: ignore[union-attr] + process._stderr._stream._transport.close() # type: ignore[union-attr] + process.kill() + if child_watcher: + child_watcher.remove_child_handler(process.pid) + + +async def _shutdown_process_pool_on_exit(workers: set[abc.Process]) -> None: + """ + Shuts down worker processes belonging to this event loop. + + NOTE: this only works when the event loop was started using asyncio.run() or + anyio.run(). + + """ + process: abc.Process + try: + await sleep(math.inf) + except asyncio.CancelledError: + workers = workers.copy() + for process in workers: + if process.returncode is None: + process.kill() + + for process in workers: + await process.aclose() + + +# +# Sockets and networking +# + + +class StreamProtocol(asyncio.Protocol): + read_queue: deque[bytes] + read_event: asyncio.Event + write_event: asyncio.Event + exception: Exception | None = None + is_at_eof: bool = False + + def connection_made(self, transport: asyncio.BaseTransport) -> None: + self.read_queue = deque() + self.read_event = asyncio.Event() + self.write_event = asyncio.Event() + self.write_event.set() + cast(asyncio.Transport, transport).set_write_buffer_limits(0) + + def connection_lost(self, exc: Exception | None) -> None: + if exc: + self.exception = exc + + self.read_event.set() + self.write_event.set() + + def data_received(self, data: bytes) -> None: + # ProactorEventloop sometimes sends bytearray instead of bytes + self.read_queue.append(bytes(data)) + self.read_event.set() + + def eof_received(self) -> bool | None: + self.is_at_eof = True + self.read_event.set() + return True + + def pause_writing(self) -> None: + self.write_event = asyncio.Event() + + def resume_writing(self) -> None: + self.write_event.set() + + +class DatagramProtocol(asyncio.DatagramProtocol): + read_queue: deque[tuple[bytes, IPSockAddrType]] + read_event: asyncio.Event + write_event: asyncio.Event + exception: Exception | None = None + + def connection_made(self, transport: asyncio.BaseTransport) -> None: + self.read_queue = deque(maxlen=100) # arbitrary value + self.read_event = asyncio.Event() + self.write_event = asyncio.Event() + self.write_event.set() + + def connection_lost(self, exc: Exception | None) -> None: + self.read_event.set() + self.write_event.set() + + def datagram_received(self, data: bytes, addr: IPSockAddrType) -> None: + addr = convert_ipv6_sockaddr(addr) + self.read_queue.append((data, addr)) + self.read_event.set() + + def error_received(self, exc: Exception) -> None: + self.exception = exc + + def pause_writing(self) -> None: + self.write_event.clear() + + def resume_writing(self) -> None: + self.write_event.set() + + +class SocketStream(abc.SocketStream): + def __init__(self, transport: asyncio.Transport, protocol: StreamProtocol): + self._transport = transport + self._protocol = protocol + self._receive_guard = ResourceGuard("reading from") + self._send_guard = ResourceGuard("writing to") + self._closed = False + + @property + def _raw_socket(self) -> socket.socket: + return self._transport.get_extra_info("socket") + + async def receive(self, max_bytes: int = 65536) -> bytes: + with self._receive_guard: + if ( + not self._protocol.read_event.is_set() + and not self._transport.is_closing() + and not self._protocol.is_at_eof + ): + self._transport.resume_reading() + await self._protocol.read_event.wait() + self._transport.pause_reading() + else: + await AsyncIOBackend.checkpoint() + + try: + chunk = self._protocol.read_queue.popleft() + except IndexError: + if self._closed: + raise ClosedResourceError from None + elif self._protocol.exception: + raise BrokenResourceError from self._protocol.exception + else: + raise EndOfStream from None + + if len(chunk) > max_bytes: + # Split the oversized chunk + chunk, leftover = chunk[:max_bytes], chunk[max_bytes:] + self._protocol.read_queue.appendleft(leftover) + + # If the read queue is empty, clear the flag so that the next call will + # block until data is available + if not self._protocol.read_queue: + self._protocol.read_event.clear() + + return chunk + + async def send(self, item: bytes) -> None: + with self._send_guard: + await AsyncIOBackend.checkpoint() + + if self._closed: + raise ClosedResourceError + elif self._protocol.exception is not None: + raise BrokenResourceError from self._protocol.exception + + try: + self._transport.write(item) + except RuntimeError as exc: + if self._transport.is_closing(): + raise BrokenResourceError from exc + else: + raise + + await self._protocol.write_event.wait() + + async def send_eof(self) -> None: + try: + self._transport.write_eof() + except OSError: + pass + + async def aclose(self) -> None: + self._closed = True + if not self._transport.is_closing(): + try: + self._transport.write_eof() + except OSError: + pass + + self._transport.close() + await sleep(0) + self._transport.abort() + + +class _RawSocketMixin: + _receive_future: asyncio.Future | None = None + _send_future: asyncio.Future | None = None + _closing = False + + def __init__(self, raw_socket: socket.socket): + self.__raw_socket = raw_socket + self._receive_guard = ResourceGuard("reading from") + self._send_guard = ResourceGuard("writing to") + + @property + def _raw_socket(self) -> socket.socket: + return self.__raw_socket + + def _wait_until_readable(self, loop: asyncio.AbstractEventLoop) -> asyncio.Future: + def callback(f: object) -> None: + del self._receive_future + loop.remove_reader(self.__raw_socket) + + f = self._receive_future = asyncio.Future() + loop.add_reader(self.__raw_socket, f.set_result, None) + f.add_done_callback(callback) + return f + + def _wait_until_writable(self, loop: asyncio.AbstractEventLoop) -> asyncio.Future: + def callback(f: object) -> None: + del self._send_future + loop.remove_writer(self.__raw_socket) + + f = self._send_future = asyncio.Future() + loop.add_writer(self.__raw_socket, f.set_result, None) + f.add_done_callback(callback) + return f + + async def aclose(self) -> None: + if not self._closing: + self._closing = True + if self.__raw_socket.fileno() != -1: + self.__raw_socket.close() + + if self._receive_future: + self._receive_future.set_result(None) + if self._send_future: + self._send_future.set_result(None) + + +class UNIXSocketStream(_RawSocketMixin, abc.UNIXSocketStream): + async def send_eof(self) -> None: + with self._send_guard: + self._raw_socket.shutdown(socket.SHUT_WR) + + async def receive(self, max_bytes: int = 65536) -> bytes: + loop = get_running_loop() + await AsyncIOBackend.checkpoint() + with self._receive_guard: + while True: + try: + data = self._raw_socket.recv(max_bytes) + except BlockingIOError: + await self._wait_until_readable(loop) + except OSError as exc: + if self._closing: + raise ClosedResourceError from None + else: + raise BrokenResourceError from exc + else: + if not data: + raise EndOfStream + + return data + + async def send(self, item: bytes) -> None: + loop = get_running_loop() + await AsyncIOBackend.checkpoint() + with self._send_guard: + view = memoryview(item) + while view: + try: + bytes_sent = self._raw_socket.send(view) + except BlockingIOError: + await self._wait_until_writable(loop) + except OSError as exc: + if self._closing: + raise ClosedResourceError from None + else: + raise BrokenResourceError from exc + else: + view = view[bytes_sent:] + + async def receive_fds(self, msglen: int, maxfds: int) -> tuple[bytes, list[int]]: + if not isinstance(msglen, int) or msglen < 0: + raise ValueError("msglen must be a non-negative integer") + if not isinstance(maxfds, int) or maxfds < 1: + raise ValueError("maxfds must be a positive integer") + + loop = get_running_loop() + fds = array.array("i") + await AsyncIOBackend.checkpoint() + with self._receive_guard: + while True: + try: + message, ancdata, flags, addr = self._raw_socket.recvmsg( + msglen, socket.CMSG_LEN(maxfds * fds.itemsize) + ) + except BlockingIOError: + await self._wait_until_readable(loop) + except OSError as exc: + if self._closing: + raise ClosedResourceError from None + else: + raise BrokenResourceError from exc + else: + if not message and not ancdata: + raise EndOfStream + + break + + for cmsg_level, cmsg_type, cmsg_data in ancdata: + if cmsg_level != socket.SOL_SOCKET or cmsg_type != socket.SCM_RIGHTS: + raise RuntimeError( + f"Received unexpected ancillary data; message = {message!r}, " + f"cmsg_level = {cmsg_level}, cmsg_type = {cmsg_type}" + ) + + fds.frombytes(cmsg_data[: len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) + + return message, list(fds) + + async def send_fds(self, message: bytes, fds: Collection[int | IOBase]) -> None: + if not message: + raise ValueError("message must not be empty") + if not fds: + raise ValueError("fds must not be empty") + + loop = get_running_loop() + filenos: list[int] = [] + for fd in fds: + if isinstance(fd, int): + filenos.append(fd) + elif isinstance(fd, IOBase): + filenos.append(fd.fileno()) + + fdarray = array.array("i", filenos) + await AsyncIOBackend.checkpoint() + with self._send_guard: + while True: + try: + # The ignore can be removed after mypy picks up + # https://github.com/python/typeshed/pull/5545 + self._raw_socket.sendmsg( + [message], [(socket.SOL_SOCKET, socket.SCM_RIGHTS, fdarray)] + ) + break + except BlockingIOError: + await self._wait_until_writable(loop) + except OSError as exc: + if self._closing: + raise ClosedResourceError from None + else: + raise BrokenResourceError from exc + + +class TCPSocketListener(abc.SocketListener): + _accept_scope: CancelScope | None = None + _closed = False + + def __init__(self, raw_socket: socket.socket): + self.__raw_socket = raw_socket + self._loop = cast(asyncio.BaseEventLoop, get_running_loop()) + self._accept_guard = ResourceGuard("accepting connections from") + + @property + def _raw_socket(self) -> socket.socket: + return self.__raw_socket + + async def accept(self) -> abc.SocketStream: + if self._closed: + raise ClosedResourceError + + with self._accept_guard: + await AsyncIOBackend.checkpoint() + with CancelScope() as self._accept_scope: + try: + client_sock, _addr = await self._loop.sock_accept(self._raw_socket) + except asyncio.CancelledError: + # Workaround for https://bugs.python.org/issue41317 + try: + self._loop.remove_reader(self._raw_socket) + except (ValueError, NotImplementedError): + pass + + if self._closed: + raise ClosedResourceError from None + + raise + finally: + self._accept_scope = None + + client_sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) + transport, protocol = await self._loop.connect_accepted_socket( + StreamProtocol, client_sock + ) + return SocketStream(transport, protocol) + + async def aclose(self) -> None: + if self._closed: + return + + self._closed = True + if self._accept_scope: + # Workaround for https://bugs.python.org/issue41317 + try: + self._loop.remove_reader(self._raw_socket) + except (ValueError, NotImplementedError): + pass + + self._accept_scope.cancel() + await sleep(0) + + self._raw_socket.close() + + +class UNIXSocketListener(abc.SocketListener): + def __init__(self, raw_socket: socket.socket): + self.__raw_socket = raw_socket + self._loop = get_running_loop() + self._accept_guard = ResourceGuard("accepting connections from") + self._closed = False + + async def accept(self) -> abc.SocketStream: + await AsyncIOBackend.checkpoint() + with self._accept_guard: + while True: + try: + client_sock, _ = self.__raw_socket.accept() + client_sock.setblocking(False) + return UNIXSocketStream(client_sock) + except BlockingIOError: + f: asyncio.Future = asyncio.Future() + self._loop.add_reader(self.__raw_socket, f.set_result, None) + f.add_done_callback( + lambda _: self._loop.remove_reader(self.__raw_socket) + ) + await f + except OSError as exc: + if self._closed: + raise ClosedResourceError from None + else: + raise BrokenResourceError from exc + + async def aclose(self) -> None: + self._closed = True + self.__raw_socket.close() + + @property + def _raw_socket(self) -> socket.socket: + return self.__raw_socket + + +class UDPSocket(abc.UDPSocket): + def __init__( + self, transport: asyncio.DatagramTransport, protocol: DatagramProtocol + ): + self._transport = transport + self._protocol = protocol + self._receive_guard = ResourceGuard("reading from") + self._send_guard = ResourceGuard("writing to") + self._closed = False + + @property + def _raw_socket(self) -> socket.socket: + return self._transport.get_extra_info("socket") + + async def aclose(self) -> None: + self._closed = True + if not self._transport.is_closing(): + self._transport.close() + + async def receive(self) -> tuple[bytes, IPSockAddrType]: + with self._receive_guard: + await AsyncIOBackend.checkpoint() + + # If the buffer is empty, ask for more data + if not self._protocol.read_queue and not self._transport.is_closing(): + self._protocol.read_event.clear() + await self._protocol.read_event.wait() + + try: + return self._protocol.read_queue.popleft() + except IndexError: + if self._closed: + raise ClosedResourceError from None + else: + raise BrokenResourceError from None + + async def send(self, item: UDPPacketType) -> None: + with self._send_guard: + await AsyncIOBackend.checkpoint() + await self._protocol.write_event.wait() + if self._closed: + raise ClosedResourceError + elif self._transport.is_closing(): + raise BrokenResourceError + else: + self._transport.sendto(*item) + + +class ConnectedUDPSocket(abc.ConnectedUDPSocket): + def __init__( + self, transport: asyncio.DatagramTransport, protocol: DatagramProtocol + ): + self._transport = transport + self._protocol = protocol + self._receive_guard = ResourceGuard("reading from") + self._send_guard = ResourceGuard("writing to") + self._closed = False + + @property + def _raw_socket(self) -> socket.socket: + return self._transport.get_extra_info("socket") + + async def aclose(self) -> None: + self._closed = True + if not self._transport.is_closing(): + self._transport.close() + + async def receive(self) -> bytes: + with self._receive_guard: + await AsyncIOBackend.checkpoint() + + # If the buffer is empty, ask for more data + if not self._protocol.read_queue and not self._transport.is_closing(): + self._protocol.read_event.clear() + await self._protocol.read_event.wait() + + try: + packet = self._protocol.read_queue.popleft() + except IndexError: + if self._closed: + raise ClosedResourceError from None + else: + raise BrokenResourceError from None + + return packet[0] + + async def send(self, item: bytes) -> None: + with self._send_guard: + await AsyncIOBackend.checkpoint() + await self._protocol.write_event.wait() + if self._closed: + raise ClosedResourceError + elif self._transport.is_closing(): + raise BrokenResourceError + else: + self._transport.sendto(item) + + +class UNIXDatagramSocket(_RawSocketMixin, abc.UNIXDatagramSocket): + async def receive(self) -> UNIXDatagramPacketType: + loop = get_running_loop() + await AsyncIOBackend.checkpoint() + with self._receive_guard: + while True: + try: + data = self._raw_socket.recvfrom(65536) + except BlockingIOError: + await self._wait_until_readable(loop) + except OSError as exc: + if self._closing: + raise ClosedResourceError from None + else: + raise BrokenResourceError from exc + else: + return data + + async def send(self, item: UNIXDatagramPacketType) -> None: + loop = get_running_loop() + await AsyncIOBackend.checkpoint() + with self._send_guard: + while True: + try: + self._raw_socket.sendto(*item) + except BlockingIOError: + await self._wait_until_writable(loop) + except OSError as exc: + if self._closing: + raise ClosedResourceError from None + else: + raise BrokenResourceError from exc + else: + return + + +class ConnectedUNIXDatagramSocket(_RawSocketMixin, abc.ConnectedUNIXDatagramSocket): + async def receive(self) -> bytes: + loop = get_running_loop() + await AsyncIOBackend.checkpoint() + with self._receive_guard: + while True: + try: + data = self._raw_socket.recv(65536) + except BlockingIOError: + await self._wait_until_readable(loop) + except OSError as exc: + if self._closing: + raise ClosedResourceError from None + else: + raise BrokenResourceError from exc + else: + return data + + async def send(self, item: bytes) -> None: + loop = get_running_loop() + await AsyncIOBackend.checkpoint() + with self._send_guard: + while True: + try: + self._raw_socket.send(item) + except BlockingIOError: + await self._wait_until_writable(loop) + except OSError as exc: + if self._closing: + raise ClosedResourceError from None + else: + raise BrokenResourceError from exc + else: + return + + +_read_events: RunVar[dict[int, asyncio.Future[bool]]] = RunVar("read_events") +_write_events: RunVar[dict[int, asyncio.Future[bool]]] = RunVar("write_events") + + +# +# Synchronization +# + + +class Event(BaseEvent): + def __new__(cls) -> Event: + return object.__new__(cls) + + def __init__(self) -> None: + self._event = asyncio.Event() + + def set(self) -> None: + self._event.set() + + def is_set(self) -> bool: + return self._event.is_set() + + async def wait(self) -> None: + if self.is_set(): + await AsyncIOBackend.checkpoint() + else: + await self._event.wait() + + def statistics(self) -> EventStatistics: + return EventStatistics(len(self._event._waiters)) + + +class Lock(BaseLock): + def __new__(cls, *, fast_acquire: bool = False) -> Lock: + return object.__new__(cls) + + def __init__(self, *, fast_acquire: bool = False) -> None: + self._fast_acquire = fast_acquire + self._owner_task: asyncio.Task | None = None + self._waiters: deque[tuple[asyncio.Task, asyncio.Future]] = deque() + + async def acquire(self) -> None: + task = cast(asyncio.Task, current_task()) + if self._owner_task is None and not self._waiters: + await AsyncIOBackend.checkpoint_if_cancelled() + self._owner_task = task + + # Unless on the "fast path", yield control of the event loop so that other + # tasks can run too + if not self._fast_acquire: + try: + await AsyncIOBackend.cancel_shielded_checkpoint() + except CancelledError: + self.release() + raise + + return + + if self._owner_task == task: + raise RuntimeError("Attempted to acquire an already held Lock") + + fut: asyncio.Future[None] = asyncio.Future() + item = task, fut + self._waiters.append(item) + try: + await fut + except CancelledError: + self._waiters.remove(item) + if self._owner_task is task: + self.release() + + raise + + self._waiters.remove(item) + + def acquire_nowait(self) -> None: + task = cast(asyncio.Task, current_task()) + if self._owner_task is None and not self._waiters: + self._owner_task = task + return + + if self._owner_task is task: + raise RuntimeError("Attempted to acquire an already held Lock") + + raise WouldBlock + + def locked(self) -> bool: + return self._owner_task is not None + + def release(self) -> None: + if self._owner_task != current_task(): + raise RuntimeError("The current task is not holding this lock") + + for task, fut in self._waiters: + if not fut.cancelled(): + self._owner_task = task + fut.set_result(None) + return + + self._owner_task = None + + def statistics(self) -> LockStatistics: + task_info = AsyncIOTaskInfo(self._owner_task) if self._owner_task else None + return LockStatistics(self.locked(), task_info, len(self._waiters)) + + +class Semaphore(BaseSemaphore): + def __new__( + cls, + initial_value: int, + *, + max_value: int | None = None, + fast_acquire: bool = False, + ) -> Semaphore: + return object.__new__(cls) + + def __init__( + self, + initial_value: int, + *, + max_value: int | None = None, + fast_acquire: bool = False, + ): + super().__init__(initial_value, max_value=max_value) + self._value = initial_value + self._max_value = max_value + self._fast_acquire = fast_acquire + self._waiters: deque[asyncio.Future[None]] = deque() + + async def acquire(self) -> None: + if self._value > 0 and not self._waiters: + await AsyncIOBackend.checkpoint_if_cancelled() + self._value -= 1 + + # Unless on the "fast path", yield control of the event loop so that other + # tasks can run too + if not self._fast_acquire: + try: + await AsyncIOBackend.cancel_shielded_checkpoint() + except CancelledError: + self.release() + raise + + return + + fut: asyncio.Future[None] = asyncio.Future() + self._waiters.append(fut) + try: + await fut + except CancelledError: + try: + self._waiters.remove(fut) + except ValueError: + self.release() + + raise + + def acquire_nowait(self) -> None: + if self._value == 0: + raise WouldBlock + + self._value -= 1 + + def release(self) -> None: + if self._max_value is not None and self._value == self._max_value: + raise ValueError("semaphore released too many times") + + for fut in self._waiters: + if not fut.cancelled(): + fut.set_result(None) + self._waiters.remove(fut) + return + + self._value += 1 + + @property + def value(self) -> int: + return self._value + + @property + def max_value(self) -> int | None: + return self._max_value + + def statistics(self) -> SemaphoreStatistics: + return SemaphoreStatistics(len(self._waiters)) + + +class CapacityLimiter(BaseCapacityLimiter): + _total_tokens: float = 0 + + def __new__(cls, total_tokens: float) -> CapacityLimiter: + return object.__new__(cls) + + def __init__(self, total_tokens: float): + self._borrowers: set[Any] = set() + self._wait_queue: OrderedDict[Any, asyncio.Event] = OrderedDict() + self.total_tokens = total_tokens + + async def __aenter__(self) -> None: + await self.acquire() + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: + self.release() + + @property + def total_tokens(self) -> float: + return self._total_tokens + + @total_tokens.setter + def total_tokens(self, value: float) -> None: + if not isinstance(value, int) and not math.isinf(value): + raise TypeError("total_tokens must be an int or math.inf") + + if value < 0: + raise ValueError("total_tokens must be >= 0") + + waiters_to_notify = max(value - self._total_tokens, 0) + self._total_tokens = value + + # Notify waiting tasks that they have acquired the limiter + while self._wait_queue and waiters_to_notify: + event = self._wait_queue.popitem(last=False)[1] + event.set() + waiters_to_notify -= 1 + + @property + def borrowed_tokens(self) -> int: + return len(self._borrowers) + + @property + def available_tokens(self) -> float: + return self._total_tokens - len(self._borrowers) + + def _notify_next_waiter(self) -> None: + """Notify the next task in line if this limiter has free capacity now.""" + if self._wait_queue and len(self._borrowers) < self._total_tokens: + event = self._wait_queue.popitem(last=False)[1] + event.set() + + def acquire_nowait(self) -> None: + self.acquire_on_behalf_of_nowait(current_task()) + + def acquire_on_behalf_of_nowait(self, borrower: object) -> None: + if borrower in self._borrowers: + raise RuntimeError( + "this borrower is already holding one of this CapacityLimiter's tokens" + ) + + if self._wait_queue or len(self._borrowers) >= self._total_tokens: + raise WouldBlock + + self._borrowers.add(borrower) + + async def acquire(self) -> None: + return await self.acquire_on_behalf_of(current_task()) + + async def acquire_on_behalf_of(self, borrower: object) -> None: + await AsyncIOBackend.checkpoint_if_cancelled() + try: + self.acquire_on_behalf_of_nowait(borrower) + except WouldBlock: + event = asyncio.Event() + self._wait_queue[borrower] = event + try: + await event.wait() + except BaseException: + self._wait_queue.pop(borrower, None) + if event.is_set(): + self._notify_next_waiter() + + raise + + self._borrowers.add(borrower) + else: + try: + await AsyncIOBackend.cancel_shielded_checkpoint() + except BaseException: + self.release() + raise + + def release(self) -> None: + self.release_on_behalf_of(current_task()) + + def release_on_behalf_of(self, borrower: object) -> None: + try: + self._borrowers.remove(borrower) + except KeyError: + raise RuntimeError( + "this borrower isn't holding any of this CapacityLimiter's tokens" + ) from None + + self._notify_next_waiter() + + def statistics(self) -> CapacityLimiterStatistics: + return CapacityLimiterStatistics( + self.borrowed_tokens, + self.total_tokens, + tuple(self._borrowers), + len(self._wait_queue), + ) + + +_default_thread_limiter: RunVar[CapacityLimiter] = RunVar("_default_thread_limiter") + + +# +# Operating system signals +# + + +class _SignalReceiver: + def __init__(self, signals: tuple[Signals, ...]): + self._signals = signals + self._loop = get_running_loop() + self._signal_queue: deque[Signals] = deque() + self._future: asyncio.Future = asyncio.Future() + self._handled_signals: set[Signals] = set() + + def _deliver(self, signum: Signals) -> None: + self._signal_queue.append(signum) + if not self._future.done(): + self._future.set_result(None) + + def __enter__(self) -> _SignalReceiver: + for sig in set(self._signals): + self._loop.add_signal_handler(sig, self._deliver, sig) + self._handled_signals.add(sig) + + return self + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: + for sig in self._handled_signals: + self._loop.remove_signal_handler(sig) + + def __aiter__(self) -> _SignalReceiver: + return self + + async def __anext__(self) -> Signals: + await AsyncIOBackend.checkpoint() + if not self._signal_queue: + self._future = asyncio.Future() + await self._future + + return self._signal_queue.popleft() + + +# +# Testing and debugging +# + + +class AsyncIOTaskInfo(TaskInfo): + def __init__(self, task: asyncio.Task): + task_state = _task_states.get(task) + if task_state is None: + parent_id = None + else: + parent_id = task_state.parent_id + + coro = task.get_coro() + assert coro is not None, "created TaskInfo from a completed Task" + super().__init__(id(task), parent_id, task.get_name(), coro) + self._task = weakref.ref(task) + + def has_pending_cancellation(self) -> bool: + if not (task := self._task()): + # If the task isn't around anymore, it won't have a pending cancellation + return False + + if task._must_cancel: # type: ignore[attr-defined] + return True + elif ( + isinstance(task._fut_waiter, asyncio.Future) # type: ignore[attr-defined] + and task._fut_waiter.cancelled() # type: ignore[attr-defined] + ): + return True + + if task_state := _task_states.get(task): + if cancel_scope := task_state.cancel_scope: + return cancel_scope._effectively_cancelled + + return False + + +class TestRunner(abc.TestRunner): + _send_stream: MemoryObjectSendStream[tuple[Awaitable[Any], asyncio.Future[Any]]] + + def __init__( + self, + *, + debug: bool | None = None, + use_uvloop: bool = False, + loop_factory: Callable[[], AbstractEventLoop] | None = None, + ) -> None: + if use_uvloop and loop_factory is None: + if sys.platform != "win32": + import uvloop + + loop_factory = uvloop.new_event_loop + else: + import winloop + + loop_factory = winloop.new_event_loop + + self._runner = Runner(debug=debug, loop_factory=loop_factory) + self._exceptions: list[BaseException] = [] + self._runner_task: asyncio.Task | None = None + + def __enter__(self) -> TestRunner: + self._runner.__enter__() + self.get_loop().set_exception_handler(self._exception_handler) + return self + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: + self._runner.__exit__(exc_type, exc_val, exc_tb) + + def get_loop(self) -> AbstractEventLoop: + return self._runner.get_loop() + + def _exception_handler( + self, loop: asyncio.AbstractEventLoop, context: dict[str, Any] + ) -> None: + if isinstance(context.get("exception"), Exception): + self._exceptions.append(context["exception"]) + else: + loop.default_exception_handler(context) + + def _raise_async_exceptions(self) -> None: + # Re-raise any exceptions raised in asynchronous callbacks + if self._exceptions: + exceptions, self._exceptions = self._exceptions, [] + if len(exceptions) == 1: + raise exceptions[0] + elif exceptions: + raise BaseExceptionGroup( + "Multiple exceptions occurred in asynchronous callbacks", exceptions + ) + + async def _run_tests_and_fixtures( + self, + receive_stream: MemoryObjectReceiveStream[ + tuple[Awaitable[T_Retval], asyncio.Future[T_Retval]] + ], + ) -> None: + from _pytest.outcomes import OutcomeException + + with receive_stream, self._send_stream: + async for coro, future in receive_stream: + try: + retval = await coro + except CancelledError as exc: + if not future.cancelled(): + future.cancel(*exc.args) + + raise + except BaseException as exc: + if not future.cancelled(): + future.set_exception(exc) + + if not isinstance(exc, (Exception, OutcomeException)): + raise + else: + if not future.cancelled(): + future.set_result(retval) + + async def _call_in_runner_task( + self, + func: Callable[P, Awaitable[T_Retval]], + /, + *args: P.args, + **kwargs: P.kwargs, + ) -> T_Retval: + if not self._runner_task: + self._send_stream, receive_stream = create_memory_object_stream[ + tuple[Awaitable[Any], asyncio.Future] + ](1) + self._runner_task = self.get_loop().create_task( + self._run_tests_and_fixtures(receive_stream) + ) + + coro = func(*args, **kwargs) + future: asyncio.Future[T_Retval] = self.get_loop().create_future() + self._send_stream.send_nowait((coro, future)) + return await future + + def run_asyncgen_fixture( + self, + fixture_func: Callable[..., AsyncGenerator[T_Retval, Any]], + kwargs: dict[str, Any], + ) -> Iterable[T_Retval]: + asyncgen = fixture_func(**kwargs) + fixturevalue: T_Retval = self.get_loop().run_until_complete( + self._call_in_runner_task(asyncgen.asend, None) + ) + self._raise_async_exceptions() + + yield fixturevalue + + try: + self.get_loop().run_until_complete( + self._call_in_runner_task(asyncgen.asend, None) + ) + except StopAsyncIteration: + self._raise_async_exceptions() + else: + self.get_loop().run_until_complete(asyncgen.aclose()) + raise RuntimeError("Async generator fixture did not stop") + + def run_fixture( + self, + fixture_func: Callable[..., Coroutine[Any, Any, T_Retval]], + kwargs: dict[str, Any], + ) -> T_Retval: + retval = self.get_loop().run_until_complete( + self._call_in_runner_task(fixture_func, **kwargs) + ) + self._raise_async_exceptions() + return retval + + def run_test( + self, test_func: Callable[..., Coroutine[Any, Any, Any]], kwargs: dict[str, Any] + ) -> None: + try: + self.get_loop().run_until_complete( + self._call_in_runner_task(test_func, **kwargs) + ) + except Exception as exc: + self._exceptions.append(exc) + + self._raise_async_exceptions() + + +class AsyncIOBackend(AsyncBackend): + @classmethod + def run( + cls, + func: Callable[[Unpack[PosArgsT]], Awaitable[T_Retval]], + args: tuple[Unpack[PosArgsT]], + kwargs: dict[str, Any], + options: dict[str, Any], + ) -> T_Retval: + @wraps(func) + async def wrapper() -> T_Retval: + task = cast(asyncio.Task, current_task()) + task.set_name(get_callable_name(func)) + _task_states[task] = TaskState(None, None) + + try: + return await func(*args) + finally: + del _task_states[task] + + debug = options.get("debug", None) + loop_factory = options.get("loop_factory", None) + if loop_factory is None and options.get("use_uvloop", False): + if sys.platform != "win32": + import uvloop + + loop_factory = uvloop.new_event_loop + else: + import winloop + + loop_factory = winloop.new_event_loop + + with Runner(debug=debug, loop_factory=loop_factory) as runner: + return runner.run(wrapper()) + + @classmethod + def current_token(cls) -> object: + return get_running_loop() + + @classmethod + def current_time(cls) -> float: + return get_running_loop().time() + + @classmethod + def cancelled_exception_class(cls) -> type[BaseException]: + return CancelledError + + @classmethod + async def checkpoint(cls) -> None: + await sleep(0) + + @classmethod + async def checkpoint_if_cancelled(cls) -> None: + task = current_task() + if task is None: + return + + try: + cancel_scope = _task_states[task].cancel_scope + except KeyError: + return + + while cancel_scope: + if cancel_scope.cancel_called: + await sleep(0) + elif cancel_scope.shield: + break + else: + cancel_scope = cancel_scope._parent_scope + + @classmethod + async def cancel_shielded_checkpoint(cls) -> None: + with CancelScope(shield=True): + await sleep(0) + + @classmethod + async def sleep(cls, delay: float) -> None: + await sleep(delay) + + @classmethod + def create_cancel_scope( + cls, *, deadline: float = math.inf, shield: bool = False + ) -> CancelScope: + return CancelScope(deadline=deadline, shield=shield) + + @classmethod + def current_effective_deadline(cls) -> float: + if (task := current_task()) is None: + return math.inf + + try: + cancel_scope = _task_states[task].cancel_scope + except KeyError: + return math.inf + + deadline = math.inf + while cancel_scope: + deadline = min(deadline, cancel_scope.deadline) + if cancel_scope._cancel_called: + deadline = -math.inf + break + elif cancel_scope.shield: + break + else: + cancel_scope = cancel_scope._parent_scope + + return deadline + + @classmethod + def create_task_group(cls) -> abc.TaskGroup: + return TaskGroup() + + @classmethod + def create_event(cls) -> abc.Event: + return Event() + + @classmethod + def create_lock(cls, *, fast_acquire: bool) -> abc.Lock: + return Lock(fast_acquire=fast_acquire) + + @classmethod + def create_semaphore( + cls, + initial_value: int, + *, + max_value: int | None = None, + fast_acquire: bool = False, + ) -> abc.Semaphore: + return Semaphore(initial_value, max_value=max_value, fast_acquire=fast_acquire) + + @classmethod + def create_capacity_limiter(cls, total_tokens: float) -> abc.CapacityLimiter: + return CapacityLimiter(total_tokens) + + @classmethod + async def run_sync_in_worker_thread( # type: ignore[return] + cls, + func: Callable[[Unpack[PosArgsT]], T_Retval], + args: tuple[Unpack[PosArgsT]], + abandon_on_cancel: bool = False, + limiter: abc.CapacityLimiter | None = None, + ) -> T_Retval: + await cls.checkpoint() + + # If this is the first run in this event loop thread, set up the necessary + # variables + try: + idle_workers = _threadpool_idle_workers.get() + workers = _threadpool_workers.get() + except LookupError: + idle_workers = deque() + workers = set() + _threadpool_idle_workers.set(idle_workers) + _threadpool_workers.set(workers) + + async with limiter or cls.current_default_thread_limiter(): + with CancelScope(shield=not abandon_on_cancel) as scope: + future = asyncio.Future[T_Retval]() + root_task = find_root_task() + if not idle_workers: + worker = WorkerThread(root_task, workers, idle_workers) + worker.start() + workers.add(worker) + root_task.add_done_callback( + worker.stop, context=contextvars.Context() + ) + else: + worker = idle_workers.pop() + + # Prune any other workers that have been idle for MAX_IDLE_TIME + # seconds or longer + now = cls.current_time() + while idle_workers: + if ( + now - idle_workers[0].idle_since + < WorkerThread.MAX_IDLE_TIME + ): + break + + expired_worker = idle_workers.popleft() + expired_worker.root_task.remove_done_callback( + expired_worker.stop + ) + expired_worker.stop() + + context = copy_context() + context.run(set_current_async_library, None) + if abandon_on_cancel or scope._parent_scope is None: + worker_scope = scope + else: + worker_scope = scope._parent_scope + + worker.queue.put_nowait((context, func, args, future, worker_scope)) + return await future + + @classmethod + def check_cancelled(cls) -> None: + scope: CancelScope | None = threadlocals.current_cancel_scope + while scope is not None: + if scope.cancel_called: + raise CancelledError(f"Cancelled by cancel scope {id(scope):x}") + + if scope.shield: + return + + scope = scope._parent_scope + + @classmethod + def run_async_from_thread( + cls, + func: Callable[[Unpack[PosArgsT]], Awaitable[T_Retval]], + args: tuple[Unpack[PosArgsT]], + token: object, + ) -> T_Retval: + async def task_wrapper() -> T_Retval: + __tracebackhide__ = True + if scope is not None: + task = cast(asyncio.Task, current_task()) + _task_states[task] = TaskState(None, scope) + scope._tasks.add(task) + try: + return await func(*args) + except CancelledError as exc: + raise concurrent.futures.CancelledError(str(exc)) from None + finally: + if scope is not None: + scope._tasks.discard(task) + + loop = cast( + "AbstractEventLoop", token or threadlocals.current_token.native_token + ) + if loop.is_closed(): + raise RunFinishedError + + context = copy_context() + context.run(set_current_async_library, "asyncio") + scope = getattr(threadlocals, "current_cancel_scope", None) + f: concurrent.futures.Future[T_Retval] = context.run( + asyncio.run_coroutine_threadsafe, task_wrapper(), loop=loop + ) + return f.result() + + @classmethod + def run_sync_from_thread( + cls, + func: Callable[[Unpack[PosArgsT]], T_Retval], + args: tuple[Unpack[PosArgsT]], + token: object, + ) -> T_Retval: + @wraps(func) + def wrapper() -> None: + try: + set_current_async_library("asyncio") + f.set_result(func(*args)) + except BaseException as exc: + f.set_exception(exc) + if not isinstance(exc, Exception): + raise + + loop = cast( + "AbstractEventLoop", token or threadlocals.current_token.native_token + ) + if loop.is_closed(): + raise RunFinishedError + + f: concurrent.futures.Future[T_Retval] = Future() + loop.call_soon_threadsafe(wrapper) + return f.result() + + @classmethod + async def open_process( + cls, + command: StrOrBytesPath | Sequence[StrOrBytesPath], + *, + stdin: int | IO[Any] | None, + stdout: int | IO[Any] | None, + stderr: int | IO[Any] | None, + **kwargs: Any, + ) -> Process: + await cls.checkpoint() + if isinstance(command, PathLike): + command = os.fspath(command) + + if isinstance(command, (str, bytes)): + process = await asyncio.create_subprocess_shell( + command, + stdin=stdin, + stdout=stdout, + stderr=stderr, + **kwargs, + ) + else: + process = await asyncio.create_subprocess_exec( + *command, + stdin=stdin, + stdout=stdout, + stderr=stderr, + **kwargs, + ) + + stdin_stream = StreamWriterWrapper(process.stdin) if process.stdin else None + stdout_stream = StreamReaderWrapper(process.stdout) if process.stdout else None + stderr_stream = StreamReaderWrapper(process.stderr) if process.stderr else None + return Process(process, stdin_stream, stdout_stream, stderr_stream) + + @classmethod + def setup_process_pool_exit_at_shutdown(cls, workers: set[abc.Process]) -> None: + create_task( + _shutdown_process_pool_on_exit(workers), + name="AnyIO process pool shutdown task", + ) + find_root_task().add_done_callback( + partial(_forcibly_shutdown_process_pool_on_exit, workers) # type:ignore[arg-type] + ) + + @classmethod + async def connect_tcp( + cls, host: str, port: int, local_address: IPSockAddrType | None = None + ) -> abc.SocketStream: + transport, protocol = cast( + tuple[asyncio.Transport, StreamProtocol], + await get_running_loop().create_connection( + StreamProtocol, host, port, local_addr=local_address + ), + ) + transport.pause_reading() + return SocketStream(transport, protocol) + + @classmethod + async def connect_unix(cls, path: str | bytes) -> abc.UNIXSocketStream: + await cls.checkpoint() + loop = get_running_loop() + raw_socket = socket.socket(socket.AF_UNIX) + raw_socket.setblocking(False) + while True: + try: + raw_socket.connect(path) + except BlockingIOError: + f: asyncio.Future = asyncio.Future() + loop.add_writer(raw_socket, f.set_result, None) + f.add_done_callback(lambda _: loop.remove_writer(raw_socket)) + await f + except BaseException: + raw_socket.close() + raise + else: + return UNIXSocketStream(raw_socket) + + @classmethod + def create_tcp_listener(cls, sock: socket.socket) -> SocketListener: + return TCPSocketListener(sock) + + @classmethod + def create_unix_listener(cls, sock: socket.socket) -> SocketListener: + return UNIXSocketListener(sock) + + @classmethod + async def create_udp_socket( + cls, + family: AddressFamily, + local_address: IPSockAddrType | None, + remote_address: IPSockAddrType | None, + reuse_port: bool, + ) -> UDPSocket | ConnectedUDPSocket: + transport, protocol = await get_running_loop().create_datagram_endpoint( + DatagramProtocol, + local_addr=local_address, + remote_addr=remote_address, + family=family, + reuse_port=reuse_port, + ) + if protocol.exception: + transport.close() + raise protocol.exception + + if not remote_address: + return UDPSocket(transport, protocol) + else: + return ConnectedUDPSocket(transport, protocol) + + @classmethod + async def create_unix_datagram_socket( # type: ignore[override] + cls, raw_socket: socket.socket, remote_path: str | bytes | None + ) -> abc.UNIXDatagramSocket | abc.ConnectedUNIXDatagramSocket: + await cls.checkpoint() + loop = get_running_loop() + + if remote_path: + while True: + try: + raw_socket.connect(remote_path) + except BlockingIOError: + f: asyncio.Future = asyncio.Future() + loop.add_writer(raw_socket, f.set_result, None) + f.add_done_callback(lambda _: loop.remove_writer(raw_socket)) + await f + except BaseException: + raw_socket.close() + raise + else: + return ConnectedUNIXDatagramSocket(raw_socket) + else: + return UNIXDatagramSocket(raw_socket) + + @classmethod + async def getaddrinfo( + cls, + host: bytes | str | None, + port: str | int | None, + *, + family: int | AddressFamily = 0, + type: int | SocketKind = 0, + proto: int = 0, + flags: int = 0, + ) -> Sequence[ + tuple[ + AddressFamily, + SocketKind, + int, + str, + tuple[str, int] | tuple[str, int, int, int] | tuple[int, bytes], + ] + ]: + return await get_running_loop().getaddrinfo( + host, port, family=family, type=type, proto=proto, flags=flags + ) + + @classmethod + async def getnameinfo( + cls, sockaddr: IPSockAddrType, flags: int = 0 + ) -> tuple[str, str]: + return await get_running_loop().getnameinfo(sockaddr, flags) + + @classmethod + async def wait_readable(cls, obj: FileDescriptorLike) -> None: + try: + read_events = _read_events.get() + except LookupError: + read_events = {} + _read_events.set(read_events) + + fd = obj if isinstance(obj, int) else obj.fileno() + if read_events.get(fd): + raise BusyResourceError("reading from") + + loop = get_running_loop() + fut: asyncio.Future[bool] = loop.create_future() + + def cb() -> None: + try: + del read_events[fd] + except KeyError: + pass + else: + remove_reader(fd) + + try: + fut.set_result(True) + except asyncio.InvalidStateError: + pass + + try: + loop.add_reader(fd, cb) + except NotImplementedError: + from anyio._core._asyncio_selector_thread import get_selector + + selector = get_selector() + selector.add_reader(fd, cb) + remove_reader = selector.remove_reader + else: + remove_reader = loop.remove_reader + + read_events[fd] = fut + try: + success = await fut + finally: + try: + del read_events[fd] + except KeyError: + pass + else: + remove_reader(fd) + + if not success: + raise ClosedResourceError + + @classmethod + async def wait_writable(cls, obj: FileDescriptorLike) -> None: + try: + write_events = _write_events.get() + except LookupError: + write_events = {} + _write_events.set(write_events) + + fd = obj if isinstance(obj, int) else obj.fileno() + if write_events.get(fd): + raise BusyResourceError("writing to") + + loop = get_running_loop() + fut: asyncio.Future[bool] = loop.create_future() + + def cb() -> None: + try: + del write_events[fd] + except KeyError: + pass + else: + remove_writer(fd) + + try: + fut.set_result(True) + except asyncio.InvalidStateError: + pass + + try: + loop.add_writer(fd, cb) + except NotImplementedError: + from anyio._core._asyncio_selector_thread import get_selector + + selector = get_selector() + selector.add_writer(fd, cb) + remove_writer = selector.remove_writer + else: + remove_writer = loop.remove_writer + + write_events[fd] = fut + try: + success = await fut + finally: + try: + del write_events[fd] + except KeyError: + pass + else: + remove_writer(fd) + + if not success: + raise ClosedResourceError + + @classmethod + def notify_closing(cls, obj: FileDescriptorLike) -> None: + fd = obj if isinstance(obj, int) else obj.fileno() + loop = get_running_loop() + + try: + write_events = _write_events.get() + except LookupError: + pass + else: + try: + fut = write_events.pop(fd) + except KeyError: + pass + else: + try: + fut.set_result(False) + except asyncio.InvalidStateError: + pass + + try: + loop.remove_writer(fd) + except NotImplementedError: + from anyio._core._asyncio_selector_thread import get_selector + + get_selector().remove_writer(fd) + + try: + read_events = _read_events.get() + except LookupError: + pass + else: + try: + fut = read_events.pop(fd) + except KeyError: + pass + else: + try: + fut.set_result(False) + except asyncio.InvalidStateError: + pass + + try: + loop.remove_reader(fd) + except NotImplementedError: + from anyio._core._asyncio_selector_thread import get_selector + + get_selector().remove_reader(fd) + + @classmethod + async def wrap_listener_socket(cls, sock: socket.socket) -> SocketListener: + return TCPSocketListener(sock) + + @classmethod + async def wrap_stream_socket(cls, sock: socket.socket) -> SocketStream: + transport, protocol = await get_running_loop().create_connection( + StreamProtocol, sock=sock + ) + return SocketStream(transport, protocol) + + @classmethod + async def wrap_unix_stream_socket(cls, sock: socket.socket) -> UNIXSocketStream: + return UNIXSocketStream(sock) + + @classmethod + async def wrap_udp_socket(cls, sock: socket.socket) -> UDPSocket: + transport, protocol = await get_running_loop().create_datagram_endpoint( + DatagramProtocol, sock=sock + ) + return UDPSocket(transport, protocol) + + @classmethod + async def wrap_connected_udp_socket(cls, sock: socket.socket) -> ConnectedUDPSocket: + transport, protocol = await get_running_loop().create_datagram_endpoint( + DatagramProtocol, sock=sock + ) + return ConnectedUDPSocket(transport, protocol) + + @classmethod + async def wrap_unix_datagram_socket(cls, sock: socket.socket) -> UNIXDatagramSocket: + return UNIXDatagramSocket(sock) + + @classmethod + async def wrap_connected_unix_datagram_socket( + cls, sock: socket.socket + ) -> ConnectedUNIXDatagramSocket: + return ConnectedUNIXDatagramSocket(sock) + + @classmethod + def current_default_thread_limiter(cls) -> CapacityLimiter: + try: + return _default_thread_limiter.get() + except LookupError: + limiter = CapacityLimiter(40) + _default_thread_limiter.set(limiter) + return limiter + + @classmethod + def open_signal_receiver( + cls, *signals: Signals + ) -> AbstractContextManager[AsyncIterator[Signals]]: + return _SignalReceiver(signals) + + @classmethod + def get_current_task(cls) -> TaskInfo: + return AsyncIOTaskInfo(current_task()) # type: ignore[arg-type] + + @classmethod + def get_running_tasks(cls) -> Sequence[TaskInfo]: + return [AsyncIOTaskInfo(task) for task in all_tasks() if not task.done()] + + @classmethod + async def wait_all_tasks_blocked(cls) -> None: + await cls.checkpoint() + this_task = current_task() + while True: + for task in all_tasks(): + if task is this_task: + continue + + waiter = task._fut_waiter # type: ignore[attr-defined] + if waiter is None or waiter.done(): + await sleep(0.1) + break + else: + return + + @classmethod + def create_test_runner(cls, options: dict[str, Any]) -> TestRunner: + return TestRunner(**options) + + +backend_class = AsyncIOBackend diff --git a/venv/lib/python3.12/site-packages/anyio/_backends/_trio.py b/venv/lib/python3.12/site-packages/anyio/_backends/_trio.py new file mode 100644 index 0000000..b85a10a --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/_backends/_trio.py @@ -0,0 +1,1343 @@ +from __future__ import annotations + +import array +import math +import os +import socket +import sys +import types +import weakref +from collections.abc import ( + AsyncGenerator, + AsyncIterator, + Awaitable, + Callable, + Collection, + Coroutine, + Iterable, + Sequence, +) +from contextlib import AbstractContextManager +from dataclasses import dataclass +from io import IOBase +from os import PathLike +from signal import Signals +from socket import AddressFamily, SocketKind +from types import TracebackType +from typing import ( + IO, + TYPE_CHECKING, + Any, + Generic, + NoReturn, + ParamSpec, + TypeVar, + cast, + overload, +) + +import trio.from_thread +import trio.lowlevel +from outcome import Error, Outcome, Value +from trio.lowlevel import ( + current_root_task, + current_task, + notify_closing, + wait_readable, + wait_writable, +) +from trio.socket import SocketType as TrioSocketType +from trio.to_thread import run_sync + +from .. import ( + CapacityLimiterStatistics, + EventStatistics, + LockStatistics, + RunFinishedError, + TaskInfo, + WouldBlock, + abc, +) +from .._core._eventloop import claim_worker_thread +from .._core._exceptions import ( + BrokenResourceError, + BusyResourceError, + ClosedResourceError, + EndOfStream, +) +from .._core._sockets import convert_ipv6_sockaddr +from .._core._streams import create_memory_object_stream +from .._core._synchronization import ( + CapacityLimiter as BaseCapacityLimiter, +) +from .._core._synchronization import Event as BaseEvent +from .._core._synchronization import Lock as BaseLock +from .._core._synchronization import ( + ResourceGuard, + SemaphoreStatistics, +) +from .._core._synchronization import Semaphore as BaseSemaphore +from .._core._tasks import CancelScope as BaseCancelScope +from ..abc import IPSockAddrType, UDPPacketType, UNIXDatagramPacketType +from ..abc._eventloop import AsyncBackend, StrOrBytesPath +from ..streams.memory import MemoryObjectSendStream + +if TYPE_CHECKING: + from _typeshed import FileDescriptorLike + +if sys.version_info >= (3, 11): + from typing import TypeVarTuple, Unpack +else: + from exceptiongroup import BaseExceptionGroup + from typing_extensions import TypeVarTuple, Unpack + +T = TypeVar("T") +T_Retval = TypeVar("T_Retval") +T_SockAddr = TypeVar("T_SockAddr", str, IPSockAddrType) +PosArgsT = TypeVarTuple("PosArgsT") +P = ParamSpec("P") + + +# +# Event loop +# + +RunVar = trio.lowlevel.RunVar + + +# +# Timeouts and cancellation +# + + +class CancelScope(BaseCancelScope): + def __new__( + cls, original: trio.CancelScope | None = None, **kwargs: object + ) -> CancelScope: + return object.__new__(cls) + + def __init__(self, original: trio.CancelScope | None = None, **kwargs: Any) -> None: + self.__original = original or trio.CancelScope(**kwargs) + + def __enter__(self) -> CancelScope: + self.__original.__enter__() + return self + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> bool: + return self.__original.__exit__(exc_type, exc_val, exc_tb) + + def cancel(self, reason: str | None = None) -> None: + self.__original.cancel(reason) + + @property + def deadline(self) -> float: + return self.__original.deadline + + @deadline.setter + def deadline(self, value: float) -> None: + self.__original.deadline = value + + @property + def cancel_called(self) -> bool: + return self.__original.cancel_called + + @property + def cancelled_caught(self) -> bool: + return self.__original.cancelled_caught + + @property + def shield(self) -> bool: + return self.__original.shield + + @shield.setter + def shield(self, value: bool) -> None: + self.__original.shield = value + + +# +# Task groups +# + + +class TaskGroup(abc.TaskGroup): + def __init__(self) -> None: + self._active = False + self._nursery_manager = trio.open_nursery(strict_exception_groups=True) + self.cancel_scope = None # type: ignore[assignment] + + async def __aenter__(self) -> TaskGroup: + self._active = True + self._nursery = await self._nursery_manager.__aenter__() + self.cancel_scope = CancelScope(self._nursery.cancel_scope) + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> bool: + try: + # trio.Nursery.__exit__ returns bool; .open_nursery has wrong type + return await self._nursery_manager.__aexit__(exc_type, exc_val, exc_tb) # type: ignore[return-value] + except BaseExceptionGroup as exc: + if not exc.split(trio.Cancelled)[1]: + raise trio.Cancelled._create() from exc + + raise + finally: + del exc_val, exc_tb + self._active = False + + def start_soon( + self, + func: Callable[[Unpack[PosArgsT]], Awaitable[Any]], + *args: Unpack[PosArgsT], + name: object = None, + ) -> None: + if not self._active: + raise RuntimeError( + "This task group is not active; no new tasks can be started." + ) + + self._nursery.start_soon(func, *args, name=name) + + async def start( + self, func: Callable[..., Awaitable[Any]], *args: object, name: object = None + ) -> Any: + if not self._active: + raise RuntimeError( + "This task group is not active; no new tasks can be started." + ) + + return await self._nursery.start(func, *args, name=name) + + +# +# Subprocesses +# + + +@dataclass(eq=False) +class ReceiveStreamWrapper(abc.ByteReceiveStream): + _stream: trio.abc.ReceiveStream + + async def receive(self, max_bytes: int | None = None) -> bytes: + try: + data = await self._stream.receive_some(max_bytes) + except trio.ClosedResourceError as exc: + raise ClosedResourceError from exc.__cause__ + except trio.BrokenResourceError as exc: + raise BrokenResourceError from exc.__cause__ + + if data: + return bytes(data) + else: + raise EndOfStream + + async def aclose(self) -> None: + await self._stream.aclose() + + +@dataclass(eq=False) +class SendStreamWrapper(abc.ByteSendStream): + _stream: trio.abc.SendStream + + async def send(self, item: bytes) -> None: + try: + await self._stream.send_all(item) + except trio.ClosedResourceError as exc: + raise ClosedResourceError from exc.__cause__ + except trio.BrokenResourceError as exc: + raise BrokenResourceError from exc.__cause__ + + async def aclose(self) -> None: + await self._stream.aclose() + + +@dataclass(eq=False) +class Process(abc.Process): + _process: trio.Process + _stdin: abc.ByteSendStream | None + _stdout: abc.ByteReceiveStream | None + _stderr: abc.ByteReceiveStream | None + + async def aclose(self) -> None: + with CancelScope(shield=True): + if self._stdin: + await self._stdin.aclose() + if self._stdout: + await self._stdout.aclose() + if self._stderr: + await self._stderr.aclose() + + try: + await self.wait() + except BaseException: + self.kill() + with CancelScope(shield=True): + await self.wait() + raise + + async def wait(self) -> int: + return await self._process.wait() + + def terminate(self) -> None: + self._process.terminate() + + def kill(self) -> None: + self._process.kill() + + def send_signal(self, signal: Signals) -> None: + self._process.send_signal(signal) + + @property + def pid(self) -> int: + return self._process.pid + + @property + def returncode(self) -> int | None: + return self._process.returncode + + @property + def stdin(self) -> abc.ByteSendStream | None: + return self._stdin + + @property + def stdout(self) -> abc.ByteReceiveStream | None: + return self._stdout + + @property + def stderr(self) -> abc.ByteReceiveStream | None: + return self._stderr + + +class _ProcessPoolShutdownInstrument(trio.abc.Instrument): + def after_run(self) -> None: + super().after_run() + + +current_default_worker_process_limiter: trio.lowlevel.RunVar = RunVar( + "current_default_worker_process_limiter" +) + + +async def _shutdown_process_pool(workers: set[abc.Process]) -> None: + try: + await trio.sleep(math.inf) + except trio.Cancelled: + for process in workers: + if process.returncode is None: + process.kill() + + with CancelScope(shield=True): + for process in workers: + await process.aclose() + + +# +# Sockets and networking +# + + +class _TrioSocketMixin(Generic[T_SockAddr]): + def __init__(self, trio_socket: TrioSocketType) -> None: + self._trio_socket = trio_socket + self._closed = False + + def _check_closed(self) -> None: + if self._closed: + raise ClosedResourceError + if self._trio_socket.fileno() < 0: + raise BrokenResourceError + + @property + def _raw_socket(self) -> socket.socket: + return self._trio_socket._sock # type: ignore[attr-defined] + + async def aclose(self) -> None: + if self._trio_socket.fileno() >= 0: + self._closed = True + self._trio_socket.close() + + def _convert_socket_error(self, exc: BaseException) -> NoReturn: + if isinstance(exc, trio.ClosedResourceError): + raise ClosedResourceError from exc + elif self._trio_socket.fileno() < 0 and self._closed: + raise ClosedResourceError from None + elif isinstance(exc, OSError): + raise BrokenResourceError from exc + else: + raise exc + + +class SocketStream(_TrioSocketMixin, abc.SocketStream): + def __init__(self, trio_socket: TrioSocketType) -> None: + super().__init__(trio_socket) + self._receive_guard = ResourceGuard("reading from") + self._send_guard = ResourceGuard("writing to") + + async def receive(self, max_bytes: int = 65536) -> bytes: + with self._receive_guard: + try: + data = await self._trio_socket.recv(max_bytes) + except BaseException as exc: + self._convert_socket_error(exc) + + if data: + return data + else: + raise EndOfStream + + async def send(self, item: bytes) -> None: + with self._send_guard: + view = memoryview(item) + while view: + try: + bytes_sent = await self._trio_socket.send(view) + except BaseException as exc: + self._convert_socket_error(exc) + + view = view[bytes_sent:] + + async def send_eof(self) -> None: + self._trio_socket.shutdown(socket.SHUT_WR) + + +class UNIXSocketStream(SocketStream, abc.UNIXSocketStream): + async def receive_fds(self, msglen: int, maxfds: int) -> tuple[bytes, list[int]]: + if not isinstance(msglen, int) or msglen < 0: + raise ValueError("msglen must be a non-negative integer") + if not isinstance(maxfds, int) or maxfds < 1: + raise ValueError("maxfds must be a positive integer") + + fds = array.array("i") + await trio.lowlevel.checkpoint() + with self._receive_guard: + while True: + try: + message, ancdata, flags, addr = await self._trio_socket.recvmsg( + msglen, socket.CMSG_LEN(maxfds * fds.itemsize) + ) + except BaseException as exc: + self._convert_socket_error(exc) + else: + if not message and not ancdata: + raise EndOfStream + + break + + for cmsg_level, cmsg_type, cmsg_data in ancdata: + if cmsg_level != socket.SOL_SOCKET or cmsg_type != socket.SCM_RIGHTS: + raise RuntimeError( + f"Received unexpected ancillary data; message = {message!r}, " + f"cmsg_level = {cmsg_level}, cmsg_type = {cmsg_type}" + ) + + fds.frombytes(cmsg_data[: len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) + + return message, list(fds) + + async def send_fds(self, message: bytes, fds: Collection[int | IOBase]) -> None: + if not message: + raise ValueError("message must not be empty") + if not fds: + raise ValueError("fds must not be empty") + + filenos: list[int] = [] + for fd in fds: + if isinstance(fd, int): + filenos.append(fd) + elif isinstance(fd, IOBase): + filenos.append(fd.fileno()) + + fdarray = array.array("i", filenos) + await trio.lowlevel.checkpoint() + with self._send_guard: + while True: + try: + await self._trio_socket.sendmsg( + [message], + [ + ( + socket.SOL_SOCKET, + socket.SCM_RIGHTS, + fdarray, + ) + ], + ) + break + except BaseException as exc: + self._convert_socket_error(exc) + + +class TCPSocketListener(_TrioSocketMixin, abc.SocketListener): + def __init__(self, raw_socket: socket.socket): + super().__init__(trio.socket.from_stdlib_socket(raw_socket)) + self._accept_guard = ResourceGuard("accepting connections from") + + async def accept(self) -> SocketStream: + with self._accept_guard: + try: + trio_socket, _addr = await self._trio_socket.accept() + except BaseException as exc: + self._convert_socket_error(exc) + + trio_socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) + return SocketStream(trio_socket) + + +class UNIXSocketListener(_TrioSocketMixin, abc.SocketListener): + def __init__(self, raw_socket: socket.socket): + super().__init__(trio.socket.from_stdlib_socket(raw_socket)) + self._accept_guard = ResourceGuard("accepting connections from") + + async def accept(self) -> UNIXSocketStream: + with self._accept_guard: + try: + trio_socket, _addr = await self._trio_socket.accept() + except BaseException as exc: + self._convert_socket_error(exc) + + return UNIXSocketStream(trio_socket) + + +class UDPSocket(_TrioSocketMixin[IPSockAddrType], abc.UDPSocket): + def __init__(self, trio_socket: TrioSocketType) -> None: + super().__init__(trio_socket) + self._receive_guard = ResourceGuard("reading from") + self._send_guard = ResourceGuard("writing to") + + async def receive(self) -> tuple[bytes, IPSockAddrType]: + with self._receive_guard: + try: + data, addr = await self._trio_socket.recvfrom(65536) + return data, convert_ipv6_sockaddr(addr) + except BaseException as exc: + self._convert_socket_error(exc) + + async def send(self, item: UDPPacketType) -> None: + with self._send_guard: + try: + await self._trio_socket.sendto(*item) + except BaseException as exc: + self._convert_socket_error(exc) + + +class ConnectedUDPSocket(_TrioSocketMixin[IPSockAddrType], abc.ConnectedUDPSocket): + def __init__(self, trio_socket: TrioSocketType) -> None: + super().__init__(trio_socket) + self._receive_guard = ResourceGuard("reading from") + self._send_guard = ResourceGuard("writing to") + + async def receive(self) -> bytes: + with self._receive_guard: + try: + return await self._trio_socket.recv(65536) + except BaseException as exc: + self._convert_socket_error(exc) + + async def send(self, item: bytes) -> None: + with self._send_guard: + try: + await self._trio_socket.send(item) + except BaseException as exc: + self._convert_socket_error(exc) + + +class UNIXDatagramSocket(_TrioSocketMixin[str], abc.UNIXDatagramSocket): + def __init__(self, trio_socket: TrioSocketType) -> None: + super().__init__(trio_socket) + self._receive_guard = ResourceGuard("reading from") + self._send_guard = ResourceGuard("writing to") + + async def receive(self) -> UNIXDatagramPacketType: + with self._receive_guard: + try: + data, addr = await self._trio_socket.recvfrom(65536) + return data, addr + except BaseException as exc: + self._convert_socket_error(exc) + + async def send(self, item: UNIXDatagramPacketType) -> None: + with self._send_guard: + try: + await self._trio_socket.sendto(*item) + except BaseException as exc: + self._convert_socket_error(exc) + + +class ConnectedUNIXDatagramSocket( + _TrioSocketMixin[str], abc.ConnectedUNIXDatagramSocket +): + def __init__(self, trio_socket: TrioSocketType) -> None: + super().__init__(trio_socket) + self._receive_guard = ResourceGuard("reading from") + self._send_guard = ResourceGuard("writing to") + + async def receive(self) -> bytes: + with self._receive_guard: + try: + return await self._trio_socket.recv(65536) + except BaseException as exc: + self._convert_socket_error(exc) + + async def send(self, item: bytes) -> None: + with self._send_guard: + try: + await self._trio_socket.send(item) + except BaseException as exc: + self._convert_socket_error(exc) + + +# +# Synchronization +# + + +class Event(BaseEvent): + def __new__(cls) -> Event: + return object.__new__(cls) + + def __init__(self) -> None: + self.__original = trio.Event() + + def is_set(self) -> bool: + return self.__original.is_set() + + async def wait(self) -> None: + return await self.__original.wait() + + def statistics(self) -> EventStatistics: + orig_statistics = self.__original.statistics() + return EventStatistics(tasks_waiting=orig_statistics.tasks_waiting) + + def set(self) -> None: + self.__original.set() + + +class Lock(BaseLock): + def __new__(cls, *, fast_acquire: bool = False) -> Lock: + return object.__new__(cls) + + def __init__(self, *, fast_acquire: bool = False) -> None: + self._fast_acquire = fast_acquire + self.__original = trio.Lock() + + @staticmethod + def _convert_runtime_error_msg(exc: RuntimeError) -> None: + if exc.args == ("attempt to re-acquire an already held Lock",): + exc.args = ("Attempted to acquire an already held Lock",) + + async def acquire(self) -> None: + if not self._fast_acquire: + try: + await self.__original.acquire() + except RuntimeError as exc: + self._convert_runtime_error_msg(exc) + raise + + return + + # This is the "fast path" where we don't let other tasks run + await trio.lowlevel.checkpoint_if_cancelled() + try: + self.__original.acquire_nowait() + except trio.WouldBlock: + await self.__original._lot.park() + except RuntimeError as exc: + self._convert_runtime_error_msg(exc) + raise + + def acquire_nowait(self) -> None: + try: + self.__original.acquire_nowait() + except trio.WouldBlock: + raise WouldBlock from None + except RuntimeError as exc: + self._convert_runtime_error_msg(exc) + raise + + def locked(self) -> bool: + return self.__original.locked() + + def release(self) -> None: + self.__original.release() + + def statistics(self) -> LockStatistics: + orig_statistics = self.__original.statistics() + owner = TrioTaskInfo(orig_statistics.owner) if orig_statistics.owner else None + return LockStatistics( + orig_statistics.locked, owner, orig_statistics.tasks_waiting + ) + + +class Semaphore(BaseSemaphore): + def __new__( + cls, + initial_value: int, + *, + max_value: int | None = None, + fast_acquire: bool = False, + ) -> Semaphore: + return object.__new__(cls) + + def __init__( + self, + initial_value: int, + *, + max_value: int | None = None, + fast_acquire: bool = False, + ) -> None: + super().__init__(initial_value, max_value=max_value, fast_acquire=fast_acquire) + self.__original = trio.Semaphore(initial_value, max_value=max_value) + + async def acquire(self) -> None: + if not self._fast_acquire: + await self.__original.acquire() + return + + # This is the "fast path" where we don't let other tasks run + await trio.lowlevel.checkpoint_if_cancelled() + try: + self.__original.acquire_nowait() + except trio.WouldBlock: + await self.__original._lot.park() + + def acquire_nowait(self) -> None: + try: + self.__original.acquire_nowait() + except trio.WouldBlock: + raise WouldBlock from None + + @property + def max_value(self) -> int | None: + return self.__original.max_value + + @property + def value(self) -> int: + return self.__original.value + + def release(self) -> None: + self.__original.release() + + def statistics(self) -> SemaphoreStatistics: + orig_statistics = self.__original.statistics() + return SemaphoreStatistics(orig_statistics.tasks_waiting) + + +class CapacityLimiter(BaseCapacityLimiter): + def __new__( + cls, + total_tokens: float | None = None, + *, + original: trio.CapacityLimiter | None = None, + ) -> CapacityLimiter: + return object.__new__(cls) + + def __init__( + self, + total_tokens: float | None = None, + *, + original: trio.CapacityLimiter | None = None, + ) -> None: + if original is not None: + self.__original = original + else: + assert total_tokens is not None + self.__original = trio.CapacityLimiter(total_tokens) + + async def __aenter__(self) -> None: + return await self.__original.__aenter__() + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: + await self.__original.__aexit__(exc_type, exc_val, exc_tb) + + @property + def total_tokens(self) -> float: + return self.__original.total_tokens + + @total_tokens.setter + def total_tokens(self, value: float) -> None: + self.__original.total_tokens = value + + @property + def borrowed_tokens(self) -> int: + return self.__original.borrowed_tokens + + @property + def available_tokens(self) -> float: + return self.__original.available_tokens + + def acquire_nowait(self) -> None: + self.__original.acquire_nowait() + + def acquire_on_behalf_of_nowait(self, borrower: object) -> None: + self.__original.acquire_on_behalf_of_nowait(borrower) + + async def acquire(self) -> None: + await self.__original.acquire() + + async def acquire_on_behalf_of(self, borrower: object) -> None: + await self.__original.acquire_on_behalf_of(borrower) + + def release(self) -> None: + return self.__original.release() + + def release_on_behalf_of(self, borrower: object) -> None: + return self.__original.release_on_behalf_of(borrower) + + def statistics(self) -> CapacityLimiterStatistics: + orig = self.__original.statistics() + return CapacityLimiterStatistics( + borrowed_tokens=orig.borrowed_tokens, + total_tokens=orig.total_tokens, + borrowers=tuple(orig.borrowers), + tasks_waiting=orig.tasks_waiting, + ) + + +_capacity_limiter_wrapper: trio.lowlevel.RunVar = RunVar("_capacity_limiter_wrapper") + + +# +# Signal handling +# + + +class _SignalReceiver: + _iterator: AsyncIterator[int] + + def __init__(self, signals: tuple[Signals, ...]): + self._signals = signals + + def __enter__(self) -> _SignalReceiver: + self._cm = trio.open_signal_receiver(*self._signals) + self._iterator = self._cm.__enter__() + return self + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> bool | None: + return self._cm.__exit__(exc_type, exc_val, exc_tb) + + def __aiter__(self) -> _SignalReceiver: + return self + + async def __anext__(self) -> Signals: + signum = await self._iterator.__anext__() + return Signals(signum) + + +# +# Testing and debugging +# + + +class TestRunner(abc.TestRunner): + def __init__(self, **options: Any) -> None: + from queue import Queue + + self._call_queue: Queue[Callable[[], object]] = Queue() + self._send_stream: MemoryObjectSendStream | None = None + self._options = options + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: types.TracebackType | None, + ) -> None: + if self._send_stream: + self._send_stream.close() + while self._send_stream is not None: + self._call_queue.get()() + + async def _run_tests_and_fixtures(self) -> None: + self._send_stream, receive_stream = create_memory_object_stream(1) + with receive_stream: + async for coro, outcome_holder in receive_stream: + try: + retval = await coro + except BaseException as exc: + outcome_holder.append(Error(exc)) + else: + outcome_holder.append(Value(retval)) + + def _main_task_finished(self, outcome: object) -> None: + self._send_stream = None + + def _call_in_runner_task( + self, + func: Callable[P, Awaitable[T_Retval]], + /, + *args: P.args, + **kwargs: P.kwargs, + ) -> T_Retval: + if self._send_stream is None: + trio.lowlevel.start_guest_run( + self._run_tests_and_fixtures, + run_sync_soon_threadsafe=self._call_queue.put, + done_callback=self._main_task_finished, + **self._options, + ) + while self._send_stream is None: + self._call_queue.get()() + + outcome_holder: list[Outcome] = [] + self._send_stream.send_nowait((func(*args, **kwargs), outcome_holder)) + while not outcome_holder: + self._call_queue.get()() + + return outcome_holder[0].unwrap() + + def run_asyncgen_fixture( + self, + fixture_func: Callable[..., AsyncGenerator[T_Retval, Any]], + kwargs: dict[str, Any], + ) -> Iterable[T_Retval]: + asyncgen = fixture_func(**kwargs) + fixturevalue: T_Retval = self._call_in_runner_task(asyncgen.asend, None) + + yield fixturevalue + + try: + self._call_in_runner_task(asyncgen.asend, None) + except StopAsyncIteration: + pass + else: + self._call_in_runner_task(asyncgen.aclose) + raise RuntimeError("Async generator fixture did not stop") + + def run_fixture( + self, + fixture_func: Callable[..., Coroutine[Any, Any, T_Retval]], + kwargs: dict[str, Any], + ) -> T_Retval: + return self._call_in_runner_task(fixture_func, **kwargs) + + def run_test( + self, test_func: Callable[..., Coroutine[Any, Any, Any]], kwargs: dict[str, Any] + ) -> None: + self._call_in_runner_task(test_func, **kwargs) + + +class TrioTaskInfo(TaskInfo): + def __init__(self, task: trio.lowlevel.Task): + parent_id = None + if task.parent_nursery and task.parent_nursery.parent_task: + parent_id = id(task.parent_nursery.parent_task) + + super().__init__(id(task), parent_id, task.name, task.coro) + self._task = weakref.proxy(task) + + def has_pending_cancellation(self) -> bool: + try: + return self._task._cancel_status.effectively_cancelled + except ReferenceError: + # If the task is no longer around, it surely doesn't have a cancellation + # pending + return False + + +class TrioBackend(AsyncBackend): + @classmethod + def run( + cls, + func: Callable[[Unpack[PosArgsT]], Awaitable[T_Retval]], + args: tuple[Unpack[PosArgsT]], + kwargs: dict[str, Any], + options: dict[str, Any], + ) -> T_Retval: + return trio.run(func, *args) + + @classmethod + def current_token(cls) -> object: + return trio.lowlevel.current_trio_token() + + @classmethod + def current_time(cls) -> float: + return trio.current_time() + + @classmethod + def cancelled_exception_class(cls) -> type[BaseException]: + return trio.Cancelled + + @classmethod + async def checkpoint(cls) -> None: + await trio.lowlevel.checkpoint() + + @classmethod + async def checkpoint_if_cancelled(cls) -> None: + await trio.lowlevel.checkpoint_if_cancelled() + + @classmethod + async def cancel_shielded_checkpoint(cls) -> None: + await trio.lowlevel.cancel_shielded_checkpoint() + + @classmethod + async def sleep(cls, delay: float) -> None: + await trio.sleep(delay) + + @classmethod + def create_cancel_scope( + cls, *, deadline: float = math.inf, shield: bool = False + ) -> abc.CancelScope: + return CancelScope(deadline=deadline, shield=shield) + + @classmethod + def current_effective_deadline(cls) -> float: + return trio.current_effective_deadline() + + @classmethod + def create_task_group(cls) -> abc.TaskGroup: + return TaskGroup() + + @classmethod + def create_event(cls) -> abc.Event: + return Event() + + @classmethod + def create_lock(cls, *, fast_acquire: bool) -> Lock: + return Lock(fast_acquire=fast_acquire) + + @classmethod + def create_semaphore( + cls, + initial_value: int, + *, + max_value: int | None = None, + fast_acquire: bool = False, + ) -> abc.Semaphore: + return Semaphore(initial_value, max_value=max_value, fast_acquire=fast_acquire) + + @classmethod + def create_capacity_limiter(cls, total_tokens: float) -> CapacityLimiter: + return CapacityLimiter(total_tokens) + + @classmethod + async def run_sync_in_worker_thread( + cls, + func: Callable[[Unpack[PosArgsT]], T_Retval], + args: tuple[Unpack[PosArgsT]], + abandon_on_cancel: bool = False, + limiter: abc.CapacityLimiter | None = None, + ) -> T_Retval: + def wrapper() -> T_Retval: + with claim_worker_thread(TrioBackend, token): + return func(*args) + + token = TrioBackend.current_token() + return await run_sync( + wrapper, + abandon_on_cancel=abandon_on_cancel, + limiter=cast(trio.CapacityLimiter, limiter), + ) + + @classmethod + def check_cancelled(cls) -> None: + trio.from_thread.check_cancelled() + + @classmethod + def run_async_from_thread( + cls, + func: Callable[[Unpack[PosArgsT]], Awaitable[T_Retval]], + args: tuple[Unpack[PosArgsT]], + token: object, + ) -> T_Retval: + trio_token = cast("trio.lowlevel.TrioToken | None", token) + try: + return trio.from_thread.run(func, *args, trio_token=trio_token) + except trio.RunFinishedError: + raise RunFinishedError from None + + @classmethod + def run_sync_from_thread( + cls, + func: Callable[[Unpack[PosArgsT]], T_Retval], + args: tuple[Unpack[PosArgsT]], + token: object, + ) -> T_Retval: + trio_token = cast("trio.lowlevel.TrioToken | None", token) + try: + return trio.from_thread.run_sync(func, *args, trio_token=trio_token) + except trio.RunFinishedError: + raise RunFinishedError from None + + @classmethod + async def open_process( + cls, + command: StrOrBytesPath | Sequence[StrOrBytesPath], + *, + stdin: int | IO[Any] | None, + stdout: int | IO[Any] | None, + stderr: int | IO[Any] | None, + **kwargs: Any, + ) -> Process: + def convert_item(item: StrOrBytesPath) -> str: + str_or_bytes = os.fspath(item) + if isinstance(str_or_bytes, str): + return str_or_bytes + else: + return os.fsdecode(str_or_bytes) + + if isinstance(command, (str, bytes, PathLike)): + process = await trio.lowlevel.open_process( + convert_item(command), + stdin=stdin, + stdout=stdout, + stderr=stderr, + shell=True, + **kwargs, + ) + else: + process = await trio.lowlevel.open_process( + [convert_item(item) for item in command], + stdin=stdin, + stdout=stdout, + stderr=stderr, + shell=False, + **kwargs, + ) + + stdin_stream = SendStreamWrapper(process.stdin) if process.stdin else None + stdout_stream = ReceiveStreamWrapper(process.stdout) if process.stdout else None + stderr_stream = ReceiveStreamWrapper(process.stderr) if process.stderr else None + return Process(process, stdin_stream, stdout_stream, stderr_stream) + + @classmethod + def setup_process_pool_exit_at_shutdown(cls, workers: set[abc.Process]) -> None: + trio.lowlevel.spawn_system_task(_shutdown_process_pool, workers) + + @classmethod + async def connect_tcp( + cls, host: str, port: int, local_address: IPSockAddrType | None = None + ) -> SocketStream: + family = socket.AF_INET6 if ":" in host else socket.AF_INET + trio_socket = trio.socket.socket(family) + trio_socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) + if local_address: + await trio_socket.bind(local_address) + + try: + await trio_socket.connect((host, port)) + except BaseException: + trio_socket.close() + raise + + return SocketStream(trio_socket) + + @classmethod + async def connect_unix(cls, path: str | bytes) -> abc.UNIXSocketStream: + trio_socket = trio.socket.socket(socket.AF_UNIX) + try: + await trio_socket.connect(path) + except BaseException: + trio_socket.close() + raise + + return UNIXSocketStream(trio_socket) + + @classmethod + def create_tcp_listener(cls, sock: socket.socket) -> abc.SocketListener: + return TCPSocketListener(sock) + + @classmethod + def create_unix_listener(cls, sock: socket.socket) -> abc.SocketListener: + return UNIXSocketListener(sock) + + @classmethod + async def create_udp_socket( + cls, + family: socket.AddressFamily, + local_address: IPSockAddrType | None, + remote_address: IPSockAddrType | None, + reuse_port: bool, + ) -> UDPSocket | ConnectedUDPSocket: + trio_socket = trio.socket.socket(family=family, type=socket.SOCK_DGRAM) + + if reuse_port: + trio_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) + + if local_address: + await trio_socket.bind(local_address) + + if remote_address: + await trio_socket.connect(remote_address) + return ConnectedUDPSocket(trio_socket) + else: + return UDPSocket(trio_socket) + + @classmethod + @overload + async def create_unix_datagram_socket( + cls, raw_socket: socket.socket, remote_path: None + ) -> abc.UNIXDatagramSocket: ... + + @classmethod + @overload + async def create_unix_datagram_socket( + cls, raw_socket: socket.socket, remote_path: str | bytes + ) -> abc.ConnectedUNIXDatagramSocket: ... + + @classmethod + async def create_unix_datagram_socket( + cls, raw_socket: socket.socket, remote_path: str | bytes | None + ) -> abc.UNIXDatagramSocket | abc.ConnectedUNIXDatagramSocket: + trio_socket = trio.socket.from_stdlib_socket(raw_socket) + + if remote_path: + await trio_socket.connect(remote_path) + return ConnectedUNIXDatagramSocket(trio_socket) + else: + return UNIXDatagramSocket(trio_socket) + + @classmethod + async def getaddrinfo( + cls, + host: bytes | str | None, + port: str | int | None, + *, + family: int | AddressFamily = 0, + type: int | SocketKind = 0, + proto: int = 0, + flags: int = 0, + ) -> Sequence[ + tuple[ + AddressFamily, + SocketKind, + int, + str, + tuple[str, int] | tuple[str, int, int, int] | tuple[int, bytes], + ] + ]: + return await trio.socket.getaddrinfo(host, port, family, type, proto, flags) + + @classmethod + async def getnameinfo( + cls, sockaddr: IPSockAddrType, flags: int = 0 + ) -> tuple[str, str]: + return await trio.socket.getnameinfo(sockaddr, flags) + + @classmethod + async def wait_readable(cls, obj: FileDescriptorLike) -> None: + try: + await wait_readable(obj) + except trio.ClosedResourceError as exc: + raise ClosedResourceError().with_traceback(exc.__traceback__) from None + except trio.BusyResourceError: + raise BusyResourceError("reading from") from None + + @classmethod + async def wait_writable(cls, obj: FileDescriptorLike) -> None: + try: + await wait_writable(obj) + except trio.ClosedResourceError as exc: + raise ClosedResourceError().with_traceback(exc.__traceback__) from None + except trio.BusyResourceError: + raise BusyResourceError("writing to") from None + + @classmethod + def notify_closing(cls, obj: FileDescriptorLike) -> None: + notify_closing(obj) + + @classmethod + async def wrap_listener_socket(cls, sock: socket.socket) -> abc.SocketListener: + return TCPSocketListener(sock) + + @classmethod + async def wrap_stream_socket(cls, sock: socket.socket) -> SocketStream: + trio_sock = trio.socket.from_stdlib_socket(sock) + return SocketStream(trio_sock) + + @classmethod + async def wrap_unix_stream_socket(cls, sock: socket.socket) -> UNIXSocketStream: + trio_sock = trio.socket.from_stdlib_socket(sock) + return UNIXSocketStream(trio_sock) + + @classmethod + async def wrap_udp_socket(cls, sock: socket.socket) -> UDPSocket: + trio_sock = trio.socket.from_stdlib_socket(sock) + return UDPSocket(trio_sock) + + @classmethod + async def wrap_connected_udp_socket(cls, sock: socket.socket) -> ConnectedUDPSocket: + trio_sock = trio.socket.from_stdlib_socket(sock) + return ConnectedUDPSocket(trio_sock) + + @classmethod + async def wrap_unix_datagram_socket(cls, sock: socket.socket) -> UNIXDatagramSocket: + trio_sock = trio.socket.from_stdlib_socket(sock) + return UNIXDatagramSocket(trio_sock) + + @classmethod + async def wrap_connected_unix_datagram_socket( + cls, sock: socket.socket + ) -> ConnectedUNIXDatagramSocket: + trio_sock = trio.socket.from_stdlib_socket(sock) + return ConnectedUNIXDatagramSocket(trio_sock) + + @classmethod + def current_default_thread_limiter(cls) -> CapacityLimiter: + try: + return _capacity_limiter_wrapper.get() + except LookupError: + limiter = CapacityLimiter( + original=trio.to_thread.current_default_thread_limiter() + ) + _capacity_limiter_wrapper.set(limiter) + return limiter + + @classmethod + def open_signal_receiver( + cls, *signals: Signals + ) -> AbstractContextManager[AsyncIterator[Signals]]: + return _SignalReceiver(signals) + + @classmethod + def get_current_task(cls) -> TaskInfo: + task = current_task() + return TrioTaskInfo(task) + + @classmethod + def get_running_tasks(cls) -> Sequence[TaskInfo]: + root_task = current_root_task() + assert root_task + task_infos = [TrioTaskInfo(root_task)] + nurseries = root_task.child_nurseries + while nurseries: + new_nurseries: list[trio.Nursery] = [] + for nursery in nurseries: + for task in nursery.child_tasks: + task_infos.append(TrioTaskInfo(task)) + new_nurseries.extend(task.child_nurseries) + + nurseries = new_nurseries + + return task_infos + + @classmethod + async def wait_all_tasks_blocked(cls) -> None: + from trio.testing import wait_all_tasks_blocked + + await wait_all_tasks_blocked() + + @classmethod + def create_test_runner(cls, options: dict[str, Any]) -> TestRunner: + return TestRunner(**options) + + +backend_class = TrioBackend diff --git a/venv/lib/python3.12/site-packages/anyio/_core/__init__.py b/venv/lib/python3.12/site-packages/anyio/_core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.12/site-packages/anyio/_core/__pycache__/__init__.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/_core/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ac757fbaa3454c3a059f86d4f959528b7ea40bf5 GIT binary patch literal 199 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_contextmanagers.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_contextmanagers.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f6f86dc3255437fcadedae479d1c94474d4d0859 GIT binary patch literal 9005 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_eventloop.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_eventloop.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..33360286be4536750095dd9b66abac974b1352fa GIT binary patch literal 8198 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_exceptions.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_exceptions.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7b70330e044d9dd6827ad8971893de7146018a56 GIT binary patch literal 7441 zcmcIpU5p#m6~5!KyO)HuRSi$@Sfsx7B>}1gE0H46hw`>zje_#j@7(ct?d&cz zh>qnu*JsYXbMHOpeCNmiY;TVS$sob>=ZMYp;)Y-j4KND zLsn=!gu7~~h46S-(!y4x5FL-oe#B}i#KvO^?ku@dE%_<^NzPmY8=$I25M4L6QH&?P&*_w32H|JwNp|%LG5awc1dbCs6D*9 z{UvN& zH1MvK)L~FHzOK$YB&oN7dV2$PeL0lc^d%iqN~yHzw(WSjXF9e!hTpBbxy^;{IRZbT z1~<6vp{H)M%c;>0L52XMp8OgjahF?8FsGHIvC?VP30WM&+3$SvwQo|!V;;@xge=tV9vhq-+? zW0{kgV%eK^?EBOA-j{JrkKYZ}L;4hVGrCjqov+SB%in#CX_<$i9j`db7%S^Z-jm zEB(IK`X{o-#ukc#qn(@ku2V6Wn43>Vx1qFrwkUNC`dYIn&2;6I!Z!vJrhp@KOOuTg zNsb)wuzt}7@l_VPVSs;BPO*9AVEy4z=SXNi^rk!_E;Y!%$ zR$dH)O$-rlYc>mWcHL~&rR4#=UJ_CXH{jQtwu-u>gQ+!exh9%#USe01Yc3{-FC>SL zsh@XrU+U=l!~E~&-)s3x+n?Gl4QlTWy)|@kFnwV#eSRSGzBsq}!z~|dIk*0N-(x4$ zt9|QFStqTFeOoT{ZTX~cRA*6Y9TX?Z;a##0F0Hd=^`Osei+<@M{TaHM!aW z;l+#*PDqvc2RfuOt!$pHq%hjtIi&xm{v*$w3umfy{&8p9^86~BT&2>rBAa4>}bC1WD(SB~j zB}`3wTFtx~Y-?mWcdA7Sz7pp`z(Eu(y)0<+Vm+D)a38(|+7iLdELK|U&M~D5jo8*w za~m3$thBBvoA6_9cy&#Yvu>qfB{Wc!g;0BI^3uT2yNS0F7Y8yI1~SL?RAa1n?LtUd z({;J4?_~eU;ZM76Ki|1=frU49EyP&&x)W^+Od0B0Xp46BUQe(!YftWcefMHVtT(y9 zV(rOqsx7Q@@GGXY-f_8S;N$}*AN#at(k5 z-w;UXsZb>fBrFNLqGG`~Dl#RJq^5%!3IhZgg`oXb+G}=`>4?sgp%|xcis1D?BH7C7XIjJzEDmz#BAwU>hPjxKFuAco9vv zXlZ3_E{WCPcMw9I2}#A3LaC`}C93BroLfOlC7!Kac0hF`+m7|QBr7QBOHi{LUza3(lvTnz z{52E(me$<4-H%csvt7Drabxb4WeTfnwNMsJ8hN}z(bMwaMo1-@(`gMV!$(H6r$|4f zKLa8{hfL4)ReA&-aAacN0U4%GXz-odBm&YIT^JbP6pBb8CQZxqYU;f5-hYhk32L6e z*A3#+a1fu;lP1p;24N%F@XKj|1(mTkL#IN&iA0#fUhNOFGUk6%Ii)D*J-}W~{8fctQN{oganm(z*VFAB z7p<5J?jVTS+)6jh9_bTr2+V%>pqeC zY<=dlmU}Ms3|;Kme4%GE;dAEL_RIaL_cwmppT3w#Ur3~{0irVtQPwf=`;LVOYtP(p z6PV`Z^kd37<&o$I?T;x6M$FEamf*pruD^ozb$#_wyV#5Ay?(CoTM6*^=#Nl*T6*X5Sj+Wy_6jJ=%J6c{QVc_6MMf_L#=Ti zbHn0M@KsdAH)1pO!eb8dd`g0rVeG?1q~wEI$V5x6uK$KLDKe`jB(Be8U+-l)NPb3&W99@%&n#d zO$!1NpvVFcCU=)}N)|0x`X~~LA?**LkB0aAMi)Y_DQoL*mSNrCX2IxEa@S~Zi6@ur z4AYWziN~o~(YSWd6Kab1E*Vz@#+7U~E@EoZ#^5Mc3ttAGLKbUm^N@T@mOQ@KaSoM= zep&5}Mh#q6vS}WNGS6WXwX`%UXF{K-RpD^#Q$T7IA?PI(Mfh)#6GJl^a1S*#+W{=* z^^)ajhjj~uxO$yVPV#Lwx`z&knir`<5uT4VM7pKph(ArDAGMs^p}7ZZK^(R|G4ac+ z?ab(=H-RvwWXo{Zr3w|E+?4`x##b2{xJn2|(Tkww6@2R<+^D}$qTkX&JI9=zI9U$@ z^Tnm#dlP10*)Bf}m9`pIEb)-c&x9$Wh6DzfpM^;%?SRIk{AQEutEINJd_xM%o0b6U zgD%26PH6&!77SUMs}>>3xDY(L<$}wvNRb}V0ggR$Yq(WU&jU?#IQA z^|Qg7kG77*ZxR18EdJRN7K`2BSQ&)((GzN3r%CD&4oVBxFHLD;w!&>F13OFEy$Np9KpW@f>aDOlCoRr$T^mUvM(H!o7N|DB215B z9*}ni{|3m~QY8w+g>?ujvQ!d40T=8jOy-?RvYu8<(cdpJ8xePc&;KJp7R9M9A~R;0 zb5>evDV)s0WZEG^JsA~Azf@^!a2yhdCDK(Akc4Lz{QqgBMadJqsStl7_OSo2$fM#{ zcrm#w_X-+Rkrd?$yZs9mzryag!q#13eOJ}!MYZRG+H+#+6LtNS@V(V&Sc#oZRT*y8 zWMf}blBdlo!>zhYX;Jnnr(3Ix?$usJ*{RSNx>sWnC3a$_%5YogY*7X-bqp=2xL=K= z79+S8iUD5LXitdX3%I?a3f49Fs&>iTn>aOaq?yl~y z>8|Oo?XE>SS#d|}`s=&vS=bYu(Lb|$rYJ-zRX<=Ti8l1l>Yl~Q^F|x{gWbXYrtYTx z=I-YH+1;~6VL*!{So=u2&75|%oH$)B?!@3GsS4W&m4a3>a-x!d$vNW|wQ}YJ+fS&FU%JCiE%YRwj zNJuYP6oze~;0N?FBxXy(0|T){IMEjyh;I)$vZbBz;ep<*iHI6b#MG?3DIAT4_eUdH znZ=nQ_I6L?$)U(VZv+Lom2e{58x67848Hr>Bv(*s+#-5SSj{@R`Ub+$tn0qWKt%29&C0Q(5j7eM zD<2T1R9zz0lQ^VC!U}$Hpm#^&u_2WK<9R5i3`HY*hX*4eDOJ{l($!IT^GDC6TjSTK_!gnhT-~t!8z=KeuA|q6y1Qj>ld6g!`1HV*h zR!ZQP!S}-VMaq@g=nZD66^Ln3%B(TU9B{bQjW<@#Q|5wa&3u)}HxE2$iBVb^FIFlc zrA-L{8h<2kxXp?_4<8Vf`AQYuS1SvYYSdH%jB4Q54*Nq3vu?&hU479=IEB{o1o3nZ z1jEEwht$|WY$zT)fVaWe{=<>pM7xKj*n6li9%TFzJf?;R5_o*nwc;P=u9xAQp|rj`a;34DOG{dXG?`Kaw~U zQ{utaV}~MYBp5y#?qfV2j15q>U`*{hNbF~=H`KwwYzq?4v66Xku_YYs8{n1lSM)P( zdEGaVh~@p%a~~s~)84VLHE%*48t4rh@8glk5iMyV5{+uX1JR-QAr50_G#ZQn5!Jvn z3^bKK71Rcm2GPeN3NTe;LkABPl0QB)I2cnCaYl=rR_l!oB+zYw{o#S|K@^X6NW^+$ z(crN|eZ7a!da*bfMW_7GfPy|dOcZC$9Zs+k(NtRd1oiS*%M=0cm_1DYI2KrIYV zXzLEGU5LpzHyrCr914byh5Hi082Wh+)!o|O-X6mH;DHWCE=o<0#y>GNNc0Z&4df@F zM1v|Cu9XsmSms`Buw|Wr!Wb09iAn^{3Zvqv(8GHP++pFOxc#D-wf7tt4B4_$JQ6*S zwH+9YQ?6ieGP3AUtUt0y2@mu|7qt_#=m5tS9gC?);)CJd$fARN@xg`hUi62Ey69+R z;OL@g-~L5|!{Fb6rR|HCEQ*5=3z75)+9SRwJTTlBTh!AVQzMHQ-hHw5!Qrgj)6+N5 zm+0vksqCZb zWyCWo>hsYaL2X0?aCaSyV3tX!Y7>56w5iSTveH1fKcW#sZK0Two*peBpslh(Yea8F zy0{nTQI)`%Q$5$X$RTPLshu2p@q} z$|}d|8eVI7x#5+@jKB5N=J$O5vFiGlJlD&s#!CeJ@V8FJy-0qtsugg}mCpHE#hjKQ z+@GPIGl&4k-DIqyY$Y5fM$CH-JM$v&^9_xD`Lx<2fG(0r7fG!`Y7l2=pocmJW6rFD zjbrLUys|d86VeUFw~=y_I6UUlNH{SE4x`Mqs#%$;d8w*-7o@l3i}G7#7t7LBD>A+n zNqI%mw_ z+JS^4WhPlD^<#*O&x2ExD5V!mFD24dYcjqyNqJ4uw?-pN`wH=rc(3%fW5p+dEDl0+ zvAUX2we%!)J<-FLOOM4gD@;ugaLHvUU9~pjTbq>ECVgus)wRfQcXk+)Gt_$kWPVR! zk=Ch3AA9ysM}kc2s#NQ$bX7;j*O8PvlD>{fb>%031X;I^Uc7)18v(y{Ff~#}rl&+l zsgHT+oZXqNI;vg3w)cX<6XAhS22&J5w9K;@%JJVI`GQM?5d0o=C zP8%((pJw^bQz+vr9VywSNJKRdE@1&9_q0acb5iVZoC?z$SZTqew zRo<0DpGr8Xw}I(Xgz40Me08dI_2qr(s!bW+rlhD$En`1ZTM7i48!VNoa=Jxncc zS%vB;Pfkw_5)CddOIK~k_%biaDnG`l5 zyV?w}vd-9n1Mx^A>xAwJiqkk18r1v6r|`onNK?koBW_AQd5Z+;qnD4StGY72uB6X^rDsG+v0NR+m4lY>9Wg|BC`_du?nQ8$MdK`iB1tU=D;Z?C=fN$Rm(HJaGBNS}<6rMwaS%M5-&uA=x-2sk7ltdbaL(l&jDm&pOpeVn`jxO50;l zSV<}^*|YXIG%sNaIl0m`WMe`SFDw%l5D7wmP(zW z7r_cEd`~JK4i8nP!(%Q?9|aX2=SB7ACY4z1NMJV>bf)G%I0_Xsr(0o-qz@UXWz@pn z!K1l3AGgqqlSL)Hlgcuc8krb8CUqtLzSVf2S18~yUgc)xY98J!lO8k+l2ZHUP=oXo zycxPFL_((dUT1UfM2zz^ao*W8CwKuMw9wpY>)1y*!YMlDL4I+T{oH1A z)K1tD8fPKd>8PG47ac2aAjw*C)=}csd5S%nzR=LFtDnQm7x8Bi7Xw1=3{7^s zO?cHIDyg78Rta-n&9AAtu1HNJxiZQeMc`JXfdt8w>=`9BzHQV#DvdfuoujTdNFc?7 znP1FNy~+s}e*>MjtScRvlF>&it&nZxWwv9m12hbVwOtU)Hdu7n*z~|QlzMQeKQe%Q z7uv0f91pY28rqMFqbIV>3+z+S@BKr4(FFD?Iu2l8sN)H0hbOdxI{4_{fo(Frxlv@p zjc*cd$0$zPPc{u_B`SomSIDgr#Z(gi)#Kz0lQTljXUQQET|Gh0Y&c9<*BL`w*AhFh zmbyp@I^nR{`bLXTUYGGTrF>1-WbY~E^yYJ+^PjqK^wP0+TtBRyu-nR=zZ7g9=hGW+ zI0bLj>D|w-O-i-nE<|ank&l{j3EUZFBN2jADCR+s$M(+A?=5NKp zHmapzDdfzS_Ru~(n_jT9KT@NI9@V$++2r|nR_@c}gB;Z)>EHpSIPnq!x7*o@Y48=m z`KIj+txM*M+_dNMv@2l@EDE#{3F`3dfudXFA=VXZsViQzZ{LfJxQg(8>>tMldhowD z4EZ|>DZ$bU2C%!Sei50om3tDgLAEUBl)zSFRw7zJZefBvhRWlKqu8RPAy^aOv$Tgo z@z_JD$ss7V+q4%+B#)Cg!zI|-rc7;Hsz^5aY zh$_ipJ+0BiiE@mNxvU2(2^%aV>=B0|F%}$P77ipzTx*OA8njf7M( ztPDKx$ws0CKG{fkl|g1BQK~%2Y$VDQl`JH>eM+3{BD%}rGkXa5uz={Ugb%xiZoiUX z_6`B~e*CVAR4YTUdoV2`Y7i5HrGpt$%VJ>j@P-CscO8p?^@9;pkC>xMttDm#VvZ?w zmYA6=SG^^sfyKab>0@rjey-u*3vW?kvFG1UMVvH^UFYpFIU7n;0e6Mp_P2 zd*?leNz0b^z(T1Rtu>okD>6?RR$45zx5Cn7?yI6{WulBI^PY8fhl<3vBED@vQa-DM z0AJe_@U=1cmIBXFWxl1R`LHxusIG=t3RH*k ztkQv0_YQ1QRuxa#YddZ`g2f8bHnBYA12$~jmKIR$^U7*Kbnn2d;^iPW^$Q>JEmYPN z(B=!uTFMQMSO<8P8`ytQS&!c<7@iv}c&-GVop`ef{zmv6@HfF<4SzHIHSo8jnNs!sUZ;BSQg0Q^nLDdj=NLp$sR#1CM!+6VtZG#|b z?(G3=dwy;1eS&f;zpI1+&tByfWk39VT3>xt>BZZJLBn$v8vdT50K-R=-&bB!A_#p7 zSf5u8AoS@ev1UDpm!W*!EQ>Y&)M|B|`5IQ4hdwNfVm4qKN*%XoRn7DCM;2lE4c9kt;5SFEFWz%lYr3fcT5{|7>8KIsJ@G^@ z*q|pK8G!X&-_ghuPr#%StHTJ|j`~b&AUe#r0``Sg(^8Z9Z-KDr>h1k7dY&5kTVxn2 zERX8b1=;x@bpmAcFpzh*7s^CZeo2w+Htgip0%v0s5EedvbVxJQl?$%ZI(G zdg>wQ+on%(Z2I?1$q=8mh{*9lENF+~5p~*R2Vv?vIBkkUu(Q^OOh(2jup)!iX$wNn zW9Ga)O5|u??@iP8qT*Xj3Ipbw)qJ22W5;yh13J=$-YktVcHE?_{@Bn!;%0@#VRjz5 zd8*-lqW`poMSE|`Q&AYrPhVI6k(&{cDHNx}Ja!B!;b|cyOQ#;T&vWx+WKw?9R5zuK z8li28o0Kycg>-V0H0atGcBeyM?Y|iXNn?9cKD%j4#W_pRSUVj!iP%u@p=nbL4cwG` zY>=I<7G@Z73r)(?@it}Ubt(#`NfM!=kf3PFFpp&DCo#Cz+EBnk_~hr0g2R20DD6gEt`)2XWu>I~KeIk2?HRE|Z9j9U|0Jd~cNyiEeUo*U{gk6KU zRRzg5<3>t%(!{Bo__skF8YjIPEaux5zqR1vg3D5}Z7pp5J%uLeR6W2JCurYpDuemM zgjn9A>%R<}e+DS+A0EJAhQuKdDbJ)@eFa5~_%vAcR0|1O(#gWg+~oRpWfJ&#ollcVt<3c^=ja_SjUvCCM4HfX104QhkD=M`x4 zajJm~bn+gZXwtuE3+vs1p=Y2TcrJm=#F7lb_&ju-2?ZxXaRwRxI# z7S7i@Zga}loc6UO)lHr^(|nMOPMIPxYV~1olA)CTM0pFwtx`ocPTq2g8>l*j>)S z4r#W2BC$JIyzTzPiXEkS=#z5_yIvkwr)tC5EeI{HsOH0a~Ajmwb^x>BI-iAGAcZd1;`1}Jhf_Cp767{FH}f418y9; zQLms7tRHRd_hd!=5IB<{Cf#ce!p!dYpt^3PQD(0?)*HekKR0N#n`3C! z$-yf?;3tFtm%Vt37{Ono!LJRQnZTS>V2))4nbWq&a3_W+W@=pkUmL;4`yM;(j>^=( zLR=vM?+_SSXB-xug{vg>J%WT&il;b6u>8%(3X9BZiWD;5-x4%@0imb)Ea1`f6vo(1 z3y7rL{P9ssiYFrd1+Df|f{wQuy?<)zRwK55h6V;QhPoBgw<*>tPGrw}^zKk-{+7@z zQrTS##5Z_MyHnnI9HwC#9|L54+k*9~kgh=*gl@(<`>TJ4!nBsrb38*WL()*eu?x>d zPo|X)EAi9Zrz9q-JU^0@>&ERu`PxZlw0Lr1r-%dZ>!nNO2;_7=8l%}5z8rxmmnOYSS$ol~DrLFbum--=lr#-8eAggwJ6uJU-)~y( zFS%&juKstFf$s7WysXFE>DDy^Ug|-l5{4pqK>bIg%3T!y6Jj(ir=&YZd&b4M{#{|9OZJ2A8zY=c`JF97}q0ng=YmgME4 zaL-QpXPf$pagCBQa?mEhpqAfevJU; z;=q`$kLBQ|{fm>{#SBuE#(Gs5O3N9Yh~kWoe#6y^L{<$21HeZpU7Ka-{Wl3zO)lr4 zo?U-tebUQkzr9@-ZCM}RJHc%wY_~9;t$-B_Iy-jcv6q6wOSpqg=N9tGMEV(;o&Ey? z`Loll3ubg00=f1K zwdSDWE>LrjNi09TP$mRsjFkt@dd_&x`p)>qf{VtQm)>wmfwEJZZ+L`2?W=v6S@)!7 z-E%4M-D5u(eS7qsuJnor(z71S)ION@Ka})7l&pPllC4cob_P0|#4FWeXQOy4)VZ_qKP#oUG^(=^SN^>B4-4>st`)>Ho(h2=LMENFH0xl!`>sRe0mSkQu*@|IM2 z%Pq9ww)Bb}=~+87wL8=PT}kh*WbMvLRY18$i=lXdgg4gB{uqJ$ZdPm=YBE07k6O19 zgoLp}Qna%Ohm8{tR4IRob~|GNyLorw!lF~9&XV5}Y-+%&~bHRFK%BQzU&ti*x40=UG?P8Qg8{P7tq>J2N zCMudE5F?=5Fu~F%Ejv+(%GO67nW)J3evHIFqD1%Tq`V>Lj4(vL%;GJn#arGPNzdAy zsokCS?@4<1Bx`qT68F+hLHwS$PX4|dfgIu)vQZZbpZdZvlSOf3s5o0NCB+s&1qPqS zJ)*~iSON-XwaSV7VW?z;EI6pe{AzjvDVlR^EYmI78B zPhyjt3P^D=8JYj&u@{cOU_Fg36>p5TbODbKX zcd7BJuM5{J49SG+LPBf-5 z8lOTSpT@;TMDzINt@ck{G{~po3DE}SpUJ+As$N422Z_M!pvI_&ManS+{qqBWt6qnb z(?2VSe(WaOb|lLZ^^Dc<`#QDWbiL)h=*_gQOtr2|SFOtUR-KaG^HrW+_WW>C27e0W z9g`DevT$;7r%n8h*eOWgEk!7YZq#m!ZV3c#g>JX5PGBeMrWnyo&QqU5#n!W-T)=X2 zW5faxHb9i&YgnG*?+`H&LK&R3bmHJPJf>EF_iEMdjBj^R-ktRAo>U)2>Kq~% z)9DwA5aCV@@6(Y(XDvn+CUtVMIEv1Y9@7f5fIc-uA8z7erur|$K+q=Z-Oqomaz>`I zB~{sSe(&quU+>P$=}67#_@Q#Oa!B^%^y7PPy6R2y_&IujvX?YYkaQLKu17i z{!`3SDR+&JVcZbAM(t+Hv-PoxYs`g<+7R1-Fk9cNxWHUss&;dT%|q*-D8(E=gSpEq zU^QnTcDeoZqIBifLgXN0k@6s0j<|(BK%0JflqsdxDj<>0ShGuT2Y9aVFl9i8pCH zng~;dy0&~WQE#SK41dZ^_-jTGc?9^MM1aLe0s@p-2ryP&GuF6ptZDJMOYk>O2$H|- z)FxU#HRZN6vK!CcIw(4rU3Ed9p9k1Aoe4|eM!QWjB+`8G!_8N#c4d6KlJc&kZda1bAY!w5;Ts6#&kMI>FoX4mVHQ(NYDpLp%V8Q%@*cY1SXTq&&$|#4>3&s*In%oG zY%44iFB51aGD}sR#3_WU#!1-{i!r*kEpCbNB58aDlJi9!jz?FYKJcn?wPf~K)eKs0 zoa%bNtR_Z2vJ>H)35W(x zM(t0E^dga6z9zn8-SmUms9MRYl3}Gb@KS;R(b1TM-mjmXsb7$)U-0H5Z#{PLvCP7C zsfFv(_3JZ%^{3n<#jJY%b4j@YQcTqbaZ;^BSveG=_G81+ol)awORyBscOMEm*gb>^ zx0kRat0RO+w6hqF&Pn;O?Pr=xAfxfzt)q$$I9ZQS6rfKgrXvA;!DLN3lSp7lriL7k zh0}}Mp4*o3&P{peUT(ql0@ZZAfF@Nyv?%u!k;3j)`q0wRa%`l4Jj;kY#(L6{vgsz& znUnI)VV5s_lBweabx2#b5PWXAPeff#RN;a;PcawNP^%DID1YCrE$;&4bi}6sIWqLs ztQfQ;_z=o;b1q$>3i-NfPsX<=Dep=8_I!dm04D=XJM!Cjbsia_kpVk`7pUuo*XWWI!8S!I&MU%1MoQC~lMRe;@E!p<1=^<;~wQ_n+be7#xMoT;0i zs+$k%?rj&hWfp8qE!dc@+m!KdN_saX{kTPw_MdX5EUd5U+aFk`|`4)GX=B!JGrjYC0-H4PKR^_7niwm*yt&ap{IFmFj++Tbt{^rNt)pga19G{|sB2o*q*~V`cS6;& zFXP*nl=mfl`#wQq9BlIS^=|<&x`-HDr(&k+oSqtMQ>|;0yY^kJdN|{II4M7z^gTQU zHSF{~4iBo(#zYX9KgGsGMP%2P)K4)s8Y?Zm4D&l4150kQby`&aTue8r*xs~HwNruB zp0NRIYDAa7lu`SNh+X@Nh;7uSe?jC0A69X*@aJ8wSucj9?dtnLVXyinxFHwr6CI9c zz1pn@I9-k@nJI!?+F?4&LXT88n4`+ z@sSzt`FZd9LRf^9R&arKR?0i;syFz4O)ygvO4Woew7k`Ju`ScKCe_B6zh+;iVjnaO zZZA{}Gg>d$)Ab8}DTwZxadJ+#;8@TL+wi{fVezAJ2~i(m3G^#AIG*gBxzR3OnI(3v zm98}UDBLb>6m3_Qh@I=5SC-l-yj-UE^&-N5F4_>z8E9x`0Skx|T?kmMZb(60jGc;Z zSm9WpKB4AW+Ax~Shhu#MP`4dY&!Lu_72ktISZ-sdCwhn|%hheL)Jg{Cal7(NU|uRP z??NCMXixhVCFMnh1{@#bs5$jcTcJ+Da%-WcndYaWvG{EU{_Nhu93pHdB5=W%r`$;- zph#q+2otAb7#hxs!;&&3RaYJ)ni!ib%c)AZ+x?IQE4@%_ZBCQ!Gm(}!p8)7eNR{^uFI-+Xc z)tYfC52GR;W)-gf7Jh3Q8#*L@Ox`g!&4ZnO&IpH+t&{3y3NMi0{7qIHP@}v~vCP6e}GP3e(H(lnKQS`3U z*+?FzNt`vx6wMMNLTy4K&P?S(pdsU*lk(5e)Gl10KELY1q07#9T-ePCkn*L>bIOK$ zPRr}gRr2c`U5L{52bXj@#qWxplJvcDgmR{oyLP-`cS015H{E8(V+lqMuB0s9y- zID zKdD-KA@b6}v(Yor^Y{L^I+Uzhd#Vc#46l;4?dPP|JTH4Pwe6|e_DjxW?fvh#QnmM| z{acgXt-t!YU8r8iOzJ*Avs0D~N)yum5>l*67#3IwvDiYqze0FxGHfAgj%4lfw0}j? zyJDJ^|EwH?GgDN}2EawK48wgk-$CQv7?d+F;< zXzClyq>v_|ENIK_yUMd`(x><%K%QG$)6{6JOQKe~v;40U-3_~6{$1XYGb3Cnb7}5X zvV{X_Uk&k1<_mk@*?YBqTPCnA?Ry|8KadP;)A!}Y&NA_eUF`JAS0p#WIkYDz@b|GB zG&$IXPt2l8oe5-fB^)|osx6{fx^EHkO#sa>VailCrz)GzuSi$UFSPS9FhVhGTxA&T z#*f=I=dp0mv_?z=s7VdN$rCH`5%~@w(#jCQwe#F)Nk`@Kx@2W@x^mkz_#pSkZ=R&K z5Hbv-IfM~OCv0`bm(2Mn{VAbDv!KNciKCQbh&21w43UWco+19DEtveiUsTMzWi77W zck|b{x1tSU7t$3hP-yp8XH&Yd?yraxEdZQPRrz`^QhB7ymSp55@5)OwWyiu5IJJ4N zbjg|bJzisxQtZ6Lzm_y`d)sMK&i%4}d7q|H%zBteUT9Au1%M1%*Y$xl{adm^rBVx)Z+^2+fIBI2_+bhv1T*J1-Eb$waBkOUuipu zI&E-Z$XFZWzz|lfqheeH>TF<*7N#)0HbS-WBh9SN!Ul zFZgrV+gHEmZx}1D`p_-}=$mft>i@+InorU|@$7cuzot(PL!>e{lW1O??5SWJ~FbOk3H-u((YY zAI@S%=xA)=X(sw*%WyAW5BvHOKFc%|8EIk`lB7E{Z_&w3@(bb&l88QnbZE0z1h36# zJa2zxRWi`>(Y2Zu94)H|zBi*0N6RXLystguDHFczuD8D|*4x2|VdNdThuyRDC~d*& zUujr?4+!8(mh_QEOYm{+tBg2-#CTjH*evrNsdhphwk3gY=*9-|dBtM`SsCA|VxQ;Z zr@KB6jI$1gq530a$VwQS<5^sfg=;)GO-NV5L}GF_aJl#k)GPReNwxkHVSW(lK4P8X z7hb6}n0rp4^}_v^V(H4RQ=70yer?t~?QHX`^sEh;+6|{2WB%IHYsUih*IPoV@}|?$ zY31COYt{AVmi^A*^DP$~$?Apa@`dB2SVfH0ZkS{?L(i=3Y-Tn?LD&oh5zZN{SjQlq zp{+9OW;r?ppv`}Nt*a>*+1>Od3-) z1zIlz(o^r3lb!%M`Tpszi_a9eYx`kVnvCFwzJ}0!-CRJjsGSKzb`_AmVNO@wSZR>u z^r35StdyYNE~3PIq_^Bir&HpR^aIb^p3FU+Df|z0rUM((?90`Kh6Mj&4PC;Tkl!w( zV@sDHS+P~mP>XY`LQ8T_(Kc^O1==nwPY0HyeM^%vzlp?<#8EJ{H{X;XsXeF7VZ@=e zhI$3>^hu1}9TJZmWS>Z}!j&!M&}gqlD*0eWoU11SXVOQ2_~(_wc*8#yt$jGU7ZGS+7T-rNqZA>r?JiZJ z2zr&3_QzsTEqbKJm`t?~k7(8KQeFX~dI7(SFpp)kr#2<~_>>Iz76jYd+aK5JA1T`t zd2)!pyUspq`M7$9K+*EJjVT*t|2Kk*Ah(q5WS7nG*nh;U$r1uN=S#~PWOONwB{z%J zC{Tu1A(>rAGFi>(XZem2Cm~z&QYLm+iONDmBQ}a7vz=c39y!yel=!VDETx%WvgEhM zew%7A$;p6r^3TAMpkS$s<=Rh(Xh^ZNlG;EZ8AO}(TRxu|Q#r+Pp507EL{wj;OsvG; zM+n%l_Y4m6Jv(%0(t)Mq*iA0vL}V9c=QE@AH%nmsF1H4|Ru(a|1$)L!k_CGPp#|s3 zGBg|MEpUrLd?<=d@xFfs{9RqZfUWiz&8||Z3~pNdSz3~nB!M;CLtdV~mXgv~#6QtZ zU47ESabsWdrukj{I+gNSBgB9@gr6Y?6=jrFM=5g4;#sFGgq9p3M^;qT0|;&3zFh~4 zHRtUVHEH?YIzGjNu7|>$eCT4}n=ml&+3?`xqXBDmwij-;wbl}(kQiy;^q6*VVCls! z^kKGnkz0@&Av`7ZDA6&G*QI<8KaWI!oN88IqYR%V$1IR@L*MriyBF!qRxjGt>Teav zZQr|{80L${t5XP#G;hMUGUzk(k3PC%4_otM6%pHi7#bLT36Tfu$UV7zjSqh`Fk6-% zmf+)$g9vSen9*JN;3BCc4i?6~S2Xr_2yT;%T2ry9ijDMP%0(Rk>qBsXM`f>AmBimS z;YpS;ocHxwm8^s4(*W^kED^^&#b2R<=8*FWIrkGt>|XBI=;t@cxj@bzk@F@wm&o}( zIhV=#6LS8PoIfMy&&hd`oWCIFFUk24Ie$$K>(D=;5ThO=%iq#ZMz+7B(Cg&i8U#ny*tdgy)N;aY@ zSxl-}!fV!Y-Sm?zp488f!>l#P=74R8tF#ZR(x#wF+b?RI9MX=fq^4Cz$T>j{sb*AK ziK=WB@*;)Kkn<8bBaAnD~mZXBL5Yi;KQR{Gn~D=#a-@$XPM(>8;l*0%<8Q zA&HK46Hd`F54%@#Nyb%^a@Cw$@vf^GZ`=#$O$#}lBDr(PnKR+EIYJY1F-LT?Qj%sA z<}CZUO>_h&>F9jBbh@|LvRaorsN=I&)E*;56~-OFHUbf5Tu_@UkI zepnm}&K~E1m793rdTGUkgI+MpCCC}puNX1?9x_1bpI zx7*Bzpq>vwJ>PC|Vy4~w0NzRNy*w8M04B3QoaJ~>91GNFfwp!n zu(68=7}S&oSfYck_CSQNQ#h0sF*Qc zLLskEiO;H2s7&zG|J;WVp^q+4ag`Ku3bUHV>SpE?-*COGo{DcUif=HAZ!n5)Fp6)W z;%lk+2BY|f@oJ%}cC2p3SmW%mhNdxab!mwMC0C3);A0+Cw%=yb06G!bY(RbxH2IV>6&`Cx7WW=3g%j-f-YI z;JXtnzjOi|?*WJ3yNY@)*bHM!+qg@1>=Un-uN`+#fEv1)#{mgX*@T;7Zv;fgCh>;T z;iyKYTw>8kG`4#ESW9T!?RU3duLe)RM?p2K#$6QRV-yq zU?MqfUpn0Bgyyrap$#RV)PUq_r=+w2&ILu1T(iF3STqVbA3GfJ_VE5*m6UfX z>5){@`Kpk8AQ-~Qmaw~C>HcS2uI{E7H~UyIR1$H1XB-)u;(JBIgV-cfy_AuZh5So( zbPbtWPEG|mq^@MrUY6fpn6*>g)riGc1cnDuLk)%9J?zJ!h@#d~4%Sxn6q-Q}Q|2^K z=yT*eL(Uh-Apwr;SPx=T1X~%~C~ht}EpR5~HMrFdw^y%IzYP-LKaS?u1OdA)qWDvx z`DcRrZ-uhI6+FMRIYrwq1ais*vH7P$!%u~pU)tQF?Uw?a337f>Er@kL6&nAuz5J(A z@V`orT$LWVe&0h$>7l2$!#VvKIOn66dTuxmh~moArRR>FKl<`hHw5}MzS}O?s8dzf zVFaQ<9@9vmW^B=t@d~#%W6T3t2mW;rCS~~Ohvk0sLxg0(SBHLxkVh!3K|e$Yvuy2n zDTT@)G>rQwR4$Y*WM$D@QvGv3;xGZAP9QO3yp}>vn!7L&6arAE0Z@0{Q%wNW835E7 z0Mr=()ENMfl)?e1GXSU~00IO62`e0cy78GpMPRI|W^6{|SY5+d{j9M-?bxEF;}umR zuN(e#PwBV=zE(GdIPw(Y$Ww?TPa$46g*fsQqPi#i2u<80i!(l~7HlP_B3H%04Vy=7 yIQ`K1xv4;CLO_^cgVc%8FY7nDMbC!o*>tyA@Ta}W27eAYbYm3}iYQC27RxCd_2Ju2vB% zLb1}D_2gZu2Nk?Z&t3!%)<8iJ!QKijSc(T8c<(%bb>t%-hp3Gk7$aZt)lg}x4Ha;~*TOep;cbsc)JuK2=>V1y!h5d(+(a1E z#7FUs0qYWafS2$cHBTD;a|T9B=#Dn@=O~Xa!-V%C|Ao4)KGihnAa3zaY;{Qxr$i2wSP$r|IVdm{5kcBV8B_n~ z$Gl&*-)zQKMG+n%(feW&on%dIB{6cbiI&Ne=`&c?VasXpHg$Z$g3zgfZsvug>vXwT zkP-2y(+p%ZAw5ANDx5{i7M(Ddb0W~l*~QxA1xE%kodD_rX;SHc`hYvG#|3rVyr-;1 zz2sP5i#yL@OXfRa*b^1dkm{8;;P{OW9-;l?s5JKM)Gksq>*cvE!(1C(8C|VxRmRu& z3jbQEelx0HjOrf^;u-0OQ9T&m{z@AvJucTx{QPVktMBkN{e1zz#}ROS!hklhRxcGd z^&&WC?1Csmf=Kr$(FKh=f+d9+&Zu2XO0GNK0S|RukuGAQk~wccbz>qIWcJwE6tB@9 sFpx0eI5e)bx!(!tRWT0NbhqURICfQx@isdB3stvKbzd)ION@d4AIV?x6#xJL literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_signals.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_signals.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..14013dd7bc014ccf79af48631aaa384a5e2f843c GIT binary patch literal 1395 zcmZux&x;&I6t141yE9ouOgyN_!-F`G?KW9YjR^z^vY@LlLSRDZsp+nrF1Nd?c~vvx zhy)LM^_ssyy!d~3i72Q83xasaZDBn~PQL2u8CbL$s$NySdhdJRd#`^yI2bS*kFWnO z|7kP!r`v2t%L~EfCnP*!8Owr#mBAzkoZKo}WqZ=D<#y32yOVA$cZy!wpY%!YX1!vs z+@I_RY`^)k{jC3WXEIptjRw!0`BAVLa;3E8R%&HvdvMRJReEd%a;uRJUb#0j7I|vl z*UE~|?MGbkxo|iAv79Sjm}h~v^wM0|guCa-jHhQpWvTPA9TXqyGZtLFL&6i*V%EK@ z$M?0OLqXag4d6m4$A?s4bFp)mE)boX%~9~ovlE7};^?&F7#>KK>6L*@69TG=t+yR# zig;d%Vhu)vw9eH`7&54VFSX2eo{)6v)Hnd7ML<&2#vE1!x5QHkys8SB`m$>hbp^`D z4cSuP^d>0DL^Q!C?hP#c6|c)WSU~&CPWxJhj#F<>>puKQqSFH#|R$a$Slj z<4P7$=-#9SUqvg8XQrYkqPaBHp-GWbh!J62MunV3)!OD-9fh}UM~15CkW|m8@k~T9 zOC2StMiDjMO<1kb{YmP{3FbALzG4?|v1{-CGJO5#;TyjWkA4~+{qW%F@XpiDolClA zC!-DyX~iB*o1U-pFT($C_=i`13=hY?#~wWz4L5@%IbBeXh$KPR<(n5%T@)g%|0yA# zrPy(&gQj69I_%aSJyG8MAgOEEabMG0hw>f61JcB6G(F#YuhiM15O?tgZ5_F0MAJn( n2!eC==3i`d&JNGnt0Y|XUJma5_QH*eHm!ejkN)n`TATV8c~hfP literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_sockets.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_sockets.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..51d5164b39a9d50f1b19bcce4e9d66aa6c490b72 GIT binary patch literal 40651 zcmeIb33OZ6nI`xiHew|RfcqkXt4N89R!X8|*_1@d)E<#uM8_c^K2QV&5cC5mnF{Dq zWT!%<+-0ib#B{|qrYo)qJ$6+oUFj*MCwMe>C_ZCM=dP@*zlkDNrNLg=Lq`bGBy*t7ckyX8`B9*fY5Xy))bpY3yxeeph%+WNq)-NKL z;nv8y-gV6H39pZA=-t5l-tflArru4F&AppNAy^<&-+ke>$d=wMqA+3zZtdL?%o&!| zLDqkz{8I)&kZH^c!tIgmz1xvLd&k zwa=J(A4E<05@VYC+juD6>gwUDqDE8&V&U9+i$u?a!Edk79rAl(xSv^6`~=r5(?hw6*#f7JFYt?9PnX zW71>N{g|U}{62u+9_h1E2Yw$?$47cx+J*Or)pzw*`kb^I;g19z24SBd?RiF!I)kg! z{jJshs1m;y@%ysGA7^WeR@Z}f>a)}*b)mn#@ePK z9cKcec;G}hNH0<#9vBD*VzEYJ%F%W7^rj9;l7q1rdudZ&?4i-V0FP)iq^w5+@u7pE zQ^AyZU?>um5ad!)?hQmj;qjEcJ34SG7(Wmiks8e@SI_aIoqf9>?A(2z>+rsmv14RB zm2)r@56XdX$}|v&#Z%Vk>7X2r2Be<>0t+ZGZ+CQLBsf5=-Wv#ogHp;CkM_lfnx(EF|DF-4-q^s+w((<11(O@dK zi{+vq{?3yf48`KXk)WJ%@^@Zw%BEN1edzYG^C&Dc1IF8RXe=BLspX-cxjhHFGkaje zJ1_ocv__G|b21q33&h4p2Kr6}Fsc|*1Y**nv0&d|R2~Qpj)lYH2sC$|4vxf8sAm8J z6A$*q1F=(mC*|naXv!7A2=_%t`T~O(cO>@i#i;HH#s=ijXgn&@bT%4(MrY2?9K7P( z&L;LYdCbGb#y#F6dl>vvVKEr3=6**Nlyh% z24k&(k?~Np6`hrXt$i`JYho><<0%IQh1P#xd|*`Gi3Z${|2Jr6{$Jsfb3!^_@Z|sU zh6(TI4JNVC#JfQ~kav(n4ZpV$lDAO$t>kQjli6GOJ_@DUnRAFd)DHOpIF05NLzksu zpsjbF8olDzta3XQyPX`GkCYL!pihcka?FZYWiI?Hn)eu@V)_Ub(g?AZYU6N^&5?Ig zNq4Dfcx6rbMZ6~L1-6`)jXtf-JFZWC5HN?!2Z1j>nqunkiq4KNZ$hr1HeqkiNkrk9 zyT8%GTeAmm*#>jjxKMZ54w}V&`jYsiqAwMHspLzgUn=9fNfN(YEIB5NCW|LaCQB#9 z$+AIBn;a5E55Fj z@iZu(&jU7n&G3Tp56xy_!k(~845OVAKPOJuCLE|wFF{aCm~h&JI4ueGB=m4s!u5rN zakm!Zisz|*wN80eMi0Ddtp1yD4d?4`s&CM6Qk=*gc`qYxp&F2+m%ZyzPe{G>SHp2#~XOynl)dxXamg1|=1GvS!XX)Xo2CSR% zggaI$Sti_x+~G2{PW@LhCOio*pNm0*I(DM)Y}>NZvy1^NeN`eah8kq5A@2?~`ucKNA{V1|SP(vo6*%FW z$d6a8%r#MPp=`KD4b^`W)7>V_jg2x}-RNhxutk_MJeyl1#0dppPc3M98n+48ajg1hZ=DgI zG#(euh)5|uJGDi4_P^l&U)2cfg_wB8APUDZD;U>btEry-bBbf5iXHYf6V1dHpc~6l z|4W{_=2OQ*ul?Cxw33c$wUveFHJ!rjxlpW*GwUbS%=$?+i^6$9Er+n1MrYs;07C6_ zKqy$GKOXf5{Di>x$6}$8lm7Tn(BHHBsDD(B#-jt#aEqNK?->fk{DWg748`_`BBSA8 z1lVJYr3Vrg4~9Vo_<@$kfC2iWgDm1fLd5)?3L@qYgil80P<$xjZ#cGhH!HVo^XAQs zE&i@Se}8`l&eh-VM}11e2(?0Sfw&)}Ml^gnh+3om2%*MkhQI5mUm-Svu_jh%FfcIW zkB$VXjJO;MO8&8tcqq(*6hw&{8HmS&kR<=?Etp-Na zvh^Yd<6|;bwN_C(qtx5`pJG%)3r`wrK}{_h*@%5Mg7p-TGTV|dmAuE@-3O`JM0WY3 zCx$_2Pz%RmK|dCqKN<;PC$aS+1qTDzms;Ww-#M(?jK~BvPA|&5&;rRq!L@UEz{jG= z57Gz&7~!ynMkF>g7MG%DM)akr^_h>gpU7Pmnk^fmC&oemA{azK6WVUEpbVIW!DfL3 zb7KB8!7#ucHItqrw8qb1dpG&pgHH}%I59je7?I8+dpl)0D);*%fpOXvasa6$zceOO z)x>%L$dscIUJ;upz1VKhg&L5>ZUztKW}U#YHf%Jwrvu@!Ae{v(VEeK)kd0VxM>|2YV|9%vz%I>aZW?7JV+D^ySMD^-1VK5#D0TXk-N;vy zQZP+;Og&09-cvh4HR`{*(*bM-Y1H{qdRQZ*=l~}q2Mbm0i&?ph?)r2@qe4G`JnnMIr1t`-Y{4WLyLnI@6fM~6qFkZ+RcBmoxZ^HPx zhJ+tS|0ax289%)ip6-mOB0Dvo+A=jIp+$_SZp>j!inq#P@00!ODy6Y{^LR zHz*$F3+FL z^SVfhP@i;=HH7xU`o^XjfUJ?$|D zm19E4TMkO|R=FABZ&ev7q}IEu&G=TE5#cgzjMoe)%OK}Ho8sW)?(LDQ5q!2rLn<@2 zt^!K{%Nb|+?5Yl6L3fS^%hJJ5mA)AGohhpdS{Y9z<;!y3f%8JV94w}|EFXbSCL%Cp z;eab;B7CW_T&`h(9EO1}zqjw9!`(+acc&acVQ3MBMgZYIN7-qsrR)zA_~pyh9>Q@* zH3NRr9#2`3z3XsiPg}}PoKxcAg9DqRgr*$bM|L0R>+U($*>NakK~{i$nKAV0seINv zJIa&eI9;M6@@gv6M3RD(F&rF`*HWs36lfj@2LrN9^e__OI7+#81!6&sSuEEg2Ax~M z%-TZ*Xlz!UqbEN?5yz>t92`G=Xn0EO!=_+}9Ou_sX)yW#-NBvZ!4wcnSx>it13rdb zYdyV5@fiYxDMKufGJ?~cGEq7<0cdsr=#6}gYU?Jahn$DVc^FQt9FD)A_U3KR1N5xm zzdcQPevYO0|M6}3Sy5T?Iu z2BW!n$yYIbYQeW=(wepk*1Wl#vL#2s)X=MrYmTO+ikg@EUhJD4T5RcuW*`1;{bKvU`Syc1jfN8Y zF9d_nKADqt3YE2U)|yG{)YfEC$)qz`TJ^DDwXMIfe{vUEwkzrOJpb?ueHZ(#x@%v1 zG+9-kg?`+3w1v3ZU&s&%FplSe@%Bph@rVV-Kk|kg5g0KD;g4wn@P0nm}vZC>0!Q@(f z(KcnA>RBqT_ zNKG-7r8^CRZ~LvAPQh9Du^^g@lfI%qvZjsj-Ad-U?CKUkmN)t2*)S?tC>-(Y&jzaIW~y@e>}-NrTh z*9kxLiThhjKg>6hzld7#!wN@NlktZQM)I!}$=}4nH;Bml!%ZSe{$ZQB>wd=%x96bz z_Y4&Np2@PmFy}qHxZmY`&yhoZZw`f*c=xY0zPFZ2d#^=AE$^)>I^Z_`U5yspwWV<%tsq>{%1z z3K`D6$MD(R9H}5egRs|=A)qsUl1eIgvqF_01`Qujc??8IKLV0BdImHF$BH@84q@C7 zXl=M^dHmo~FlR=q-U%gF()@PVHO^l{G=}pX0yYSMYcRGz>J;(V*huI}NHa|o6{ERO z1SRL-mC11;Fh-0@2B&Xg59L0$?ZURHo-0R#)R+%hrUYml`sNbjS1*?Nv4-XRp)^J zN}fsMq-oF~nV-p>uw=*;fKDe2Is!k;bkNjV`LASQJmNf^pE{hoJO#a>?wpJiniNG( znGu^s#&8zM%Ny1V&aPpZoF^w9WV?*uK7455fj#gRkD>JI<83m4MM__QKx@JVR)4s2@&(=gmgz)4Ul=6v&tLnYPl1R3|WKYq^O2> zL-N5SVT9DNN0$jCG_JmynoEf$Tuf#J=@E!R8^TT~lB2u{*MukGk#cC{6Yi4+_+65r zRQPl8FD(-u>RBQ$;n5@r_5@Z48^NlKS~W?CWIF}SQ1&J4!)uksW&Efk$LE>Jpfq`e zp6t`cMeP}Q`;rMnZpJ9(s&ND0|3BsI7ED5%gtzRGax+@2jnmf!$^B;DPxl}GEe47~iw!eQ} z3;PHDJFy2@efaI~Z*SLw+Lo~kd48PTAeKnx!{7Z4IL9Q;&(}u-Wt;&kP3h$_zMpae zwu5{6WGFHg@hd|NcHt9a!7(ap1f(f(`gCGDhH6G>76MwfD3^Lr&o-=Cv%Zaq6(CmH z*tV=X{hVFSX2&Q;&*;J=zAA{5>F1n$jtj*gg3<<1>3Ay>Bs7pnBQ`clFKDxl4k@+k z%tyvsXja#o%11}vz>yuHZjw|5V;_OAVCCxMZ1i@)Q$>*^L5BC6LvYc*6Vd7-{_- z%hzxlt$1L1difV}QzAti31j!uNbUG4db?pqACPa**rn$j$lbgs~U&i4oJx29`y{@l7V>g||)oL70 zVlQbb3={ur#iQaLnKJiA%i+B#^O?}d#tn?WcuTBf?8io*96)yB6UI*fSf0YplpP3> z2PxQ&VA{Hn`^f89I#P)2d${e$;e*G)Bpe4TYcw2)lTZx0vquj05x1_hC*|ut(%1Ru z?t>3?cRk$Mv1iY*hq^nVgnFd!SSNfGpuZhGa;zt1j*W(iWryvbG7*SKSvY)>N2y-$ z?!c37w5E)J@hKZ6=wmFhFHx+C+9-dXyjI37?+Z!tGkBH12q!}!?%X-fxz0ns#zy<( zz!^m(b+%d6JRKPAQvsvS#$K6xD<&qk3C<_y1h6ym3ZI*}FfrY|;I5i9r41!EZ_=5! z=q#UimQO!)%~^BZ?R`G7SlBdQ*mTw1l+4Q~e)g-*HwG759++==;LZALd0jWHLZ0ur z#D&E4nXB%4HH~G_zkc4o{@ZPf8xPHIJoN4p@8^Byx{^O5ZtwiYz3+<77OJ*i%$+h# z4J9k8X12|K=9L|nJm21Z+4?t!z@(e9U3caY4}B^GraJoi+<^-RrgPvY&VBx*op@|sLH+Yr_6)lz{wa}uD3BO zfI^Bl_97K0Miav0*uhY!6DJG_F=N{++Z745hk)nT#1}*$)nz6{*_O*)4EoB4Qn{gJ zo%|wl$ugW6!DgK6Z28=>?KlZU?Mdjjo~^&@y3x`-K?{bU03+tFx;rnezEpEroH9N? zu~^hRU)215Uh}-W^OrF?XUDwto|_o%rMagnxMm z3+8b$-*hLU(XiZy%(qyov&yhnAM-IVB**m)Wj&^ht zkbowBS04d}-A4}Z?b-*~6+>fWIx6|RoS+43|wCXxc0L(ZV9c2Oq zfXxk*@M&_6lcPZ!&Zz%03VQ-h%1Ckn8&yZ}Dh4)-26R$Z71E?EioA{1TFRyd$5Qzx zNJ`Kb936s^6K0dKXV}~U(kW%ipFyS=&>vc$Ky#NpocsRrp@>T zN8eMBrWkB|d(qDw@ZCHr3I+b8)k}Zwf~A`JZ|(r}*mAX|{n>{XU6of|m2Zkmx%rE^ zmGilkuhuVCx6R`(w+&q50t>jtZp*oSH=!n8G;`+P6?M-TFV$QMe5?Mu`xkc{o8NJ4 zVZ*UMHC`?1UdZb?*M<6RzBy}Y(#Zg9^L%0RRcG^()4S-bn|Ib-bFN-;y0Nb=KXT38 zdCl4RK|$S;vt-d(J@2fZ>6vYxt8KeH1`$G`ebNrtm|wo=Yn}JCUa~Lvwoh7@+~w0l z)4dDshB<4)_3~Bc_NEQ1&Aug1;q$TSZC`n6!BhXS;I}nRb|hQYO?D+~n&$uk4P~yv zWaEa9!JIxK&ga)n?Vhfhel%IRdRBb#^K(rP%vBzFbL+bu@9uhY$9(0HsRw^lwH`fu za-r&hsr~3rarMk+{^Sqd*f@LU^&OY1uCCplY~8ll+Bx6axzM`rU2(p3|6Fm?_56y( z{Mz~a+L=ce>pJG^I^JBfP_h@PgY2a~1MFSowfx=^}yF@NpV{Iy`^dzx?_7F15hUfp*szbRQ< z_Ok6o+p7;P)@`1z+kCZna}xav{Hgm#)Q8d+4qZGnQ*$l9KB@KR_%|PaLsvkULJMDpjFk?1|2kwOX~2r#}^Vnk+KTQT7-QILTE?VzHA2mDgb zRsXN>tmK*|p!2F?lM@D=bD98Vcz0?;#i1F01?Q5=M^|W>EHsF&nGV{5U_N_ZSAMf8 zPUy-Hj62^7+*6}TG~Cmp6p-;#*3tGtg4hQ4;5{kEKaMa`3+ zK&%>tA3{?D?ms|(C`JmQjGzWSNAxkt7H-e+dt(Ra1i1?E6;hm&ye%!N66*jIA5R9Q z_ICfqmUXOiG>%<^IQDt-!FIu*O5^_ElfVJM<=}lA#7!whOB08BhA4%E4miu>svf0Q zCMh_c2J;|OOOun{jW+pz#YCryI4(@$i$2a>;Z4v_b@>IP<0wGBavt;43V(~Aw$n(2 znuyLuy+_1f z0tI)LKzgWTDW10$U&GmAbpallbAKJHN8RVwcHAfarPxtn`YRKBf794eDO@QxzmTz<1$%@DNe`&S>%p^GMM$Iz9_m0b^stEe!LBLCS#)iV9_q3X8JQ@_@2t+yF7YPWUz+z|!Sy zwq&$flbR$fYC9QJ9D&@jkU=-=*l_^-70_*u%Gp(58un{{KQZTkqiI^sOtjgQ0g2Qt z>1UW9msmpcl5zNyZOyhFt1JTb@(}3;Mgl~+qZlMrKtgPcUzTOuROry34l%YHu73JY zK-k?1}&R z`Li@f%DKdPakjaW>9_l<`Rr8F3{>j_Sq-i+v|pk4%a)V;zhFflW(4)m{t*u@_k9B) zoZ(|Qo1-w=`MX;uu4IW)4Uofhw*v4HR|oo6d-fgcI3$0QqGrh@tIyA*b0u{!kae8<||e(_4PxVzkRrKO_;FW<`% zcds&i&ssqKRU%xRo>@jxQ|TqhrpfMquAMZvRb)vR<*?2n&%ix3=^*%;hPz{-8L?E$ ziYFshJ9YFVx1ATu??~q85^EjnOynqhR(5+*g~MR?sNw81fvy00%AbsWY4<0Y_J9KO zVVT0BrqzGnFlU?z|LxjkjceGlb}nhBqFy`BX$$V*-MJ06jIq(rQkyy+>|FYDoJ)_A zsxv#AEMvdE?QBxSSOCg8s8LR--CRFqSyapq8;A`xJ7OzWQR9r2Tk3;2+S zUyxy%`%EZBcY_!R1B(VKIAmJ^2NZOZ`DwsZ+5zguUCM^@JZUq4nYX8B70Ro@dXIgVGjVL z&aHU~FSl`Ph$};>*ptmJKn7Q4`Ke*hDKic7XXVl8{GhBFlJ$V-7Oo{3fF9OLYJ-#` z$tDijh*6Nod*h`rvV`N3G(Nu-al+UM88irkz1ipx7+490P7|r3wpF>9#!mu}DL4pl zlL?ni0nuf;mc|3<1mdOQu1iK{oB)|b4?Cj(A5}6#=@C&y!MIL`1ymyGp7|!r3%reY zLK}T0-((pvLk;0K7|BNrnlnQo+_TG0g7E41G}aZTWE4Vyz)8maGR9j|$9NeraTxYb zzKdnd88&Z{j{sasg+Yv0qvlk^qu^)!fD*n#&bQ&jjBrpRXVLtSg2}1Hx{MuwM`h6z zw}SgJwf|K`R*79-OrXPSIkz7;u(yUOu|6>GdEm{`cY78*#}*yO=1j-ZIY{vd81l|; z@m8z~<(;qWaEh;p9ahtySHXA1D0bLQS4?K|+eNqoD%!VfD^sIaZsmJdXJ*Kvh9VAU zL38i8>5ccwW`!z>0#-hC)4zG!rq_-Ot{bgR+VbtMBXld`e`BnUR<6E>mhXt)f}@cE zG}zA0+{eq97r!;oV8s&Z3XJoAETEwv4lAI>y`sB1H2-~qoV%|^1r-DN{}eW*{0HP@ z0YeOo(8aZk5m*U(h<*d?;lL+VcRTJxylHi@D-cZnKauGH0#78d=HO|a;465c@nYlj zfdy~FxdY%K-y^W1WCwH%CJmOcMTJ=mU11<=Q%9BfzZ0kUZ>!+DQY>~XhO*b zrX8h$YDlO`VL!zH%dw`3oJ3Bx(MW*v3|e0qwF%2{;n_)5TNjvCh-pA))NqDbWoyg{ zd>>gDU^y6#p7KKnG(h^IK^gk38Tz*T%1VaW5EXC|r*ecDH4KD9XF)Pc;F>}>L&^x8 z1dc;hAqJ%?#03UmUrp7PBoY@oo+HgHL5S?z1;U&R>e_R-!@ptOx~+64omrt%s)Gy( zdLuzdjy5$jeGbyAZPTzHt~aaHyNrQL`XtaFp+*4eY~Yz8SkhHo8|XGEOd^1(+6Wci zkuVJL0jYsCgLbmc(%#Pzla`Dtq5aIdfzmVuJ)%-FuKKf)RiZM;b*_<{8L3j?3YN)V z{SE!AH8ypVzon&RndU8Bux(d6PcKN{pK-sGEP<@d!}cWvh>8&!MK^d^OGr(r-Osd@ zXs||Ml#+hOM)~b(Afp*$(9qc5&vUEdKN9{iGc}}vgF{(Y!)@Tbf_MOJ#ZXflng|mH zj|R&HrWzC#kVZ{n7z+lW8xzHZ-+2~z;*>cM8wiCMSlX4?FXnHY&)=A|=1)m8 zZI?`!JKrt9g~@_VHw2yHg`&&02gF~P%}&e50-O(=n8?U}BdDVcrnLwCt^!_4{@ z*S;FN=3Wc2qCIaae`;(xbggmc?;yU)(+uzqDz3`$E~)FCR?jAm&y&7j*EgpIeaYm$6QC>%3>z{o?bUUAe+v)WHY* zch@G<6^E1jMeBC8Ip503f&Z;s|E~4Mw^|J3Uni1(y@~v7Hn`d$g934PL=cR0$h5(e zsXVP63y59$kfMSLKD%M>Gw?;6P;6zZfRO+e%{aG61Az@NF&#uM2LtL#*0!g@Gx0YB zTTZsX{Klvfpg^_O3w4NZA#&RN^7a$tXOcY zT6C`!D&92~8^66;oOUP?#lj{q?HZM3v!Y6+XA<$4%Qp@&`!pDs9kJ@L+>Bs2j9t-qAGM^Vg5P_Sox> z^Gzx*A;~>&(lfAv_s_RUfAw2!(%ag651W*@0FaMUR$Q{fR#oyaSjKE_tyy#UNY9!z zezJ&6{5j<=ITkq5>lO(aJP%<#lQ0Wh1ttUw5N;M2fH`Wm{xZP4YLSXc939`-vUP3a z{{#*M!0_A#9Mp;ZJpzZURsQn;2em2kPqBgJ>u@sc0;HC~1uf}^NcDeYz=f7ifeXuy zU_$EfU%asio_jxnU(Y;dzXRf)P1hsYPDsVB*_}_wBQWa#ZjEkAvcDgBAcJ5EE!?Uj z?OW_#((!=?KU5QO-bkALcXp>R2s?DDq*;faSF~P2M76OXl-mx1j*PHzor@h?agnbX_h=OHVWv*oB*#-@G;e( zESNI!aY8fbx()GZfM!8+fvL{{8Ea6$KWlb>|4{|%YeWFX4uD=6e6U4;HS(E+_8qeG zV7&=|5YiP?vdNp=(w8pib9U@8l|Bo<93 z0?&+OJ6QIxwe#s{=RXO`iLD5X6PhF3Q0LvYB!(bkAMz#{lQziYU zV2Vn`zZ-JOt709ZlkZci{Jot&oKTei9`OG)F=a$6Gmab<%$)b>grVEEz&v*>J7KyP z955cXp5dGW%DI4a>|FVs&zAqJVuyD-TkeF|DO3--^gq-RR8RJ7YyY2U31+SG_q7B; zo$D-1G9OFeO^ObHqYi5X#N(!8H#>>05Sutv2Vu5ANvrNL^}J)J2Uy_jQiO`Mlc7Nr zej-HB{=XlvsW5Kjf4~Nk{{x)N-N*vTA>)1OZmjr{+n|GJ7No9M z&PFG7bM3+l=ga7DJrs!qr4X5f2Np$k!%18Nbb?v0U~N!MQfFa$sJ6dZgsg0`lqnt@jnTCuNU(x(JLg5MZ}E3NiJSfdp*Y4c5&)^4(P-`9CdmdHH?|U}$La-U zRwq9}38_)9Fa=IPrhpy;Brp&%&IgBEi`mfPXDhZJI9+HECTqD#?tbc^zAC_G8zTvql(om=-FT59ZAyL*;0702etz1FQ(j#wJ7O!C|8^oRX+ArH|NOVXP&vFnPCF z;k@7=$7!keBjaZRDzN=0IGulAC)Qz=y`H;#Io$@Z{}VxRa-2p0Y%&K2^r>Ai7cQ8J z7ESf@ruv!K`=+(G<4z_dMHcbK*Wk&d%d^V+x9WGobh|c^$ZW){NeG`sX=E0GR zNd-(;=b+dXkEDOQi0RkEYKaJYVfY5h*M&bbCJcj+u#*-5`xU@oHw9kC;lS3&ZZ0Xt z^1h3VnYKbel_P_U;*#eKVGgbisr!hVs$zyb{9SuEF*b5GC<9J%dJ4I@T$)z4R+LIq zDLlFU{yHN12;FA7gk(6MZQ4OHvlN1G9RQG5LN9o908JttB0D>3`LgCc?)P{Al4jG$?^U)eMm>}j`C&=o zbMlcKhaY&Fk{@+mk+h;BhJUAH8uZpzF$#B3qR&r`UW%ZC0P zC8Vo0DJzW;GvZ9jurZwb0*#}h?)N^WBWFD=Y$_59dliXU8(!+XmQ(#|YE;^+Rca3@d^}AXh0H#w7b(B+gsx)pDY|~R z0GLglq;H1UAsF4$$eL`|Mf5Ez2jfu1bKu%cwd&JxyRT4l6ig69}nrkcsgKw5R}u1ktL* zlj$x)y*k7ZT7KJH0o#XvQ)9dUd3rspi3))HG`(luvdkP5lBwL&lA+Y26COO2U1j9( z@$fBC*h@C$Jb@E94e*gs{DGl>uP!teGCf5=!WixekopTZG9M!*77R{-HceT(`?|WR zrc_QW-bbxYSx66Rc5`$c2n~r@3#Z@@Y)Gx_73h)`*kA=c-msAT@=Uh(F60{??U)(+&U+~q!csoo- z6)(E0=iSvao36PV(k7>?c4?LW<&!U-oRPjBnR38p3qbpQ7w?-XTddkNU$yC)Z}U=q z;R{_CyQZbD9sx9;w0`I*dZFTC#Y?AOe(J@iW}n2B%5(dZrrbqS>Ab0Qdh<0?)%6@V zOvI-R7P8@8w&<;$_twtzezWhDzDq-M#~!}sePq%3$ei<$q}w;=u3RdtTr6yuFKl?D z;F9%nEhQ*?WHIlNxx7c9sN*c0GZjp>!};XqW+A`qV?n)Kzru;t>GrTmf?4qiM+ zKd?eVKL;)zP<~)BKrcA;JzRPg<;?K{)@}zu*vshcIO~#gZxihLQ3`BTkJo4Isj`NbO6370O0mq5DTW zRo4$9l!(CxR%YgI=X!zc({M!f>DD?|BtKh;y#Pa2WJt>;U{6|Ra%Wvxt!$ZNV zfb9>^9E6z35*)G`PHcn>=1|Jj2g^_ZLc|B_>tkhQ%vZ~@*gv7&-iU(E2}y^W*%W`` z%lA$1dAaMwu37Wd^5!LP`CP^J1@DeI=MLz|}M#%E4l@?6^Vx7)t8?b6!I$KEtv9-GVS zgr>SL_qwkTW=vc~fMdw>>)1Nfb6)Id5TB`O5xyxlnP!bGxF(H&H^dgj*-I1`9m5ZO7=zJBa_)|P3H=ZH4CQ3 zq}}y&*A0`wd>`lwOYX-8i@E5A5x$Se$CfY4PlKyHD2pEPMho0K1IeISvPh;3kZ2h< zH|C_=bYN%fv9nzDLkUq}BEN;j6}<0+Pb~+D`i&1J=jP&D$d~EP*lqaI*=7#lPT-sJ zF@UzCNJig7Co_Iz!B2Z<2_9!i!!jU8D8bV-1h2w#uiIGNI(OW#+9n6eT7?a(@f+^A zVGZCk(6%(GW#4gI8V}1>S`BtMpl8pa-5eLvwx8@k)G`%ET2g0=R?L^W>HarbQpZq? zvgwSrt)8pfcDeT7Hh!n^a>bh`-u1m} zo~t>$;5{<;(4%wCN3q2ynYPFB#Aoo;v6sXu)1Mh@gc-3T4_Dc0gm2h7T*f!bJFLbl zRx`X;Tt>ubdyF)_a9hSjz0D=ZO->#;9&+xuTYMBt&J1;}2F1{BF=4kj1;^F})0XRI z*T)8v`M9WT5%TgqLb))iduUWQl0&!w`@B3`Hi#8yatR`%Z1F}9LOzv2g{vmr8B{cw zSlR+nVZU6YFA|;7RhU>d9pWd1KNeunn4JZ z=GIO9U>OQu$F&jNOg=NN)P_$2*Jadc);~a@^`Jn%Oap2&3&p4|ZBXt-YKs$Qe$hq$ z6gJVSV6T}2=P^ijLf4NeAJc>)C@BoYLB>VYGl?-^H9l3Q^h4*R1z5%``5%jCl&|;7+vls?4?^q5S z5j3cuzSMf3`dLoG`!chrUx!syXo>sGa%$fpZQ!At~#uCb}6 z`ZJPcel1kh$z+E#rD0_gRiTKRDNJFcvVwuGX=P@tg5^Va$1ljT;Z#1A%9zf}J4PZM zQf9)(uIYoaY=3LD#ZHCzvQT7J5Z7p*KqkFZHJGw1Ekhre#D+v;Oi;swov2tV6kmf3 z@(;P9X_S-hH$am}`SdK_F$J7M!YvTH!4shwMh$c)%zxIyS9iu(K+l;S7@q}blOKoE z=;T+3NbVv3XL2IsFjVey@TJTQ0LVm1u+u7K>j4vkshe}G+K-q<3w?W#KDwOkP)a#6 zS`edCiDq3zw{u}BI3u2}1PcGsh$Hb8Bm~DA3=goZ>#vozUdverOSO}(C7W+*FId<% zVqv#^UrnhL^fbG$@8QCP< zDp0-)yj$6@O57$Y{l8>z`n%%Qyhro3V9aOA+ zK9<>>$6!^D1Jps!UY?18N@s5Rp*4) z#I_Fc7S87JfQ+G{&Ybn}0EM@;ms{ZLWf^!3ANvCkRq|VwYzkjS0zR2+x;p6o>0=C= zd2CrpP0#_Ml|Z}(7V~b1LReirJ41?e@A8{Ya+D{qXJi5 z3K|VhgT)U)w$*f)z<@aefI3iQZ7V*~fg@=YIK-&LkEN ziXdrb$^r=mP&3&@A!O7*c9TPPBxMhr6z83B;fIl`rPj-|4Q1LQ9JI2fMPNZD2+B6Q zOj}JRh?R0S(VF!F??Vc-&Ky|lgz}mlTVN{M9v^N zSKy@F8aAMSft?g}j+{5h`8VXeMb6vgkg*q3Nf>&i93#|4~@;3xh*6{6bKj|57Z7h}`%Sp^^R7{8ZTV zfidszO->f}{p#ZOGldcc{h##MiBs{Hq+HF_8&Lf(IGs`;8$R(smDS06s?DFJwu;}ZHr6+#LZ4mf9)4N(@T+u>eDrCEw1a$3>Zpr+ zxztfN`SJu`McP9?FLjj4!bg+Q(E|9Cj#5~;*3lJJ7qOAGi$zM+MOxKGRCO^`U8GfA zq*Yy{Rb8Z2T|`xTscPaM(->1;t!f%whehNy;+NHkU!_L!*{Kth1~sB27ko-d6jmxU z;QK!XutAWlZAezuB&+K`^6fQ<<*X0nVMUThDU*58joh?@dHE1BFCRnZ<%7t)d=!}% zeOYy*fV?-3nVjO*bTw69Sd^?!YTlLu=Y z3pIy%t%9pEZDU@$kn3SB@u7eC_6N&^A+=Q9aI*xDn((m@l=zXYLd;Ft@x^KUqA*86 zI){8#DuCiJQkMK14)X01h3eMDs;%=?Thqq1Vil6}cA`}dyeFO5Iy@X(CWn03Jo#xG z`RvpTN<{Zb%cZg@ zAC`)x_=bmkL!!{uj;|tplv5&hi`Vluq|M}^@hVHRFcgZ!HWs>5No-psT9Tfov=P6Q zbYnV)eCS45n&N0Qs%|*Q2fDPTHd(PM>G9(4BlkMww3nxi_`Pl~O`Gvc&Gx5l}D*&K0h`A&^IjB`=~q z_`FIp?VZ|&kBYV-hr#5^PaDaXNBhJ>J}*HUANleLz7&wJkYEnWQ7l->Zk8a7QQ7}L DccS81 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_streams.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_streams.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4db6638b7ce06531e9a8f6811c49d180122eb08a GIT binary patch literal 2348 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 K*3uMM$^QV#hg4Aj literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_synchronization.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/_core/__pycache__/_synchronization.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..86436775b08adfb09e4115b54c3a6d41f4020c4b GIT binary patch literal 33135 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 None: + self._thread = threading.Thread(target=self.run, name="AnyIO socket selector") + self._selector = DefaultSelector() + self._send, self._receive = socket.socketpair() + self._send.setblocking(False) + self._receive.setblocking(False) + # This somewhat reduces the amount of memory wasted queueing up data + # for wakeups. With these settings, maximum number of 1-byte sends + # before getting BlockingIOError: + # Linux 4.8: 6 + # macOS (darwin 15.5): 1 + # Windows 10: 525347 + # Windows you're weird. (And on Windows setting SNDBUF to 0 makes send + # blocking, even on non-blocking sockets, so don't do that.) + self._receive.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 1) + self._send.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 1) + # On Windows this is a TCP socket so this might matter. On other + # platforms this fails b/c AF_UNIX sockets aren't actually TCP. + try: + self._send.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) + except OSError: + pass + + self._selector.register(self._receive, EVENT_READ) + self._closed = False + + def start(self) -> None: + self._thread.start() + threading._register_atexit(self._stop) # type: ignore[attr-defined] + + def _stop(self) -> None: + global _selector + self._closed = True + self._notify_self() + self._send.close() + self._thread.join() + self._selector.unregister(self._receive) + self._receive.close() + self._selector.close() + _selector = None + assert not self._selector.get_map(), ( + "selector still has registered file descriptors after shutdown" + ) + + def _notify_self(self) -> None: + try: + self._send.send(b"\x00") + except BlockingIOError: + pass + + def add_reader(self, fd: FileDescriptorLike, callback: Callable[[], Any]) -> None: + loop = asyncio.get_running_loop() + try: + key = self._selector.get_key(fd) + except KeyError: + self._selector.register(fd, EVENT_READ, {EVENT_READ: (loop, callback)}) + else: + if EVENT_READ in key.data: + raise ValueError( + "this file descriptor is already registered for reading" + ) + + key.data[EVENT_READ] = loop, callback + self._selector.modify(fd, key.events | EVENT_READ, key.data) + + self._notify_self() + + def add_writer(self, fd: FileDescriptorLike, callback: Callable[[], Any]) -> None: + loop = asyncio.get_running_loop() + try: + key = self._selector.get_key(fd) + except KeyError: + self._selector.register(fd, EVENT_WRITE, {EVENT_WRITE: (loop, callback)}) + else: + if EVENT_WRITE in key.data: + raise ValueError( + "this file descriptor is already registered for writing" + ) + + key.data[EVENT_WRITE] = loop, callback + self._selector.modify(fd, key.events | EVENT_WRITE, key.data) + + self._notify_self() + + def remove_reader(self, fd: FileDescriptorLike) -> bool: + try: + key = self._selector.get_key(fd) + except KeyError: + return False + + if new_events := key.events ^ EVENT_READ: + del key.data[EVENT_READ] + self._selector.modify(fd, new_events, key.data) + else: + self._selector.unregister(fd) + + return True + + def remove_writer(self, fd: FileDescriptorLike) -> bool: + try: + key = self._selector.get_key(fd) + except KeyError: + return False + + if new_events := key.events ^ EVENT_WRITE: + del key.data[EVENT_WRITE] + self._selector.modify(fd, new_events, key.data) + else: + self._selector.unregister(fd) + + return True + + def run(self) -> None: + while not self._closed: + for key, events in self._selector.select(): + if key.fileobj is self._receive: + try: + while self._receive.recv(4096): + pass + except BlockingIOError: + pass + + continue + + if events & EVENT_READ: + loop, callback = key.data[EVENT_READ] + self.remove_reader(key.fd) + try: + loop.call_soon_threadsafe(callback) + except RuntimeError: + pass # the loop was already closed + + if events & EVENT_WRITE: + loop, callback = key.data[EVENT_WRITE] + self.remove_writer(key.fd) + try: + loop.call_soon_threadsafe(callback) + except RuntimeError: + pass # the loop was already closed + + +def get_selector() -> Selector: + global _selector + + with _selector_lock: + if _selector is None: + _selector = Selector() + _selector.start() + + return _selector diff --git a/venv/lib/python3.12/site-packages/anyio/_core/_contextmanagers.py b/venv/lib/python3.12/site-packages/anyio/_core/_contextmanagers.py new file mode 100644 index 0000000..302f32b --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/_core/_contextmanagers.py @@ -0,0 +1,200 @@ +from __future__ import annotations + +from abc import abstractmethod +from contextlib import AbstractAsyncContextManager, AbstractContextManager +from inspect import isasyncgen, iscoroutine, isgenerator +from types import TracebackType +from typing import Protocol, TypeVar, cast, final + +_T_co = TypeVar("_T_co", covariant=True) +_ExitT_co = TypeVar("_ExitT_co", covariant=True, bound="bool | None") + + +class _SupportsCtxMgr(Protocol[_T_co, _ExitT_co]): + def __contextmanager__(self) -> AbstractContextManager[_T_co, _ExitT_co]: ... + + +class _SupportsAsyncCtxMgr(Protocol[_T_co, _ExitT_co]): + def __asynccontextmanager__( + self, + ) -> AbstractAsyncContextManager[_T_co, _ExitT_co]: ... + + +class ContextManagerMixin: + """ + Mixin class providing context manager functionality via a generator-based + implementation. + + This class allows you to implement a context manager via :meth:`__contextmanager__` + which should return a generator. The mechanics are meant to mirror those of + :func:`@contextmanager `. + + .. note:: Classes using this mix-in are not reentrant as context managers, meaning + that once you enter it, you can't re-enter before first exiting it. + + .. seealso:: :doc:`contextmanagers` + """ + + __cm: AbstractContextManager[object, bool | None] | None = None + + @final + def __enter__(self: _SupportsCtxMgr[_T_co, bool | None]) -> _T_co: + # Needed for mypy to assume self still has the __cm member + assert isinstance(self, ContextManagerMixin) + if self.__cm is not None: + raise RuntimeError( + f"this {self.__class__.__qualname__} has already been entered" + ) + + cm = self.__contextmanager__() + if not isinstance(cm, AbstractContextManager): + if isgenerator(cm): + raise TypeError( + "__contextmanager__() returned a generator object instead of " + "a context manager. Did you forget to add the @contextmanager " + "decorator?" + ) + + raise TypeError( + f"__contextmanager__() did not return a context manager object, " + f"but {cm.__class__!r}" + ) + + if cm is self: + raise TypeError( + f"{self.__class__.__qualname__}.__contextmanager__() returned " + f"self. Did you forget to add the @contextmanager decorator and a " + f"'yield' statement?" + ) + + value = cm.__enter__() + self.__cm = cm + return value + + @final + def __exit__( + self: _SupportsCtxMgr[object, _ExitT_co], + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> _ExitT_co: + # Needed for mypy to assume self still has the __cm member + assert isinstance(self, ContextManagerMixin) + if self.__cm is None: + raise RuntimeError( + f"this {self.__class__.__qualname__} has not been entered yet" + ) + + # Prevent circular references + cm = self.__cm + del self.__cm + + return cast(_ExitT_co, cm.__exit__(exc_type, exc_val, exc_tb)) + + @abstractmethod + def __contextmanager__(self) -> AbstractContextManager[object, bool | None]: + """ + Implement your context manager logic here. + + This method **must** be decorated with + :func:`@contextmanager `. + + .. note:: Remember that the ``yield`` will raise any exception raised in the + enclosed context block, so use a ``finally:`` block to clean up resources! + + :return: a context manager object + """ + + +class AsyncContextManagerMixin: + """ + Mixin class providing async context manager functionality via a generator-based + implementation. + + This class allows you to implement a context manager via + :meth:`__asynccontextmanager__`. The mechanics are meant to mirror those of + :func:`@asynccontextmanager `. + + .. note:: Classes using this mix-in are not reentrant as context managers, meaning + that once you enter it, you can't re-enter before first exiting it. + + .. seealso:: :doc:`contextmanagers` + """ + + __cm: AbstractAsyncContextManager[object, bool | None] | None = None + + @final + async def __aenter__(self: _SupportsAsyncCtxMgr[_T_co, bool | None]) -> _T_co: + # Needed for mypy to assume self still has the __cm member + assert isinstance(self, AsyncContextManagerMixin) + if self.__cm is not None: + raise RuntimeError( + f"this {self.__class__.__qualname__} has already been entered" + ) + + cm = self.__asynccontextmanager__() + if not isinstance(cm, AbstractAsyncContextManager): + if isasyncgen(cm): + raise TypeError( + "__asynccontextmanager__() returned an async generator instead of " + "an async context manager. Did you forget to add the " + "@asynccontextmanager decorator?" + ) + elif iscoroutine(cm): + cm.close() + raise TypeError( + "__asynccontextmanager__() returned a coroutine object instead of " + "an async context manager. Did you forget to add the " + "@asynccontextmanager decorator and a 'yield' statement?" + ) + + raise TypeError( + f"__asynccontextmanager__() did not return an async context manager, " + f"but {cm.__class__!r}" + ) + + if cm is self: + raise TypeError( + f"{self.__class__.__qualname__}.__asynccontextmanager__() returned " + f"self. Did you forget to add the @asynccontextmanager decorator and a " + f"'yield' statement?" + ) + + value = await cm.__aenter__() + self.__cm = cm + return value + + @final + async def __aexit__( + self: _SupportsAsyncCtxMgr[object, _ExitT_co], + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> _ExitT_co: + assert isinstance(self, AsyncContextManagerMixin) + if self.__cm is None: + raise RuntimeError( + f"this {self.__class__.__qualname__} has not been entered yet" + ) + + # Prevent circular references + cm = self.__cm + del self.__cm + + return cast(_ExitT_co, await cm.__aexit__(exc_type, exc_val, exc_tb)) + + @abstractmethod + def __asynccontextmanager__( + self, + ) -> AbstractAsyncContextManager[object, bool | None]: + """ + Implement your async context manager logic here. + + This method **must** be decorated with + :func:`@asynccontextmanager `. + + .. note:: Remember that the ``yield`` will raise any exception raised in the + enclosed context block, so use a ``finally:`` block to clean up resources! + + :return: an async context manager object + """ diff --git a/venv/lib/python3.12/site-packages/anyio/_core/_eventloop.py b/venv/lib/python3.12/site-packages/anyio/_core/_eventloop.py new file mode 100644 index 0000000..59a69cc --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/_core/_eventloop.py @@ -0,0 +1,234 @@ +from __future__ import annotations + +import math +import sys +import threading +from collections.abc import Awaitable, Callable, Generator +from contextlib import contextmanager +from contextvars import Token +from importlib import import_module +from typing import TYPE_CHECKING, Any, TypeVar + +from ._exceptions import NoEventLoopError + +if sys.version_info >= (3, 11): + from typing import TypeVarTuple, Unpack +else: + from typing_extensions import TypeVarTuple, Unpack + +sniffio: Any +try: + import sniffio +except ModuleNotFoundError: + sniffio = None + +if TYPE_CHECKING: + from ..abc import AsyncBackend + +# This must be updated when new backends are introduced +BACKENDS = "asyncio", "trio" + +T_Retval = TypeVar("T_Retval") +PosArgsT = TypeVarTuple("PosArgsT") + +threadlocals = threading.local() +loaded_backends: dict[str, type[AsyncBackend]] = {} + + +def run( + func: Callable[[Unpack[PosArgsT]], Awaitable[T_Retval]], + *args: Unpack[PosArgsT], + backend: str = "asyncio", + backend_options: dict[str, Any] | None = None, +) -> T_Retval: + """ + Run the given coroutine function in an asynchronous event loop. + + The current thread must not be already running an event loop. + + :param func: a coroutine function + :param args: positional arguments to ``func`` + :param backend: name of the asynchronous event loop implementation – currently + either ``asyncio`` or ``trio`` + :param backend_options: keyword arguments to call the backend ``run()`` + implementation with (documented :ref:`here `) + :return: the return value of the coroutine function + :raises RuntimeError: if an asynchronous event loop is already running in this + thread + :raises LookupError: if the named backend is not found + + """ + if asynclib_name := current_async_library(): + raise RuntimeError(f"Already running {asynclib_name} in this thread") + + try: + async_backend = get_async_backend(backend) + except ImportError as exc: + raise LookupError(f"No such backend: {backend}") from exc + + token = None + if asynclib_name is None: + # Since we're in control of the event loop, we can cache the name of the async + # library + token = set_current_async_library(backend) + + try: + backend_options = backend_options or {} + return async_backend.run(func, args, {}, backend_options) + finally: + reset_current_async_library(token) + + +async def sleep(delay: float) -> None: + """ + Pause the current task for the specified duration. + + :param delay: the duration, in seconds + + """ + return await get_async_backend().sleep(delay) + + +async def sleep_forever() -> None: + """ + Pause the current task until it's cancelled. + + This is a shortcut for ``sleep(math.inf)``. + + .. versionadded:: 3.1 + + """ + await sleep(math.inf) + + +async def sleep_until(deadline: float) -> None: + """ + Pause the current task until the given time. + + :param deadline: the absolute time to wake up at (according to the internal + monotonic clock of the event loop) + + .. versionadded:: 3.1 + + """ + now = current_time() + await sleep(max(deadline - now, 0)) + + +def current_time() -> float: + """ + Return the current value of the event loop's internal clock. + + :return: the clock value (seconds) + :raises NoEventLoopError: if no supported asynchronous event loop is running in the + current thread + + """ + return get_async_backend().current_time() + + +def get_all_backends() -> tuple[str, ...]: + """Return a tuple of the names of all built-in backends.""" + return BACKENDS + + +def get_available_backends() -> tuple[str, ...]: + """ + Test for the availability of built-in backends. + + :return a tuple of the built-in backend names that were successfully imported + + .. versionadded:: 4.12 + + """ + available_backends: list[str] = [] + for backend_name in get_all_backends(): + try: + get_async_backend(backend_name) + except ImportError: + continue + + available_backends.append(backend_name) + + return tuple(available_backends) + + +def get_cancelled_exc_class() -> type[BaseException]: + """ + Return the current async library's cancellation exception class. + + :raises NoEventLoopError: if no supported asynchronous event loop is running in the + current thread + + """ + return get_async_backend().cancelled_exception_class() + + +# +# Private API +# + + +@contextmanager +def claim_worker_thread( + backend_class: type[AsyncBackend], token: object +) -> Generator[Any, None, None]: + from ..lowlevel import EventLoopToken + + threadlocals.current_token = EventLoopToken(backend_class, token) + try: + yield + finally: + del threadlocals.current_token + + +def get_async_backend(asynclib_name: str | None = None) -> type[AsyncBackend]: + if asynclib_name is None: + asynclib_name = current_async_library() + if not asynclib_name: + raise NoEventLoopError( + f"Not currently running on any asynchronous event loop. " + f"Available async backends: {', '.join(get_all_backends())}" + ) + + # We use our own dict instead of sys.modules to get the already imported back-end + # class because the appropriate modules in sys.modules could potentially be only + # partially initialized + try: + return loaded_backends[asynclib_name] + except KeyError: + module = import_module(f"anyio._backends._{asynclib_name}") + loaded_backends[asynclib_name] = module.backend_class + return module.backend_class + + +def current_async_library() -> str | None: + if sniffio is None: + # If sniffio is not installed, we assume we're either running asyncio or nothing + import asyncio + + try: + asyncio.get_running_loop() + return "asyncio" + except RuntimeError: + pass + else: + try: + return sniffio.current_async_library() + except sniffio.AsyncLibraryNotFoundError: + pass + + return None + + +def set_current_async_library(asynclib_name: str | None) -> Token | None: + # no-op if sniffio is not installed + if sniffio is None: + return None + + return sniffio.current_async_library_cvar.set(asynclib_name) + + +def reset_current_async_library(token: Token | None) -> None: + if token is not None: + sniffio.current_async_library_cvar.reset(token) diff --git a/venv/lib/python3.12/site-packages/anyio/_core/_exceptions.py b/venv/lib/python3.12/site-packages/anyio/_core/_exceptions.py new file mode 100644 index 0000000..3776bed --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/_core/_exceptions.py @@ -0,0 +1,156 @@ +from __future__ import annotations + +import sys +from collections.abc import Generator +from textwrap import dedent +from typing import Any + +if sys.version_info < (3, 11): + from exceptiongroup import BaseExceptionGroup + + +class BrokenResourceError(Exception): + """ + Raised when trying to use a resource that has been rendered unusable due to external + causes (e.g. a send stream whose peer has disconnected). + """ + + +class BrokenWorkerProcess(Exception): + """ + Raised by :meth:`~anyio.to_process.run_sync` if the worker process terminates abruptly or + otherwise misbehaves. + """ + + +class BrokenWorkerInterpreter(Exception): + """ + Raised by :meth:`~anyio.to_interpreter.run_sync` if an unexpected exception is + raised in the subinterpreter. + """ + + def __init__(self, excinfo: Any): + # This was adapted from concurrent.futures.interpreter.ExecutionFailed + msg = excinfo.formatted + if not msg: + if excinfo.type and excinfo.msg: + msg = f"{excinfo.type.__name__}: {excinfo.msg}" + else: + msg = excinfo.type.__name__ or excinfo.msg + + super().__init__(msg) + self.excinfo = excinfo + + def __str__(self) -> str: + try: + formatted = self.excinfo.errdisplay + except Exception: + return super().__str__() + else: + return dedent( + f""" + {super().__str__()} + + Uncaught in the interpreter: + + {formatted} + """.strip() + ) + + +class BusyResourceError(Exception): + """ + Raised when two tasks are trying to read from or write to the same resource + concurrently. + """ + + def __init__(self, action: str): + super().__init__(f"Another task is already {action} this resource") + + +class ClosedResourceError(Exception): + """Raised when trying to use a resource that has been closed.""" + + +class ConnectionFailed(OSError): + """ + Raised when a connection attempt fails. + + .. note:: This class inherits from :exc:`OSError` for backwards compatibility. + """ + + +def iterate_exceptions( + exception: BaseException, +) -> Generator[BaseException, None, None]: + if isinstance(exception, BaseExceptionGroup): + for exc in exception.exceptions: + yield from iterate_exceptions(exc) + else: + yield exception + + +class DelimiterNotFound(Exception): + """ + Raised during + :meth:`~anyio.streams.buffered.BufferedByteReceiveStream.receive_until` if the + maximum number of bytes has been read without the delimiter being found. + """ + + def __init__(self, max_bytes: int) -> None: + super().__init__( + f"The delimiter was not found among the first {max_bytes} bytes" + ) + + +class EndOfStream(Exception): + """ + Raised when trying to read from a stream that has been closed from the other end. + """ + + +class IncompleteRead(Exception): + """ + Raised during + :meth:`~anyio.streams.buffered.BufferedByteReceiveStream.receive_exactly` or + :meth:`~anyio.streams.buffered.BufferedByteReceiveStream.receive_until` if the + connection is closed before the requested amount of bytes has been read. + """ + + def __init__(self) -> None: + super().__init__( + "The stream was closed before the read operation could be completed" + ) + + +class TypedAttributeLookupError(LookupError): + """ + Raised by :meth:`~anyio.TypedAttributeProvider.extra` when the given typed attribute + is not found and no default value has been given. + """ + + +class WouldBlock(Exception): + """Raised by ``X_nowait`` functions if ``X()`` would block.""" + + +class NoEventLoopError(RuntimeError): + """ + Raised by several functions that require an event loop to be running in the current + thread when there is no running event loop. + + This is also raised by :func:`.from_thread.run` and :func:`.from_thread.run_sync` + if not calling from an AnyIO worker thread, and no ``token`` was passed. + """ + + +class RunFinishedError(RuntimeError): + """ + Raised by :func:`.from_thread.run` and :func:`.from_thread.run_sync` if the event + loop associated with the explicitly passed token has already finished. + """ + + def __init__(self) -> None: + super().__init__( + "The event loop associated with the given token has already finished" + ) diff --git a/venv/lib/python3.12/site-packages/anyio/_core/_fileio.py b/venv/lib/python3.12/site-packages/anyio/_core/_fileio.py new file mode 100644 index 0000000..3bb8c84 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/_core/_fileio.py @@ -0,0 +1,799 @@ +from __future__ import annotations + +import os +import pathlib +import sys +from collections.abc import ( + AsyncIterator, + Callable, + Iterable, + Iterator, + Sequence, +) +from dataclasses import dataclass +from functools import partial +from os import PathLike +from typing import ( + IO, + TYPE_CHECKING, + Any, + AnyStr, + ClassVar, + Final, + Generic, + overload, +) + +from .. import to_thread +from ..abc import AsyncResource + +if TYPE_CHECKING: + from types import ModuleType + + from _typeshed import OpenBinaryMode, OpenTextMode, ReadableBuffer, WriteableBuffer +else: + ReadableBuffer = OpenBinaryMode = OpenTextMode = WriteableBuffer = object + + +class AsyncFile(AsyncResource, Generic[AnyStr]): + """ + An asynchronous file object. + + This class wraps a standard file object and provides async friendly versions of the + following blocking methods (where available on the original file object): + + * read + * read1 + * readline + * readlines + * readinto + * readinto1 + * write + * writelines + * truncate + * seek + * tell + * flush + + All other methods are directly passed through. + + This class supports the asynchronous context manager protocol which closes the + underlying file at the end of the context block. + + This class also supports asynchronous iteration:: + + async with await open_file(...) as f: + async for line in f: + print(line) + """ + + def __init__(self, fp: IO[AnyStr]) -> None: + self._fp: Any = fp + + def __getattr__(self, name: str) -> object: + return getattr(self._fp, name) + + @property + def wrapped(self) -> IO[AnyStr]: + """The wrapped file object.""" + return self._fp + + async def __aiter__(self) -> AsyncIterator[AnyStr]: + while True: + line = await self.readline() + if line: + yield line + else: + break + + async def aclose(self) -> None: + return await to_thread.run_sync(self._fp.close) + + async def read(self, size: int = -1) -> AnyStr: + return await to_thread.run_sync(self._fp.read, size) + + async def read1(self: AsyncFile[bytes], size: int = -1) -> bytes: + return await to_thread.run_sync(self._fp.read1, size) + + async def readline(self) -> AnyStr: + return await to_thread.run_sync(self._fp.readline) + + async def readlines(self) -> list[AnyStr]: + return await to_thread.run_sync(self._fp.readlines) + + async def readinto(self: AsyncFile[bytes], b: WriteableBuffer) -> int: + return await to_thread.run_sync(self._fp.readinto, b) + + async def readinto1(self: AsyncFile[bytes], b: WriteableBuffer) -> int: + return await to_thread.run_sync(self._fp.readinto1, b) + + @overload + async def write(self: AsyncFile[bytes], b: ReadableBuffer) -> int: ... + + @overload + async def write(self: AsyncFile[str], b: str) -> int: ... + + async def write(self, b: ReadableBuffer | str) -> int: + return await to_thread.run_sync(self._fp.write, b) + + @overload + async def writelines( + self: AsyncFile[bytes], lines: Iterable[ReadableBuffer] + ) -> None: ... + + @overload + async def writelines(self: AsyncFile[str], lines: Iterable[str]) -> None: ... + + async def writelines(self, lines: Iterable[ReadableBuffer] | Iterable[str]) -> None: + return await to_thread.run_sync(self._fp.writelines, lines) + + async def truncate(self, size: int | None = None) -> int: + return await to_thread.run_sync(self._fp.truncate, size) + + async def seek(self, offset: int, whence: int | None = os.SEEK_SET) -> int: + return await to_thread.run_sync(self._fp.seek, offset, whence) + + async def tell(self) -> int: + return await to_thread.run_sync(self._fp.tell) + + async def flush(self) -> None: + return await to_thread.run_sync(self._fp.flush) + + +@overload +async def open_file( + file: str | PathLike[str] | int, + mode: OpenBinaryMode, + buffering: int = ..., + encoding: str | None = ..., + errors: str | None = ..., + newline: str | None = ..., + closefd: bool = ..., + opener: Callable[[str, int], int] | None = ..., +) -> AsyncFile[bytes]: ... + + +@overload +async def open_file( + file: str | PathLike[str] | int, + mode: OpenTextMode = ..., + buffering: int = ..., + encoding: str | None = ..., + errors: str | None = ..., + newline: str | None = ..., + closefd: bool = ..., + opener: Callable[[str, int], int] | None = ..., +) -> AsyncFile[str]: ... + + +async def open_file( + file: str | PathLike[str] | int, + mode: str = "r", + buffering: int = -1, + encoding: str | None = None, + errors: str | None = None, + newline: str | None = None, + closefd: bool = True, + opener: Callable[[str, int], int] | None = None, +) -> AsyncFile[Any]: + """ + Open a file asynchronously. + + The arguments are exactly the same as for the builtin :func:`open`. + + :return: an asynchronous file object + + """ + fp = await to_thread.run_sync( + open, file, mode, buffering, encoding, errors, newline, closefd, opener + ) + return AsyncFile(fp) + + +def wrap_file(file: IO[AnyStr]) -> AsyncFile[AnyStr]: + """ + Wrap an existing file as an asynchronous file. + + :param file: an existing file-like object + :return: an asynchronous file object + + """ + return AsyncFile(file) + + +@dataclass(eq=False) +class _PathIterator(AsyncIterator["Path"]): + iterator: Iterator[PathLike[str]] + + async def __anext__(self) -> Path: + nextval = await to_thread.run_sync( + next, self.iterator, None, abandon_on_cancel=True + ) + if nextval is None: + raise StopAsyncIteration from None + + return Path(nextval) + + +class Path: + """ + An asynchronous version of :class:`pathlib.Path`. + + This class cannot be substituted for :class:`pathlib.Path` or + :class:`pathlib.PurePath`, but it is compatible with the :class:`os.PathLike` + interface. + + It implements the Python 3.10 version of :class:`pathlib.Path` interface, except for + the deprecated :meth:`~pathlib.Path.link_to` method. + + Some methods may be unavailable or have limited functionality, based on the Python + version: + + * :meth:`~pathlib.Path.copy` (available on Python 3.14 or later) + * :meth:`~pathlib.Path.copy_into` (available on Python 3.14 or later) + * :meth:`~pathlib.Path.from_uri` (available on Python 3.13 or later) + * :meth:`~pathlib.PurePath.full_match` (available on Python 3.13 or later) + * :attr:`~pathlib.Path.info` (available on Python 3.14 or later) + * :meth:`~pathlib.Path.is_junction` (available on Python 3.12 or later) + * :meth:`~pathlib.PurePath.match` (the ``case_sensitive`` parameter is only + available on Python 3.13 or later) + * :meth:`~pathlib.Path.move` (available on Python 3.14 or later) + * :meth:`~pathlib.Path.move_into` (available on Python 3.14 or later) + * :meth:`~pathlib.PurePath.relative_to` (the ``walk_up`` parameter is only available + on Python 3.12 or later) + * :meth:`~pathlib.Path.walk` (available on Python 3.12 or later) + + Any methods that do disk I/O need to be awaited on. These methods are: + + * :meth:`~pathlib.Path.absolute` + * :meth:`~pathlib.Path.chmod` + * :meth:`~pathlib.Path.cwd` + * :meth:`~pathlib.Path.exists` + * :meth:`~pathlib.Path.expanduser` + * :meth:`~pathlib.Path.group` + * :meth:`~pathlib.Path.hardlink_to` + * :meth:`~pathlib.Path.home` + * :meth:`~pathlib.Path.is_block_device` + * :meth:`~pathlib.Path.is_char_device` + * :meth:`~pathlib.Path.is_dir` + * :meth:`~pathlib.Path.is_fifo` + * :meth:`~pathlib.Path.is_file` + * :meth:`~pathlib.Path.is_junction` + * :meth:`~pathlib.Path.is_mount` + * :meth:`~pathlib.Path.is_socket` + * :meth:`~pathlib.Path.is_symlink` + * :meth:`~pathlib.Path.lchmod` + * :meth:`~pathlib.Path.lstat` + * :meth:`~pathlib.Path.mkdir` + * :meth:`~pathlib.Path.open` + * :meth:`~pathlib.Path.owner` + * :meth:`~pathlib.Path.read_bytes` + * :meth:`~pathlib.Path.read_text` + * :meth:`~pathlib.Path.readlink` + * :meth:`~pathlib.Path.rename` + * :meth:`~pathlib.Path.replace` + * :meth:`~pathlib.Path.resolve` + * :meth:`~pathlib.Path.rmdir` + * :meth:`~pathlib.Path.samefile` + * :meth:`~pathlib.Path.stat` + * :meth:`~pathlib.Path.symlink_to` + * :meth:`~pathlib.Path.touch` + * :meth:`~pathlib.Path.unlink` + * :meth:`~pathlib.Path.walk` + * :meth:`~pathlib.Path.write_bytes` + * :meth:`~pathlib.Path.write_text` + + Additionally, the following methods return an async iterator yielding + :class:`~.Path` objects: + + * :meth:`~pathlib.Path.glob` + * :meth:`~pathlib.Path.iterdir` + * :meth:`~pathlib.Path.rglob` + """ + + __slots__ = "_path", "__weakref__" + + __weakref__: Any + + def __init__(self, *args: str | PathLike[str]) -> None: + self._path: Final[pathlib.Path] = pathlib.Path(*args) + + def __fspath__(self) -> str: + return self._path.__fspath__() + + if sys.version_info >= (3, 15): + + def __vfspath__(self) -> str: + return self._path.__vfspath__() + + def __str__(self) -> str: + return self._path.__str__() + + def __repr__(self) -> str: + return f"{self.__class__.__name__}({self.as_posix()!r})" + + def __bytes__(self) -> bytes: + return self._path.__bytes__() + + def __hash__(self) -> int: + return self._path.__hash__() + + def __eq__(self, other: object) -> bool: + target = other._path if isinstance(other, Path) else other + return self._path.__eq__(target) + + def __lt__(self, other: pathlib.PurePath | Path) -> bool: + target = other._path if isinstance(other, Path) else other + return self._path.__lt__(target) + + def __le__(self, other: pathlib.PurePath | Path) -> bool: + target = other._path if isinstance(other, Path) else other + return self._path.__le__(target) + + def __gt__(self, other: pathlib.PurePath | Path) -> bool: + target = other._path if isinstance(other, Path) else other + return self._path.__gt__(target) + + def __ge__(self, other: pathlib.PurePath | Path) -> bool: + target = other._path if isinstance(other, Path) else other + return self._path.__ge__(target) + + def __truediv__(self, other: str | PathLike[str]) -> Path: + return Path(self._path / other) + + def __rtruediv__(self, other: str | PathLike[str]) -> Path: + return Path(other) / self + + @property + def parts(self) -> tuple[str, ...]: + return self._path.parts + + @property + def drive(self) -> str: + return self._path.drive + + @property + def root(self) -> str: + return self._path.root + + @property + def anchor(self) -> str: + return self._path.anchor + + @property + def parents(self) -> Sequence[Path]: + return tuple(Path(p) for p in self._path.parents) + + @property + def parent(self) -> Path: + return Path(self._path.parent) + + @property + def name(self) -> str: + return self._path.name + + @property + def suffix(self) -> str: + return self._path.suffix + + @property + def suffixes(self) -> list[str]: + return self._path.suffixes + + @property + def stem(self) -> str: + return self._path.stem + + async def absolute(self) -> Path: + path = await to_thread.run_sync(self._path.absolute) + return Path(path) + + def as_posix(self) -> str: + return self._path.as_posix() + + def as_uri(self) -> str: + return self._path.as_uri() + + if sys.version_info >= (3, 13): + parser: ClassVar[ModuleType] = pathlib.Path.parser + + @classmethod + def from_uri(cls, uri: str) -> Path: + return Path(pathlib.Path.from_uri(uri)) + + def full_match( + self, path_pattern: str, *, case_sensitive: bool | None = None + ) -> bool: + return self._path.full_match(path_pattern, case_sensitive=case_sensitive) + + def match( + self, path_pattern: str, *, case_sensitive: bool | None = None + ) -> bool: + return self._path.match(path_pattern, case_sensitive=case_sensitive) + else: + + def match(self, path_pattern: str) -> bool: + return self._path.match(path_pattern) + + if sys.version_info >= (3, 14): + + @property + def info(self) -> Any: # TODO: add return type annotation when Typeshed gets it + return self._path.info + + async def copy( + self, + target: str | os.PathLike[str], + *, + follow_symlinks: bool = True, + preserve_metadata: bool = False, + ) -> Path: + func = partial( + self._path.copy, + follow_symlinks=follow_symlinks, + preserve_metadata=preserve_metadata, + ) + return Path(await to_thread.run_sync(func, pathlib.Path(target))) + + async def copy_into( + self, + target_dir: str | os.PathLike[str], + *, + follow_symlinks: bool = True, + preserve_metadata: bool = False, + ) -> Path: + func = partial( + self._path.copy_into, + follow_symlinks=follow_symlinks, + preserve_metadata=preserve_metadata, + ) + return Path(await to_thread.run_sync(func, pathlib.Path(target_dir))) + + async def move(self, target: str | os.PathLike[str]) -> Path: + # Upstream does not handle anyio.Path properly as a PathLike + target = pathlib.Path(target) + return Path(await to_thread.run_sync(self._path.move, target)) + + async def move_into( + self, + target_dir: str | os.PathLike[str], + ) -> Path: + return Path(await to_thread.run_sync(self._path.move_into, target_dir)) + + def is_relative_to(self, other: str | PathLike[str]) -> bool: + try: + self.relative_to(other) + return True + except ValueError: + return False + + async def chmod(self, mode: int, *, follow_symlinks: bool = True) -> None: + func = partial(os.chmod, follow_symlinks=follow_symlinks) + return await to_thread.run_sync(func, self._path, mode) + + @classmethod + async def cwd(cls) -> Path: + path = await to_thread.run_sync(pathlib.Path.cwd) + return cls(path) + + async def exists(self) -> bool: + return await to_thread.run_sync(self._path.exists, abandon_on_cancel=True) + + async def expanduser(self) -> Path: + return Path( + await to_thread.run_sync(self._path.expanduser, abandon_on_cancel=True) + ) + + if sys.version_info < (3, 12): + # Python 3.11 and earlier + def glob(self, pattern: str) -> AsyncIterator[Path]: + gen = self._path.glob(pattern) + return _PathIterator(gen) + elif (3, 12) <= sys.version_info < (3, 13): + # changed in Python 3.12: + # - The case_sensitive parameter was added. + def glob( + self, + pattern: str, + *, + case_sensitive: bool | None = None, + ) -> AsyncIterator[Path]: + gen = self._path.glob(pattern, case_sensitive=case_sensitive) + return _PathIterator(gen) + elif sys.version_info >= (3, 13): + # Changed in Python 3.13: + # - The recurse_symlinks parameter was added. + # - The pattern parameter accepts a path-like object. + def glob( # type: ignore[misc] # mypy doesn't allow for differing signatures in a conditional block + self, + pattern: str | PathLike[str], + *, + case_sensitive: bool | None = None, + recurse_symlinks: bool = False, + ) -> AsyncIterator[Path]: + gen = self._path.glob( + pattern, # type: ignore[arg-type] + case_sensitive=case_sensitive, + recurse_symlinks=recurse_symlinks, + ) + return _PathIterator(gen) + + async def group(self) -> str: + return await to_thread.run_sync(self._path.group, abandon_on_cancel=True) + + async def hardlink_to( + self, target: str | bytes | PathLike[str] | PathLike[bytes] + ) -> None: + if isinstance(target, Path): + target = target._path + + await to_thread.run_sync(os.link, target, self) + + @classmethod + async def home(cls) -> Path: + home_path = await to_thread.run_sync(pathlib.Path.home) + return cls(home_path) + + def is_absolute(self) -> bool: + return self._path.is_absolute() + + async def is_block_device(self) -> bool: + return await to_thread.run_sync( + self._path.is_block_device, abandon_on_cancel=True + ) + + async def is_char_device(self) -> bool: + return await to_thread.run_sync( + self._path.is_char_device, abandon_on_cancel=True + ) + + async def is_dir(self) -> bool: + return await to_thread.run_sync(self._path.is_dir, abandon_on_cancel=True) + + async def is_fifo(self) -> bool: + return await to_thread.run_sync(self._path.is_fifo, abandon_on_cancel=True) + + async def is_file(self) -> bool: + return await to_thread.run_sync(self._path.is_file, abandon_on_cancel=True) + + if sys.version_info >= (3, 12): + + async def is_junction(self) -> bool: + return await to_thread.run_sync(self._path.is_junction) + + async def is_mount(self) -> bool: + return await to_thread.run_sync( + os.path.ismount, self._path, abandon_on_cancel=True + ) + + if sys.version_info < (3, 15): + + def is_reserved(self) -> bool: + return self._path.is_reserved() + + async def is_socket(self) -> bool: + return await to_thread.run_sync(self._path.is_socket, abandon_on_cancel=True) + + async def is_symlink(self) -> bool: + return await to_thread.run_sync(self._path.is_symlink, abandon_on_cancel=True) + + async def iterdir(self) -> AsyncIterator[Path]: + gen = ( + self._path.iterdir() + if sys.version_info < (3, 13) + else await to_thread.run_sync(self._path.iterdir, abandon_on_cancel=True) + ) + async for path in _PathIterator(gen): + yield path + + def joinpath(self, *args: str | PathLike[str]) -> Path: + return Path(self._path.joinpath(*args)) + + async def lchmod(self, mode: int) -> None: + await to_thread.run_sync(self._path.lchmod, mode) + + async def lstat(self) -> os.stat_result: + return await to_thread.run_sync(self._path.lstat, abandon_on_cancel=True) + + async def mkdir( + self, mode: int = 0o777, parents: bool = False, exist_ok: bool = False + ) -> None: + await to_thread.run_sync(self._path.mkdir, mode, parents, exist_ok) + + @overload + async def open( + self, + mode: OpenBinaryMode, + buffering: int = ..., + encoding: str | None = ..., + errors: str | None = ..., + newline: str | None = ..., + ) -> AsyncFile[bytes]: ... + + @overload + async def open( + self, + mode: OpenTextMode = ..., + buffering: int = ..., + encoding: str | None = ..., + errors: str | None = ..., + newline: str | None = ..., + ) -> AsyncFile[str]: ... + + async def open( + self, + mode: str = "r", + buffering: int = -1, + encoding: str | None = None, + errors: str | None = None, + newline: str | None = None, + ) -> AsyncFile[Any]: + fp = await to_thread.run_sync( + self._path.open, mode, buffering, encoding, errors, newline + ) + return AsyncFile(fp) + + async def owner(self) -> str: + return await to_thread.run_sync(self._path.owner, abandon_on_cancel=True) + + async def read_bytes(self) -> bytes: + return await to_thread.run_sync(self._path.read_bytes) + + async def read_text( + self, encoding: str | None = None, errors: str | None = None + ) -> str: + return await to_thread.run_sync(self._path.read_text, encoding, errors) + + if sys.version_info >= (3, 12): + + def relative_to( + self, *other: str | PathLike[str], walk_up: bool = False + ) -> Path: + # relative_to() should work with any PathLike but it doesn't + others = [pathlib.Path(other) for other in other] + return Path(self._path.relative_to(*others, walk_up=walk_up)) + + else: + + def relative_to(self, *other: str | PathLike[str]) -> Path: + return Path(self._path.relative_to(*other)) + + async def readlink(self) -> Path: + target = await to_thread.run_sync(os.readlink, self._path) + return Path(target) + + async def rename(self, target: str | pathlib.PurePath | Path) -> Path: + if isinstance(target, Path): + target = target._path + + await to_thread.run_sync(self._path.rename, target) + return Path(target) + + async def replace(self, target: str | pathlib.PurePath | Path) -> Path: + if isinstance(target, Path): + target = target._path + + await to_thread.run_sync(self._path.replace, target) + return Path(target) + + async def resolve(self, strict: bool = False) -> Path: + func = partial(self._path.resolve, strict=strict) + return Path(await to_thread.run_sync(func, abandon_on_cancel=True)) + + if sys.version_info < (3, 12): + # Pre Python 3.12 + def rglob(self, pattern: str) -> AsyncIterator[Path]: + gen = self._path.rglob(pattern) + return _PathIterator(gen) + elif (3, 12) <= sys.version_info < (3, 13): + # Changed in Python 3.12: + # - The case_sensitive parameter was added. + def rglob( + self, pattern: str, *, case_sensitive: bool | None = None + ) -> AsyncIterator[Path]: + gen = self._path.rglob(pattern, case_sensitive=case_sensitive) + return _PathIterator(gen) + elif sys.version_info >= (3, 13): + # Changed in Python 3.13: + # - The recurse_symlinks parameter was added. + # - The pattern parameter accepts a path-like object. + def rglob( # type: ignore[misc] # mypy doesn't allow for differing signatures in a conditional block + self, + pattern: str | PathLike[str], + *, + case_sensitive: bool | None = None, + recurse_symlinks: bool = False, + ) -> AsyncIterator[Path]: + gen = self._path.rglob( + pattern, # type: ignore[arg-type] + case_sensitive=case_sensitive, + recurse_symlinks=recurse_symlinks, + ) + return _PathIterator(gen) + + async def rmdir(self) -> None: + await to_thread.run_sync(self._path.rmdir) + + async def samefile(self, other_path: str | PathLike[str]) -> bool: + if isinstance(other_path, Path): + other_path = other_path._path + + return await to_thread.run_sync( + self._path.samefile, other_path, abandon_on_cancel=True + ) + + async def stat(self, *, follow_symlinks: bool = True) -> os.stat_result: + func = partial(os.stat, follow_symlinks=follow_symlinks) + return await to_thread.run_sync(func, self._path, abandon_on_cancel=True) + + async def symlink_to( + self, + target: str | bytes | PathLike[str] | PathLike[bytes], + target_is_directory: bool = False, + ) -> None: + if isinstance(target, Path): + target = target._path + + await to_thread.run_sync(self._path.symlink_to, target, target_is_directory) + + async def touch(self, mode: int = 0o666, exist_ok: bool = True) -> None: + await to_thread.run_sync(self._path.touch, mode, exist_ok) + + async def unlink(self, missing_ok: bool = False) -> None: + try: + await to_thread.run_sync(self._path.unlink) + except FileNotFoundError: + if not missing_ok: + raise + + if sys.version_info >= (3, 12): + + async def walk( + self, + top_down: bool = True, + on_error: Callable[[OSError], object] | None = None, + follow_symlinks: bool = False, + ) -> AsyncIterator[tuple[Path, list[str], list[str]]]: + def get_next_value() -> tuple[pathlib.Path, list[str], list[str]] | None: + try: + return next(gen) + except StopIteration: + return None + + gen = self._path.walk(top_down, on_error, follow_symlinks) + while True: + value = await to_thread.run_sync(get_next_value) + if value is None: + return + + root, dirs, paths = value + yield Path(root), dirs, paths + + def with_name(self, name: str) -> Path: + return Path(self._path.with_name(name)) + + def with_stem(self, stem: str) -> Path: + return Path(self._path.with_name(stem + self._path.suffix)) + + def with_suffix(self, suffix: str) -> Path: + return Path(self._path.with_suffix(suffix)) + + def with_segments(self, *pathsegments: str | PathLike[str]) -> Path: + return Path(*pathsegments) + + async def write_bytes(self, data: bytes) -> int: + return await to_thread.run_sync(self._path.write_bytes, data) + + async def write_text( + self, + data: str, + encoding: str | None = None, + errors: str | None = None, + newline: str | None = None, + ) -> int: + return await to_thread.run_sync( + self._path.write_text, data, encoding, errors, newline + ) + + +PathLike.register(Path) diff --git a/venv/lib/python3.12/site-packages/anyio/_core/_resources.py b/venv/lib/python3.12/site-packages/anyio/_core/_resources.py new file mode 100644 index 0000000..b9a5344 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/_core/_resources.py @@ -0,0 +1,18 @@ +from __future__ import annotations + +from ..abc import AsyncResource +from ._tasks import CancelScope + + +async def aclose_forcefully(resource: AsyncResource) -> None: + """ + Close an asynchronous resource in a cancelled scope. + + Doing this closes the resource without waiting on anything. + + :param resource: the resource to close + + """ + with CancelScope() as scope: + scope.cancel() + await resource.aclose() diff --git a/venv/lib/python3.12/site-packages/anyio/_core/_signals.py b/venv/lib/python3.12/site-packages/anyio/_core/_signals.py new file mode 100644 index 0000000..e24c79e --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/_core/_signals.py @@ -0,0 +1,29 @@ +from __future__ import annotations + +from collections.abc import AsyncIterator +from contextlib import AbstractContextManager +from signal import Signals + +from ._eventloop import get_async_backend + + +def open_signal_receiver( + *signals: Signals, +) -> AbstractContextManager[AsyncIterator[Signals]]: + """ + Start receiving operating system signals. + + :param signals: signals to receive (e.g. ``signal.SIGINT``) + :return: an asynchronous context manager for an asynchronous iterator which yields + signal numbers + :raises NoEventLoopError: if no supported asynchronous event loop is running in the + current thread + + .. warning:: Windows does not support signals natively so it is best to avoid + relying on this in cross-platform applications. + + .. warning:: On asyncio, this permanently replaces any previous signal handler for + the given signals, as set via :meth:`~asyncio.loop.add_signal_handler`. + + """ + return get_async_backend().open_signal_receiver(*signals) diff --git a/venv/lib/python3.12/site-packages/anyio/_core/_sockets.py b/venv/lib/python3.12/site-packages/anyio/_core/_sockets.py new file mode 100644 index 0000000..6c99b3a --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/_core/_sockets.py @@ -0,0 +1,1003 @@ +from __future__ import annotations + +import errno +import os +import socket +import ssl +import stat +import sys +from collections.abc import Awaitable +from dataclasses import dataclass +from ipaddress import IPv4Address, IPv6Address, ip_address +from os import PathLike, chmod +from socket import AddressFamily, SocketKind +from typing import TYPE_CHECKING, Any, Literal, cast, overload + +from .. import ConnectionFailed, to_thread +from ..abc import ( + ByteStreamConnectable, + ConnectedUDPSocket, + ConnectedUNIXDatagramSocket, + IPAddressType, + IPSockAddrType, + SocketListener, + SocketStream, + UDPSocket, + UNIXDatagramSocket, + UNIXSocketStream, +) +from ..streams.stapled import MultiListener +from ..streams.tls import TLSConnectable, TLSStream +from ._eventloop import get_async_backend +from ._resources import aclose_forcefully +from ._synchronization import Event +from ._tasks import create_task_group, move_on_after + +if TYPE_CHECKING: + from _typeshed import FileDescriptorLike +else: + FileDescriptorLike = object + +if sys.version_info < (3, 11): + from exceptiongroup import ExceptionGroup + +if sys.version_info >= (3, 12): + from typing import override +else: + from typing_extensions import override + +if sys.version_info < (3, 13): + from typing_extensions import deprecated +else: + from warnings import deprecated + +IPPROTO_IPV6 = getattr(socket, "IPPROTO_IPV6", 41) # https://bugs.python.org/issue29515 + +AnyIPAddressFamily = Literal[ + AddressFamily.AF_UNSPEC, AddressFamily.AF_INET, AddressFamily.AF_INET6 +] +IPAddressFamily = Literal[AddressFamily.AF_INET, AddressFamily.AF_INET6] + + +# tls_hostname given +@overload +async def connect_tcp( + remote_host: IPAddressType, + remote_port: int, + *, + local_host: IPAddressType | None = ..., + ssl_context: ssl.SSLContext | None = ..., + tls_standard_compatible: bool = ..., + tls_hostname: str, + happy_eyeballs_delay: float = ..., +) -> TLSStream: ... + + +# ssl_context given +@overload +async def connect_tcp( + remote_host: IPAddressType, + remote_port: int, + *, + local_host: IPAddressType | None = ..., + ssl_context: ssl.SSLContext, + tls_standard_compatible: bool = ..., + tls_hostname: str | None = ..., + happy_eyeballs_delay: float = ..., +) -> TLSStream: ... + + +# tls=True +@overload +async def connect_tcp( + remote_host: IPAddressType, + remote_port: int, + *, + local_host: IPAddressType | None = ..., + tls: Literal[True], + ssl_context: ssl.SSLContext | None = ..., + tls_standard_compatible: bool = ..., + tls_hostname: str | None = ..., + happy_eyeballs_delay: float = ..., +) -> TLSStream: ... + + +# tls=False +@overload +async def connect_tcp( + remote_host: IPAddressType, + remote_port: int, + *, + local_host: IPAddressType | None = ..., + tls: Literal[False], + ssl_context: ssl.SSLContext | None = ..., + tls_standard_compatible: bool = ..., + tls_hostname: str | None = ..., + happy_eyeballs_delay: float = ..., +) -> SocketStream: ... + + +# No TLS arguments +@overload +async def connect_tcp( + remote_host: IPAddressType, + remote_port: int, + *, + local_host: IPAddressType | None = ..., + happy_eyeballs_delay: float = ..., +) -> SocketStream: ... + + +async def connect_tcp( + remote_host: IPAddressType, + remote_port: int, + *, + local_host: IPAddressType | None = None, + tls: bool = False, + ssl_context: ssl.SSLContext | None = None, + tls_standard_compatible: bool = True, + tls_hostname: str | None = None, + happy_eyeballs_delay: float = 0.25, +) -> SocketStream | TLSStream: + """ + Connect to a host using the TCP protocol. + + This function implements the stateless version of the Happy Eyeballs algorithm (RFC + 6555). If ``remote_host`` is a host name that resolves to multiple IP addresses, + each one is tried until one connection attempt succeeds. If the first attempt does + not connected within 250 milliseconds, a second attempt is started using the next + address in the list, and so on. On IPv6 enabled systems, an IPv6 address (if + available) is tried first. + + When the connection has been established, a TLS handshake will be done if either + ``ssl_context`` or ``tls_hostname`` is not ``None``, or if ``tls`` is ``True``. + + :param remote_host: the IP address or host name to connect to + :param remote_port: port on the target host to connect to + :param local_host: the interface address or name to bind the socket to before + connecting + :param tls: ``True`` to do a TLS handshake with the connected stream and return a + :class:`~anyio.streams.tls.TLSStream` instead + :param ssl_context: the SSL context object to use (if omitted, a default context is + created) + :param tls_standard_compatible: If ``True``, performs the TLS shutdown handshake + before closing the stream and requires that the server does this as well. + Otherwise, :exc:`~ssl.SSLEOFError` may be raised during reads from the stream. + Some protocols, such as HTTP, require this option to be ``False``. + See :meth:`~ssl.SSLContext.wrap_socket` for details. + :param tls_hostname: host name to check the server certificate against (defaults to + the value of ``remote_host``) + :param happy_eyeballs_delay: delay (in seconds) before starting the next connection + attempt + :return: a socket stream object if no TLS handshake was done, otherwise a TLS stream + :raises ConnectionFailed: if the connection fails + + """ + # Placed here due to https://github.com/python/mypy/issues/7057 + connected_stream: SocketStream | None = None + + async def try_connect(remote_host: str, event: Event) -> None: + nonlocal connected_stream + try: + stream = await asynclib.connect_tcp(remote_host, remote_port, local_address) + except OSError as exc: + oserrors.append(exc) + return + else: + if connected_stream is None: + connected_stream = stream + tg.cancel_scope.cancel() + else: + await stream.aclose() + finally: + event.set() + + asynclib = get_async_backend() + local_address: IPSockAddrType | None = None + family = socket.AF_UNSPEC + if local_host: + gai_res = await getaddrinfo(str(local_host), None) + family, *_, local_address = gai_res[0] + + target_host = str(remote_host) + try: + addr_obj = ip_address(remote_host) + except ValueError: + addr_obj = None + + if addr_obj is not None: + if isinstance(addr_obj, IPv6Address): + target_addrs = [(socket.AF_INET6, addr_obj.compressed)] + else: + target_addrs = [(socket.AF_INET, addr_obj.compressed)] + else: + # getaddrinfo() will raise an exception if name resolution fails + gai_res = await getaddrinfo( + target_host, remote_port, family=family, type=socket.SOCK_STREAM + ) + + # Organize the list so that the first address is an IPv6 address (if available) + # and the second one is an IPv4 addresses. The rest can be in whatever order. + v6_found = v4_found = False + target_addrs = [] + for af, *_, sa in gai_res: + if af == socket.AF_INET6 and not v6_found: + v6_found = True + target_addrs.insert(0, (af, sa[0])) + elif af == socket.AF_INET and not v4_found and v6_found: + v4_found = True + target_addrs.insert(1, (af, sa[0])) + else: + target_addrs.append((af, sa[0])) + + oserrors: list[OSError] = [] + try: + async with create_task_group() as tg: + for _af, addr in target_addrs: + event = Event() + tg.start_soon(try_connect, addr, event) + with move_on_after(happy_eyeballs_delay): + await event.wait() + + if connected_stream is None: + cause = ( + oserrors[0] + if len(oserrors) == 1 + else ExceptionGroup("multiple connection attempts failed", oserrors) + ) + raise OSError("All connection attempts failed") from cause + finally: + oserrors.clear() + + if tls or tls_hostname or ssl_context: + try: + return await TLSStream.wrap( + connected_stream, + server_side=False, + hostname=tls_hostname or str(remote_host), + ssl_context=ssl_context, + standard_compatible=tls_standard_compatible, + ) + except BaseException: + await aclose_forcefully(connected_stream) + raise + + return connected_stream + + +async def connect_unix(path: str | bytes | PathLike[Any]) -> UNIXSocketStream: + """ + Connect to the given UNIX socket. + + Not available on Windows. + + :param path: path to the socket + :return: a socket stream object + :raises ConnectionFailed: if the connection fails + + """ + path = os.fspath(path) + return await get_async_backend().connect_unix(path) + + +async def create_tcp_listener( + *, + local_host: IPAddressType | None = None, + local_port: int = 0, + family: AnyIPAddressFamily = socket.AddressFamily.AF_UNSPEC, + backlog: int = 65536, + reuse_port: bool = False, +) -> MultiListener[SocketStream]: + """ + Create a TCP socket listener. + + :param local_port: port number to listen on + :param local_host: IP address of the interface to listen on. If omitted, listen on + all IPv4 and IPv6 interfaces. To listen on all interfaces on a specific address + family, use ``0.0.0.0`` for IPv4 or ``::`` for IPv6. + :param family: address family (used if ``local_host`` was omitted) + :param backlog: maximum number of queued incoming connections (up to a maximum of + 2**16, or 65536) + :param reuse_port: ``True`` to allow multiple sockets to bind to the same + address/port (not supported on Windows) + :return: a multi-listener object containing one or more socket listeners + :raises OSError: if there's an error creating a socket, or binding to one or more + interfaces failed + + """ + asynclib = get_async_backend() + backlog = min(backlog, 65536) + local_host = str(local_host) if local_host is not None else None + + def setup_raw_socket( + fam: AddressFamily, + bind_addr: tuple[str, int] | tuple[str, int, int, int], + *, + v6only: bool = True, + ) -> socket.socket: + sock = socket.socket(fam) + try: + sock.setblocking(False) + + if fam == AddressFamily.AF_INET6: + sock.setsockopt(IPPROTO_IPV6, socket.IPV6_V6ONLY, v6only) + + # For Windows, enable exclusive address use. For others, enable address + # reuse. + if sys.platform == "win32": + sock.setsockopt(socket.SOL_SOCKET, socket.SO_EXCLUSIVEADDRUSE, 1) + else: + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + + if reuse_port: + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) + + # Workaround for #554 + if fam == socket.AF_INET6 and "%" in bind_addr[0]: + addr, scope_id = bind_addr[0].split("%", 1) + bind_addr = (addr, bind_addr[1], 0, int(scope_id)) + + sock.bind(bind_addr) + sock.listen(backlog) + except BaseException: + sock.close() + raise + + return sock + + # We passing type=0 on non-Windows platforms as a workaround for a uvloop bug + # where we don't get the correct scope ID for IPv6 link-local addresses when passing + # type=socket.SOCK_STREAM to getaddrinfo(): + # https://github.com/MagicStack/uvloop/issues/539 + gai_res = await getaddrinfo( + local_host, + local_port, + family=family, + type=socket.SOCK_STREAM if sys.platform == "win32" else 0, + flags=socket.AI_PASSIVE | socket.AI_ADDRCONFIG, + ) + + # The set comprehension is here to work around a glibc bug: + # https://sourceware.org/bugzilla/show_bug.cgi?id=14969 + sockaddrs = sorted({res for res in gai_res if res[1] == SocketKind.SOCK_STREAM}) + + # Special case for dual-stack binding on the "any" interface + if ( + local_host is None + and family == AddressFamily.AF_UNSPEC + and socket.has_dualstack_ipv6() + and any(fam == AddressFamily.AF_INET6 for fam, *_ in gai_res) + ): + raw_socket = setup_raw_socket( + AddressFamily.AF_INET6, ("::", local_port), v6only=False + ) + listener = asynclib.create_tcp_listener(raw_socket) + return MultiListener([listener]) + + errors: list[OSError] = [] + try: + for _ in range(len(sockaddrs)): + listeners: list[SocketListener] = [] + bound_ephemeral_port = local_port + try: + for fam, *_, sockaddr in sockaddrs: + sockaddr = sockaddr[0], bound_ephemeral_port, *sockaddr[2:] + raw_socket = setup_raw_socket(fam, sockaddr) + + # Store the assigned port if an ephemeral port was requested, so + # we'll bind to the same port on all interfaces + if local_port == 0 and len(gai_res) > 1: + bound_ephemeral_port = raw_socket.getsockname()[1] + + listeners.append(asynclib.create_tcp_listener(raw_socket)) + except BaseException as exc: + for listener in listeners: + await listener.aclose() + + # If an ephemeral port was requested but binding the assigned port + # failed for another interface, rotate the address list and try again + if ( + isinstance(exc, OSError) + and exc.errno == errno.EADDRINUSE + and local_port == 0 + and bound_ephemeral_port + ): + errors.append(exc) + sockaddrs.append(sockaddrs.pop(0)) + continue + + raise + + return MultiListener(listeners) + + raise OSError( + f"Could not create {len(sockaddrs)} listeners with a consistent port" + ) from ExceptionGroup("Several bind attempts failed", errors) + finally: + del errors # Prevent reference cycles + + +async def create_unix_listener( + path: str | bytes | PathLike[Any], + *, + mode: int | None = None, + backlog: int = 65536, +) -> SocketListener: + """ + Create a UNIX socket listener. + + Not available on Windows. + + :param path: path of the socket + :param mode: permissions to set on the socket + :param backlog: maximum number of queued incoming connections (up to a maximum of + 2**16, or 65536) + :return: a listener object + + .. versionchanged:: 3.0 + If a socket already exists on the file system in the given path, it will be + removed first. + + """ + backlog = min(backlog, 65536) + raw_socket = await setup_unix_local_socket(path, mode, socket.SOCK_STREAM) + try: + raw_socket.listen(backlog) + return get_async_backend().create_unix_listener(raw_socket) + except BaseException: + raw_socket.close() + raise + + +async def create_udp_socket( + family: AnyIPAddressFamily = AddressFamily.AF_UNSPEC, + *, + local_host: IPAddressType | None = None, + local_port: int = 0, + reuse_port: bool = False, +) -> UDPSocket: + """ + Create a UDP socket. + + If ``port`` has been given, the socket will be bound to this port on the local + machine, making this socket suitable for providing UDP based services. + + :param family: address family (``AF_INET`` or ``AF_INET6``) – automatically + determined from ``local_host`` if omitted + :param local_host: IP address or host name of the local interface to bind to + :param local_port: local port to bind to + :param reuse_port: ``True`` to allow multiple sockets to bind to the same + address/port (not supported on Windows) + :return: a UDP socket + + """ + if family is AddressFamily.AF_UNSPEC and not local_host: + raise ValueError('Either "family" or "local_host" must be given') + + if local_host: + gai_res = await getaddrinfo( + str(local_host), + local_port, + family=family, + type=socket.SOCK_DGRAM, + flags=socket.AI_PASSIVE | socket.AI_ADDRCONFIG, + ) + family = cast(AnyIPAddressFamily, gai_res[0][0]) + local_address = gai_res[0][-1] + elif family is AddressFamily.AF_INET6: + local_address = ("::", 0) + else: + local_address = ("0.0.0.0", 0) + + sock = await get_async_backend().create_udp_socket( + family, local_address, None, reuse_port + ) + return cast(UDPSocket, sock) + + +async def create_connected_udp_socket( + remote_host: IPAddressType, + remote_port: int, + *, + family: AnyIPAddressFamily = AddressFamily.AF_UNSPEC, + local_host: IPAddressType | None = None, + local_port: int = 0, + reuse_port: bool = False, +) -> ConnectedUDPSocket: + """ + Create a connected UDP socket. + + Connected UDP sockets can only communicate with the specified remote host/port, an + any packets sent from other sources are dropped. + + :param remote_host: remote host to set as the default target + :param remote_port: port on the remote host to set as the default target + :param family: address family (``AF_INET`` or ``AF_INET6``) – automatically + determined from ``local_host`` or ``remote_host`` if omitted + :param local_host: IP address or host name of the local interface to bind to + :param local_port: local port to bind to + :param reuse_port: ``True`` to allow multiple sockets to bind to the same + address/port (not supported on Windows) + :return: a connected UDP socket + + """ + local_address = None + if local_host: + gai_res = await getaddrinfo( + str(local_host), + local_port, + family=family, + type=socket.SOCK_DGRAM, + flags=socket.AI_PASSIVE | socket.AI_ADDRCONFIG, + ) + family = cast(AnyIPAddressFamily, gai_res[0][0]) + local_address = gai_res[0][-1] + + gai_res = await getaddrinfo( + str(remote_host), remote_port, family=family, type=socket.SOCK_DGRAM + ) + family = cast(AnyIPAddressFamily, gai_res[0][0]) + remote_address = gai_res[0][-1] + + sock = await get_async_backend().create_udp_socket( + family, local_address, remote_address, reuse_port + ) + return cast(ConnectedUDPSocket, sock) + + +async def create_unix_datagram_socket( + *, + local_path: None | str | bytes | PathLike[Any] = None, + local_mode: int | None = None, +) -> UNIXDatagramSocket: + """ + Create a UNIX datagram socket. + + Not available on Windows. + + If ``local_path`` has been given, the socket will be bound to this path, making this + socket suitable for receiving datagrams from other processes. Other processes can + send datagrams to this socket only if ``local_path`` is set. + + If a socket already exists on the file system in the ``local_path``, it will be + removed first. + + :param local_path: the path on which to bind to + :param local_mode: permissions to set on the local socket + :return: a UNIX datagram socket + + """ + raw_socket = await setup_unix_local_socket( + local_path, local_mode, socket.SOCK_DGRAM + ) + return await get_async_backend().create_unix_datagram_socket(raw_socket, None) + + +async def create_connected_unix_datagram_socket( + remote_path: str | bytes | PathLike[Any], + *, + local_path: None | str | bytes | PathLike[Any] = None, + local_mode: int | None = None, +) -> ConnectedUNIXDatagramSocket: + """ + Create a connected UNIX datagram socket. + + Connected datagram sockets can only communicate with the specified remote path. + + If ``local_path`` has been given, the socket will be bound to this path, making + this socket suitable for receiving datagrams from other processes. Other processes + can send datagrams to this socket only if ``local_path`` is set. + + If a socket already exists on the file system in the ``local_path``, it will be + removed first. + + :param remote_path: the path to set as the default target + :param local_path: the path on which to bind to + :param local_mode: permissions to set on the local socket + :return: a connected UNIX datagram socket + + """ + remote_path = os.fspath(remote_path) + raw_socket = await setup_unix_local_socket( + local_path, local_mode, socket.SOCK_DGRAM + ) + return await get_async_backend().create_unix_datagram_socket( + raw_socket, remote_path + ) + + +async def getaddrinfo( + host: bytes | str | None, + port: str | int | None, + *, + family: int | AddressFamily = 0, + type: int | SocketKind = 0, + proto: int = 0, + flags: int = 0, +) -> list[tuple[AddressFamily, SocketKind, int, str, tuple[str, int]]]: + """ + Look up a numeric IP address given a host name. + + Internationalized domain names are translated according to the (non-transitional) + IDNA 2008 standard. + + .. note:: 4-tuple IPv6 socket addresses are automatically converted to 2-tuples of + (host, port), unlike what :func:`socket.getaddrinfo` does. + + :param host: host name + :param port: port number + :param family: socket family (`'AF_INET``, ...) + :param type: socket type (``SOCK_STREAM``, ...) + :param proto: protocol number + :param flags: flags to pass to upstream ``getaddrinfo()`` + :return: list of tuples containing (family, type, proto, canonname, sockaddr) + + .. seealso:: :func:`socket.getaddrinfo` + + """ + # Handle unicode hostnames + if isinstance(host, str): + try: + encoded_host: bytes | None = host.encode("ascii") + except UnicodeEncodeError: + import idna + + encoded_host = idna.encode(host, uts46=True) + else: + encoded_host = host + + gai_res = await get_async_backend().getaddrinfo( + encoded_host, port, family=family, type=type, proto=proto, flags=flags + ) + return [ + (family, type, proto, canonname, convert_ipv6_sockaddr(sockaddr)) + for family, type, proto, canonname, sockaddr in gai_res + # filter out IPv6 results when IPv6 is disabled + if not isinstance(sockaddr[0], int) + ] + + +def getnameinfo(sockaddr: IPSockAddrType, flags: int = 0) -> Awaitable[tuple[str, str]]: + """ + Look up the host name of an IP address. + + :param sockaddr: socket address (e.g. (ipaddress, port) for IPv4) + :param flags: flags to pass to upstream ``getnameinfo()`` + :return: a tuple of (host name, service name) + :raises NoEventLoopError: if no supported asynchronous event loop is running in the + current thread + + .. seealso:: :func:`socket.getnameinfo` + + """ + return get_async_backend().getnameinfo(sockaddr, flags) + + +@deprecated("This function is deprecated; use `wait_readable` instead") +def wait_socket_readable(sock: socket.socket) -> Awaitable[None]: + """ + .. deprecated:: 4.7.0 + Use :func:`wait_readable` instead. + + Wait until the given socket has data to be read. + + .. warning:: Only use this on raw sockets that have not been wrapped by any higher + level constructs like socket streams! + + :param sock: a socket object + :raises ~anyio.ClosedResourceError: if the socket was closed while waiting for the + socket to become readable + :raises ~anyio.BusyResourceError: if another task is already waiting for the socket + to become readable + :raises NoEventLoopError: if no supported asynchronous event loop is running in the + current thread + + """ + return get_async_backend().wait_readable(sock.fileno()) + + +@deprecated("This function is deprecated; use `wait_writable` instead") +def wait_socket_writable(sock: socket.socket) -> Awaitable[None]: + """ + .. deprecated:: 4.7.0 + Use :func:`wait_writable` instead. + + Wait until the given socket can be written to. + + This does **NOT** work on Windows when using the asyncio backend with a proactor + event loop (default on py3.8+). + + .. warning:: Only use this on raw sockets that have not been wrapped by any higher + level constructs like socket streams! + + :param sock: a socket object + :raises ~anyio.ClosedResourceError: if the socket was closed while waiting for the + socket to become writable + :raises ~anyio.BusyResourceError: if another task is already waiting for the socket + to become writable + :raises NoEventLoopError: if no supported asynchronous event loop is running in the + current thread + + """ + return get_async_backend().wait_writable(sock.fileno()) + + +def wait_readable(obj: FileDescriptorLike) -> Awaitable[None]: + """ + Wait until the given object has data to be read. + + On Unix systems, ``obj`` must either be an integer file descriptor, or else an + object with a ``.fileno()`` method which returns an integer file descriptor. Any + kind of file descriptor can be passed, though the exact semantics will depend on + your kernel. For example, this probably won't do anything useful for on-disk files. + + On Windows systems, ``obj`` must either be an integer ``SOCKET`` handle, or else an + object with a ``.fileno()`` method which returns an integer ``SOCKET`` handle. File + descriptors aren't supported, and neither are handles that refer to anything besides + a ``SOCKET``. + + On backends where this functionality is not natively provided (asyncio + ``ProactorEventLoop`` on Windows), it is provided using a separate selector thread + which is set to shut down when the interpreter shuts down. + + .. warning:: Don't use this on raw sockets that have been wrapped by any higher + level constructs like socket streams! + + :param obj: an object with a ``.fileno()`` method or an integer handle + :raises ~anyio.ClosedResourceError: if the object was closed while waiting for the + object to become readable + :raises ~anyio.BusyResourceError: if another task is already waiting for the object + to become readable + :raises NoEventLoopError: if no supported asynchronous event loop is running in the + current thread + + """ + return get_async_backend().wait_readable(obj) + + +def wait_writable(obj: FileDescriptorLike) -> Awaitable[None]: + """ + Wait until the given object can be written to. + + :param obj: an object with a ``.fileno()`` method or an integer handle + :raises ~anyio.ClosedResourceError: if the object was closed while waiting for the + object to become writable + :raises ~anyio.BusyResourceError: if another task is already waiting for the object + to become writable + :raises NoEventLoopError: if no supported asynchronous event loop is running in the + current thread + + .. seealso:: See the documentation of :func:`wait_readable` for the definition of + ``obj`` and notes on backend compatibility. + + .. warning:: Don't use this on raw sockets that have been wrapped by any higher + level constructs like socket streams! + + """ + return get_async_backend().wait_writable(obj) + + +def notify_closing(obj: FileDescriptorLike) -> None: + """ + Call this before closing a file descriptor (on Unix) or socket (on + Windows). This will cause any `wait_readable` or `wait_writable` + calls on the given object to immediately wake up and raise + `~anyio.ClosedResourceError`. + + This doesn't actually close the object – you still have to do that + yourself afterwards. Also, you want to be careful to make sure no + new tasks start waiting on the object in between when you call this + and when it's actually closed. So to close something properly, you + usually want to do these steps in order: + + 1. Explicitly mark the object as closed, so that any new attempts + to use it will abort before they start. + 2. Call `notify_closing` to wake up any already-existing users. + 3. Actually close the object. + + It's also possible to do them in a different order if that's more + convenient, *but only if* you make sure not to have any checkpoints in + between the steps. This way they all happen in a single atomic + step, so other tasks won't be able to tell what order they happened + in anyway. + + :param obj: an object with a ``.fileno()`` method or an integer handle + :raises NoEventLoopError: if no supported asynchronous event loop is running in the + current thread + + """ + get_async_backend().notify_closing(obj) + + +# +# Private API +# + + +def convert_ipv6_sockaddr( + sockaddr: tuple[str, int, int, int] | tuple[str, int], +) -> tuple[str, int]: + """ + Convert a 4-tuple IPv6 socket address to a 2-tuple (address, port) format. + + If the scope ID is nonzero, it is added to the address, separated with ``%``. + Otherwise the flow id and scope id are simply cut off from the tuple. + Any other kinds of socket addresses are returned as-is. + + :param sockaddr: the result of :meth:`~socket.socket.getsockname` + :return: the converted socket address + + """ + # This is more complicated than it should be because of MyPy + if isinstance(sockaddr, tuple) and len(sockaddr) == 4: + host, port, flowinfo, scope_id = sockaddr + if scope_id: + # PyPy (as of v7.3.11) leaves the interface name in the result, so + # we discard it and only get the scope ID from the end + # (https://foss.heptapod.net/pypy/pypy/-/issues/3938) + host = host.split("%")[0] + + # Add scope_id to the address + return f"{host}%{scope_id}", port + else: + return host, port + else: + return sockaddr + + +async def setup_unix_local_socket( + path: None | str | bytes | PathLike[Any], + mode: int | None, + socktype: int, +) -> socket.socket: + """ + Create a UNIX local socket object, deleting the socket at the given path if it + exists. + + Not available on Windows. + + :param path: path of the socket + :param mode: permissions to set on the socket + :param socktype: socket.SOCK_STREAM or socket.SOCK_DGRAM + + """ + path_str: str | None + if path is not None: + path_str = os.fsdecode(path) + + # Linux abstract namespace sockets aren't backed by a concrete file so skip stat call + if not path_str.startswith("\0"): + # Copied from pathlib... + try: + stat_result = os.stat(path) + except OSError as e: + if e.errno not in ( + errno.ENOENT, + errno.ENOTDIR, + errno.EBADF, + errno.ELOOP, + ): + raise + else: + if stat.S_ISSOCK(stat_result.st_mode): + os.unlink(path) + else: + path_str = None + + raw_socket = socket.socket(socket.AF_UNIX, socktype) + raw_socket.setblocking(False) + + if path_str is not None: + try: + await to_thread.run_sync(raw_socket.bind, path_str, abandon_on_cancel=True) + if mode is not None: + await to_thread.run_sync(chmod, path_str, mode, abandon_on_cancel=True) + except BaseException: + raw_socket.close() + raise + + return raw_socket + + +@dataclass +class TCPConnectable(ByteStreamConnectable): + """ + Connects to a TCP server at the given host and port. + + :param host: host name or IP address of the server + :param port: TCP port number of the server + """ + + host: str | IPv4Address | IPv6Address + port: int + + def __post_init__(self) -> None: + if self.port < 1 or self.port > 65535: + raise ValueError("TCP port number out of range") + + @override + async def connect(self) -> SocketStream: + try: + return await connect_tcp(self.host, self.port) + except OSError as exc: + raise ConnectionFailed( + f"error connecting to {self.host}:{self.port}: {exc}" + ) from exc + + +@dataclass +class UNIXConnectable(ByteStreamConnectable): + """ + Connects to a UNIX domain socket at the given path. + + :param path: the file system path of the socket + """ + + path: str | bytes | PathLike[str] | PathLike[bytes] + + @override + async def connect(self) -> UNIXSocketStream: + try: + return await connect_unix(self.path) + except OSError as exc: + raise ConnectionFailed(f"error connecting to {self.path!r}: {exc}") from exc + + +def as_connectable( + remote: ByteStreamConnectable + | tuple[str | IPv4Address | IPv6Address, int] + | str + | bytes + | PathLike[str], + /, + *, + tls: bool = False, + ssl_context: ssl.SSLContext | None = None, + tls_hostname: str | None = None, + tls_standard_compatible: bool = True, +) -> ByteStreamConnectable: + """ + Return a byte stream connectable from the given object. + + If a bytestream connectable is given, it is returned unchanged. + If a tuple of (host, port) is given, a TCP connectable is returned. + If a string or bytes path is given, a UNIX connectable is returned. + + If ``tls=True``, the connectable will be wrapped in a + :class:`~.streams.tls.TLSConnectable`. + + :param remote: a connectable, a tuple of (host, port) or a path to a UNIX socket + :param tls: if ``True``, wrap the plaintext connectable in a + :class:`~.streams.tls.TLSConnectable`, using the provided TLS settings) + :param ssl_context: if ``tls=True``, the SSLContext object to use (if not provided, + a secure default will be created) + :param tls_hostname: if ``tls=True``, host name of the server to use for checking + the server certificate (defaults to the host portion of the address for TCP + connectables) + :param tls_standard_compatible: if ``False`` and ``tls=True``, makes the TLS stream + skip the closing handshake when closing the connection, so it won't raise an + exception if the server does the same + + """ + connectable: TCPConnectable | UNIXConnectable | TLSConnectable + if isinstance(remote, ByteStreamConnectable): + return remote + elif isinstance(remote, tuple) and len(remote) == 2: + connectable = TCPConnectable(*remote) + elif isinstance(remote, (str, bytes, PathLike)): + connectable = UNIXConnectable(remote) + else: + raise TypeError(f"cannot convert {remote!r} to a connectable") + + if tls: + if not tls_hostname and isinstance(connectable, TCPConnectable): + tls_hostname = str(connectable.host) + + connectable = TLSConnectable( + connectable, + ssl_context=ssl_context, + hostname=tls_hostname, + standard_compatible=tls_standard_compatible, + ) + + return connectable diff --git a/venv/lib/python3.12/site-packages/anyio/_core/_streams.py b/venv/lib/python3.12/site-packages/anyio/_core/_streams.py new file mode 100644 index 0000000..2b9c7df --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/_core/_streams.py @@ -0,0 +1,52 @@ +from __future__ import annotations + +import math +from typing import TypeVar +from warnings import warn + +from ..streams.memory import ( + MemoryObjectReceiveStream, + MemoryObjectSendStream, + _MemoryObjectStreamState, +) + +T_Item = TypeVar("T_Item") + + +class create_memory_object_stream( + tuple[MemoryObjectSendStream[T_Item], MemoryObjectReceiveStream[T_Item]], +): + """ + Create a memory object stream. + + The stream's item type can be annotated like + :func:`create_memory_object_stream[T_Item]`. + + :param max_buffer_size: number of items held in the buffer until ``send()`` starts + blocking + :param item_type: old way of marking the streams with the right generic type for + static typing (does nothing on AnyIO 4) + + .. deprecated:: 4.0 + Use ``create_memory_object_stream[YourItemType](...)`` instead. + :return: a tuple of (send stream, receive stream) + + """ + + def __new__( # type: ignore[misc] + cls, max_buffer_size: float = 0, item_type: object = None + ) -> tuple[MemoryObjectSendStream[T_Item], MemoryObjectReceiveStream[T_Item]]: + if max_buffer_size != math.inf and not isinstance(max_buffer_size, int): + raise ValueError("max_buffer_size must be either an integer or math.inf") + if max_buffer_size < 0: + raise ValueError("max_buffer_size cannot be negative") + if item_type is not None: + warn( + "The item_type argument has been deprecated in AnyIO 4.0. " + "Use create_memory_object_stream[YourItemType](...) instead.", + DeprecationWarning, + stacklevel=2, + ) + + state = _MemoryObjectStreamState[T_Item](max_buffer_size) + return (MemoryObjectSendStream(state), MemoryObjectReceiveStream(state)) diff --git a/venv/lib/python3.12/site-packages/anyio/_core/_subprocesses.py b/venv/lib/python3.12/site-packages/anyio/_core/_subprocesses.py new file mode 100644 index 0000000..9796f8b --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/_core/_subprocesses.py @@ -0,0 +1,196 @@ +from __future__ import annotations + +from collections.abc import AsyncIterable, Iterable, Mapping, Sequence +from io import BytesIO +from os import PathLike +from subprocess import PIPE, CalledProcessError, CompletedProcess +from typing import IO, Any, TypeAlias, cast + +from ..abc import Process +from ._eventloop import get_async_backend +from ._tasks import create_task_group + +StrOrBytesPath: TypeAlias = str | bytes | PathLike[str] | PathLike[bytes] + + +async def run_process( + command: StrOrBytesPath | Sequence[StrOrBytesPath], + *, + input: bytes | None = None, + stdin: int | IO[Any] | None = None, + stdout: int | IO[Any] | None = PIPE, + stderr: int | IO[Any] | None = PIPE, + check: bool = True, + cwd: StrOrBytesPath | None = None, + env: Mapping[str, str] | None = None, + startupinfo: Any = None, + creationflags: int = 0, + start_new_session: bool = False, + pass_fds: Sequence[int] = (), + user: str | int | None = None, + group: str | int | None = None, + extra_groups: Iterable[str | int] | None = None, + umask: int = -1, +) -> CompletedProcess[bytes]: + """ + Run an external command in a subprocess and wait until it completes. + + .. seealso:: :func:`subprocess.run` + + :param command: either a string to pass to the shell, or an iterable of strings + containing the executable name or path and its arguments + :param input: bytes passed to the standard input of the subprocess + :param stdin: one of :data:`subprocess.PIPE`, :data:`subprocess.DEVNULL`, + a file-like object, or `None`; ``input`` overrides this + :param stdout: one of :data:`subprocess.PIPE`, :data:`subprocess.DEVNULL`, + a file-like object, or `None` + :param stderr: one of :data:`subprocess.PIPE`, :data:`subprocess.DEVNULL`, + :data:`subprocess.STDOUT`, a file-like object, or `None` + :param check: if ``True``, raise :exc:`~subprocess.CalledProcessError` if the + process terminates with a return code other than 0 + :param cwd: If not ``None``, change the working directory to this before running the + command + :param env: if not ``None``, this mapping replaces the inherited environment + variables from the parent process + :param startupinfo: an instance of :class:`subprocess.STARTUPINFO` that can be used + to specify process startup parameters (Windows only) + :param creationflags: flags that can be used to control the creation of the + subprocess (see :class:`subprocess.Popen` for the specifics) + :param start_new_session: if ``true`` the setsid() system call will be made in the + child process prior to the execution of the subprocess. (POSIX only) + :param pass_fds: sequence of file descriptors to keep open between the parent and + child processes. (POSIX only) + :param user: effective user to run the process as (Python >= 3.9, POSIX only) + :param group: effective group to run the process as (Python >= 3.9, POSIX only) + :param extra_groups: supplementary groups to set in the subprocess (Python >= 3.9, + POSIX only) + :param umask: if not negative, this umask is applied in the child process before + running the given command (Python >= 3.9, POSIX only) + :return: an object representing the completed process + :raises ~subprocess.CalledProcessError: if ``check`` is ``True`` and the process + exits with a nonzero return code + + """ + + async def drain_stream(stream: AsyncIterable[bytes], index: int) -> None: + buffer = BytesIO() + async for chunk in stream: + buffer.write(chunk) + + stream_contents[index] = buffer.getvalue() + + if stdin is not None and input is not None: + raise ValueError("only one of stdin and input is allowed") + + async with await open_process( + command, + stdin=PIPE if input else stdin, + stdout=stdout, + stderr=stderr, + cwd=cwd, + env=env, + startupinfo=startupinfo, + creationflags=creationflags, + start_new_session=start_new_session, + pass_fds=pass_fds, + user=user, + group=group, + extra_groups=extra_groups, + umask=umask, + ) as process: + stream_contents: list[bytes | None] = [None, None] + async with create_task_group() as tg: + if process.stdout: + tg.start_soon(drain_stream, process.stdout, 0) + + if process.stderr: + tg.start_soon(drain_stream, process.stderr, 1) + + if process.stdin and input: + await process.stdin.send(input) + await process.stdin.aclose() + + await process.wait() + + output, errors = stream_contents + if check and process.returncode != 0: + raise CalledProcessError(cast(int, process.returncode), command, output, errors) + + return CompletedProcess(command, cast(int, process.returncode), output, errors) + + +async def open_process( + command: StrOrBytesPath | Sequence[StrOrBytesPath], + *, + stdin: int | IO[Any] | None = PIPE, + stdout: int | IO[Any] | None = PIPE, + stderr: int | IO[Any] | None = PIPE, + cwd: StrOrBytesPath | None = None, + env: Mapping[str, str] | None = None, + startupinfo: Any = None, + creationflags: int = 0, + start_new_session: bool = False, + pass_fds: Sequence[int] = (), + user: str | int | None = None, + group: str | int | None = None, + extra_groups: Iterable[str | int] | None = None, + umask: int = -1, +) -> Process: + """ + Start an external command in a subprocess. + + .. seealso:: :class:`subprocess.Popen` + + :param command: either a string to pass to the shell, or an iterable of strings + containing the executable name or path and its arguments + :param stdin: one of :data:`subprocess.PIPE`, :data:`subprocess.DEVNULL`, a + file-like object, or ``None`` + :param stdout: one of :data:`subprocess.PIPE`, :data:`subprocess.DEVNULL`, + a file-like object, or ``None`` + :param stderr: one of :data:`subprocess.PIPE`, :data:`subprocess.DEVNULL`, + :data:`subprocess.STDOUT`, a file-like object, or ``None`` + :param cwd: If not ``None``, the working directory is changed before executing + :param env: If env is not ``None``, it must be a mapping that defines the + environment variables for the new process + :param creationflags: flags that can be used to control the creation of the + subprocess (see :class:`subprocess.Popen` for the specifics) + :param startupinfo: an instance of :class:`subprocess.STARTUPINFO` that can be used + to specify process startup parameters (Windows only) + :param start_new_session: if ``true`` the setsid() system call will be made in the + child process prior to the execution of the subprocess. (POSIX only) + :param pass_fds: sequence of file descriptors to keep open between the parent and + child processes. (POSIX only) + :param user: effective user to run the process as (POSIX only) + :param group: effective group to run the process as (POSIX only) + :param extra_groups: supplementary groups to set in the subprocess (POSIX only) + :param umask: if not negative, this umask is applied in the child process before + running the given command (POSIX only) + :return: an asynchronous process object + + """ + kwargs: dict[str, Any] = {} + if user is not None: + kwargs["user"] = user + + if group is not None: + kwargs["group"] = group + + if extra_groups is not None: + kwargs["extra_groups"] = group + + if umask >= 0: + kwargs["umask"] = umask + + return await get_async_backend().open_process( + command, + stdin=stdin, + stdout=stdout, + stderr=stderr, + cwd=cwd, + env=env, + startupinfo=startupinfo, + creationflags=creationflags, + start_new_session=start_new_session, + pass_fds=pass_fds, + **kwargs, + ) diff --git a/venv/lib/python3.12/site-packages/anyio/_core/_synchronization.py b/venv/lib/python3.12/site-packages/anyio/_core/_synchronization.py new file mode 100644 index 0000000..9c6f9a0 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/_core/_synchronization.py @@ -0,0 +1,757 @@ +from __future__ import annotations + +import math +from collections import deque +from collections.abc import Callable +from dataclasses import dataclass +from types import TracebackType +from typing import TypeVar + +from ..lowlevel import checkpoint_if_cancelled +from ._eventloop import get_async_backend +from ._exceptions import BusyResourceError, NoEventLoopError +from ._tasks import CancelScope +from ._testing import TaskInfo, get_current_task + +T = TypeVar("T") + + +@dataclass(frozen=True) +class EventStatistics: + """ + :ivar int tasks_waiting: number of tasks waiting on :meth:`~.Event.wait` + """ + + tasks_waiting: int + + +@dataclass(frozen=True) +class CapacityLimiterStatistics: + """ + :ivar int borrowed_tokens: number of tokens currently borrowed by tasks + :ivar float total_tokens: total number of available tokens + :ivar tuple borrowers: tasks or other objects currently holding tokens borrowed from + this limiter + :ivar int tasks_waiting: number of tasks waiting on + :meth:`~.CapacityLimiter.acquire` or + :meth:`~.CapacityLimiter.acquire_on_behalf_of` + """ + + borrowed_tokens: int + total_tokens: float + borrowers: tuple[object, ...] + tasks_waiting: int + + +@dataclass(frozen=True) +class LockStatistics: + """ + :ivar bool locked: flag indicating if this lock is locked or not + :ivar ~anyio.TaskInfo owner: task currently holding the lock (or ``None`` if the + lock is not held by any task) + :ivar int tasks_waiting: number of tasks waiting on :meth:`~.Lock.acquire` + """ + + locked: bool + owner: TaskInfo | None + tasks_waiting: int + + +@dataclass(frozen=True) +class ConditionStatistics: + """ + :ivar int tasks_waiting: number of tasks blocked on :meth:`~.Condition.wait` + :ivar ~anyio.LockStatistics lock_statistics: statistics of the underlying + :class:`~.Lock` + """ + + tasks_waiting: int + lock_statistics: LockStatistics + + +@dataclass(frozen=True) +class SemaphoreStatistics: + """ + :ivar int tasks_waiting: number of tasks waiting on :meth:`~.Semaphore.acquire` + + """ + + tasks_waiting: int + + +class Event: + def __new__(cls) -> Event: + try: + return get_async_backend().create_event() + except NoEventLoopError: + return EventAdapter() + + def set(self) -> None: + """Set the flag, notifying all listeners.""" + raise NotImplementedError + + def is_set(self) -> bool: + """Return ``True`` if the flag is set, ``False`` if not.""" + raise NotImplementedError + + async def wait(self) -> None: + """ + Wait until the flag has been set. + + If the flag has already been set when this method is called, it returns + immediately. + + """ + raise NotImplementedError + + def statistics(self) -> EventStatistics: + """Return statistics about the current state of this event.""" + raise NotImplementedError + + +class EventAdapter(Event): + _internal_event: Event | None = None + _is_set: bool = False + + def __new__(cls) -> EventAdapter: + return object.__new__(cls) + + @property + def _event(self) -> Event: + if self._internal_event is None: + self._internal_event = get_async_backend().create_event() + if self._is_set: + self._internal_event.set() + + return self._internal_event + + def set(self) -> None: + if self._internal_event is None: + self._is_set = True + else: + self._event.set() + + def is_set(self) -> bool: + if self._internal_event is None: + return self._is_set + + return self._internal_event.is_set() + + async def wait(self) -> None: + await self._event.wait() + + def statistics(self) -> EventStatistics: + if self._internal_event is None: + return EventStatistics(tasks_waiting=0) + + return self._internal_event.statistics() + + +class Lock: + def __new__(cls, *, fast_acquire: bool = False) -> Lock: + try: + return get_async_backend().create_lock(fast_acquire=fast_acquire) + except NoEventLoopError: + return LockAdapter(fast_acquire=fast_acquire) + + async def __aenter__(self) -> None: + await self.acquire() + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: + self.release() + + async def acquire(self) -> None: + """Acquire the lock.""" + raise NotImplementedError + + def acquire_nowait(self) -> None: + """ + Acquire the lock, without blocking. + + :raises ~anyio.WouldBlock: if the operation would block + + """ + raise NotImplementedError + + def release(self) -> None: + """Release the lock.""" + raise NotImplementedError + + def locked(self) -> bool: + """Return True if the lock is currently held.""" + raise NotImplementedError + + def statistics(self) -> LockStatistics: + """ + Return statistics about the current state of this lock. + + .. versionadded:: 3.0 + """ + raise NotImplementedError + + +class LockAdapter(Lock): + _internal_lock: Lock | None = None + + def __new__(cls, *, fast_acquire: bool = False) -> LockAdapter: + return object.__new__(cls) + + def __init__(self, *, fast_acquire: bool = False): + self._fast_acquire = fast_acquire + + @property + def _lock(self) -> Lock: + if self._internal_lock is None: + self._internal_lock = get_async_backend().create_lock( + fast_acquire=self._fast_acquire + ) + + return self._internal_lock + + async def __aenter__(self) -> None: + await self._lock.acquire() + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: + if self._internal_lock is not None: + self._internal_lock.release() + + async def acquire(self) -> None: + """Acquire the lock.""" + await self._lock.acquire() + + def acquire_nowait(self) -> None: + """ + Acquire the lock, without blocking. + + :raises ~anyio.WouldBlock: if the operation would block + + """ + self._lock.acquire_nowait() + + def release(self) -> None: + """Release the lock.""" + self._lock.release() + + def locked(self) -> bool: + """Return True if the lock is currently held.""" + return self._lock.locked() + + def statistics(self) -> LockStatistics: + """ + Return statistics about the current state of this lock. + + .. versionadded:: 3.0 + + """ + if self._internal_lock is None: + return LockStatistics(False, None, 0) + + return self._internal_lock.statistics() + + +class Condition: + _owner_task: TaskInfo | None = None + + def __init__(self, lock: Lock | None = None): + self._lock = lock or Lock() + self._waiters: deque[Event] = deque() + + async def __aenter__(self) -> None: + await self.acquire() + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: + self.release() + + def _check_acquired(self) -> None: + if self._owner_task != get_current_task(): + raise RuntimeError("The current task is not holding the underlying lock") + + async def acquire(self) -> None: + """Acquire the underlying lock.""" + await self._lock.acquire() + self._owner_task = get_current_task() + + def acquire_nowait(self) -> None: + """ + Acquire the underlying lock, without blocking. + + :raises ~anyio.WouldBlock: if the operation would block + + """ + self._lock.acquire_nowait() + self._owner_task = get_current_task() + + def release(self) -> None: + """Release the underlying lock.""" + self._lock.release() + + def locked(self) -> bool: + """Return True if the lock is set.""" + return self._lock.locked() + + def notify(self, n: int = 1) -> None: + """Notify exactly n listeners.""" + self._check_acquired() + for _ in range(n): + try: + event = self._waiters.popleft() + except IndexError: + break + + event.set() + + def notify_all(self) -> None: + """Notify all the listeners.""" + self._check_acquired() + for event in self._waiters: + event.set() + + self._waiters.clear() + + async def wait(self) -> None: + """Wait for a notification.""" + await checkpoint_if_cancelled() + self._check_acquired() + event = Event() + self._waiters.append(event) + self.release() + try: + await event.wait() + except BaseException: + if not event.is_set(): + self._waiters.remove(event) + elif self._waiters: + # This task was notified by could not act on it, so pass + # it on to the next task + self._waiters.popleft().set() + + raise + finally: + with CancelScope(shield=True): + await self.acquire() + + async def wait_for(self, predicate: Callable[[], T]) -> T: + """ + Wait until a predicate becomes true. + + :param predicate: a callable that returns a truthy value when the condition is + met + :return: the result of the predicate + + .. versionadded:: 4.11.0 + + """ + while not (result := predicate()): + await self.wait() + + return result + + def statistics(self) -> ConditionStatistics: + """ + Return statistics about the current state of this condition. + + .. versionadded:: 3.0 + """ + return ConditionStatistics(len(self._waiters), self._lock.statistics()) + + +class Semaphore: + def __new__( + cls, + initial_value: int, + *, + max_value: int | None = None, + fast_acquire: bool = False, + ) -> Semaphore: + try: + return get_async_backend().create_semaphore( + initial_value, max_value=max_value, fast_acquire=fast_acquire + ) + except NoEventLoopError: + return SemaphoreAdapter(initial_value, max_value=max_value) + + def __init__( + self, + initial_value: int, + *, + max_value: int | None = None, + fast_acquire: bool = False, + ): + if not isinstance(initial_value, int): + raise TypeError("initial_value must be an integer") + if initial_value < 0: + raise ValueError("initial_value must be >= 0") + if max_value is not None: + if not isinstance(max_value, int): + raise TypeError("max_value must be an integer or None") + if max_value < initial_value: + raise ValueError( + "max_value must be equal to or higher than initial_value" + ) + + self._fast_acquire = fast_acquire + + async def __aenter__(self) -> Semaphore: + await self.acquire() + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: + self.release() + + async def acquire(self) -> None: + """Decrement the semaphore value, blocking if necessary.""" + raise NotImplementedError + + def acquire_nowait(self) -> None: + """ + Acquire the underlying lock, without blocking. + + :raises ~anyio.WouldBlock: if the operation would block + + """ + raise NotImplementedError + + def release(self) -> None: + """Increment the semaphore value.""" + raise NotImplementedError + + @property + def value(self) -> int: + """The current value of the semaphore.""" + raise NotImplementedError + + @property + def max_value(self) -> int | None: + """The maximum value of the semaphore.""" + raise NotImplementedError + + def statistics(self) -> SemaphoreStatistics: + """ + Return statistics about the current state of this semaphore. + + .. versionadded:: 3.0 + """ + raise NotImplementedError + + +class SemaphoreAdapter(Semaphore): + _internal_semaphore: Semaphore | None = None + + def __new__( + cls, + initial_value: int, + *, + max_value: int | None = None, + fast_acquire: bool = False, + ) -> SemaphoreAdapter: + return object.__new__(cls) + + def __init__( + self, + initial_value: int, + *, + max_value: int | None = None, + fast_acquire: bool = False, + ) -> None: + super().__init__(initial_value, max_value=max_value, fast_acquire=fast_acquire) + self._initial_value = initial_value + self._max_value = max_value + + @property + def _semaphore(self) -> Semaphore: + if self._internal_semaphore is None: + self._internal_semaphore = get_async_backend().create_semaphore( + self._initial_value, max_value=self._max_value + ) + + return self._internal_semaphore + + async def acquire(self) -> None: + await self._semaphore.acquire() + + def acquire_nowait(self) -> None: + self._semaphore.acquire_nowait() + + def release(self) -> None: + self._semaphore.release() + + @property + def value(self) -> int: + if self._internal_semaphore is None: + return self._initial_value + + return self._semaphore.value + + @property + def max_value(self) -> int | None: + return self._max_value + + def statistics(self) -> SemaphoreStatistics: + if self._internal_semaphore is None: + return SemaphoreStatistics(tasks_waiting=0) + + return self._semaphore.statistics() + + +class CapacityLimiter: + def __new__(cls, total_tokens: float) -> CapacityLimiter: + try: + return get_async_backend().create_capacity_limiter(total_tokens) + except NoEventLoopError: + return CapacityLimiterAdapter(total_tokens) + + async def __aenter__(self) -> None: + raise NotImplementedError + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: + raise NotImplementedError + + @property + def total_tokens(self) -> float: + """ + The total number of tokens available for borrowing. + + This is a read-write property. If the total number of tokens is increased, the + proportionate number of tasks waiting on this limiter will be granted their + tokens. + + .. versionchanged:: 3.0 + The property is now writable. + .. versionchanged:: 4.12 + The value can now be set to 0. + + """ + raise NotImplementedError + + @total_tokens.setter + def total_tokens(self, value: float) -> None: + raise NotImplementedError + + @property + def borrowed_tokens(self) -> int: + """The number of tokens that have currently been borrowed.""" + raise NotImplementedError + + @property + def available_tokens(self) -> float: + """The number of tokens currently available to be borrowed""" + raise NotImplementedError + + def acquire_nowait(self) -> None: + """ + Acquire a token for the current task without waiting for one to become + available. + + :raises ~anyio.WouldBlock: if there are no tokens available for borrowing + + """ + raise NotImplementedError + + def acquire_on_behalf_of_nowait(self, borrower: object) -> None: + """ + Acquire a token without waiting for one to become available. + + :param borrower: the entity borrowing a token + :raises ~anyio.WouldBlock: if there are no tokens available for borrowing + + """ + raise NotImplementedError + + async def acquire(self) -> None: + """ + Acquire a token for the current task, waiting if necessary for one to become + available. + + """ + raise NotImplementedError + + async def acquire_on_behalf_of(self, borrower: object) -> None: + """ + Acquire a token, waiting if necessary for one to become available. + + :param borrower: the entity borrowing a token + + """ + raise NotImplementedError + + def release(self) -> None: + """ + Release the token held by the current task. + + :raises RuntimeError: if the current task has not borrowed a token from this + limiter. + + """ + raise NotImplementedError + + def release_on_behalf_of(self, borrower: object) -> None: + """ + Release the token held by the given borrower. + + :raises RuntimeError: if the borrower has not borrowed a token from this + limiter. + + """ + raise NotImplementedError + + def statistics(self) -> CapacityLimiterStatistics: + """ + Return statistics about the current state of this limiter. + + .. versionadded:: 3.0 + + """ + raise NotImplementedError + + +class CapacityLimiterAdapter(CapacityLimiter): + _internal_limiter: CapacityLimiter | None = None + + def __new__(cls, total_tokens: float) -> CapacityLimiterAdapter: + return object.__new__(cls) + + def __init__(self, total_tokens: float) -> None: + self.total_tokens = total_tokens + + @property + def _limiter(self) -> CapacityLimiter: + if self._internal_limiter is None: + self._internal_limiter = get_async_backend().create_capacity_limiter( + self._total_tokens + ) + + return self._internal_limiter + + async def __aenter__(self) -> None: + await self._limiter.__aenter__() + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: + return await self._limiter.__aexit__(exc_type, exc_val, exc_tb) + + @property + def total_tokens(self) -> float: + if self._internal_limiter is None: + return self._total_tokens + + return self._internal_limiter.total_tokens + + @total_tokens.setter + def total_tokens(self, value: float) -> None: + if not isinstance(value, int) and value is not math.inf: + raise TypeError("total_tokens must be an int or math.inf") + elif value < 1: + raise ValueError("total_tokens must be >= 1") + + if self._internal_limiter is None: + self._total_tokens = value + return + + self._limiter.total_tokens = value + + @property + def borrowed_tokens(self) -> int: + if self._internal_limiter is None: + return 0 + + return self._internal_limiter.borrowed_tokens + + @property + def available_tokens(self) -> float: + if self._internal_limiter is None: + return self._total_tokens + + return self._internal_limiter.available_tokens + + def acquire_nowait(self) -> None: + self._limiter.acquire_nowait() + + def acquire_on_behalf_of_nowait(self, borrower: object) -> None: + self._limiter.acquire_on_behalf_of_nowait(borrower) + + async def acquire(self) -> None: + await self._limiter.acquire() + + async def acquire_on_behalf_of(self, borrower: object) -> None: + await self._limiter.acquire_on_behalf_of(borrower) + + def release(self) -> None: + self._limiter.release() + + def release_on_behalf_of(self, borrower: object) -> None: + self._limiter.release_on_behalf_of(borrower) + + def statistics(self) -> CapacityLimiterStatistics: + if self._internal_limiter is None: + return CapacityLimiterStatistics( + borrowed_tokens=0, + total_tokens=self.total_tokens, + borrowers=(), + tasks_waiting=0, + ) + + return self._internal_limiter.statistics() + + +class ResourceGuard: + """ + A context manager for ensuring that a resource is only used by a single task at a + time. + + Entering this context manager while the previous has not exited it yet will trigger + :exc:`BusyResourceError`. + + :param action: the action to guard against (visible in the :exc:`BusyResourceError` + when triggered, e.g. "Another task is already {action} this resource") + + .. versionadded:: 4.1 + """ + + __slots__ = "action", "_guarded" + + def __init__(self, action: str = "using"): + self.action: str = action + self._guarded = False + + def __enter__(self) -> None: + if self._guarded: + raise BusyResourceError(self.action) + + self._guarded = True + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: + self._guarded = False diff --git a/venv/lib/python3.12/site-packages/anyio/_core/_tasks.py b/venv/lib/python3.12/site-packages/anyio/_core/_tasks.py new file mode 100644 index 0000000..0688bfe --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/_core/_tasks.py @@ -0,0 +1,173 @@ +from __future__ import annotations + +import math +from collections.abc import Generator +from contextlib import contextmanager +from types import TracebackType + +from ..abc._tasks import TaskGroup, TaskStatus +from ._eventloop import get_async_backend + + +class _IgnoredTaskStatus(TaskStatus[object]): + def started(self, value: object = None) -> None: + pass + + +TASK_STATUS_IGNORED = _IgnoredTaskStatus() + + +class CancelScope: + """ + Wraps a unit of work that can be made separately cancellable. + + :param deadline: The time (clock value) when this scope is cancelled automatically + :param shield: ``True`` to shield the cancel scope from external cancellation + :raises NoEventLoopError: if no supported asynchronous event loop is running in the + current thread + """ + + def __new__( + cls, *, deadline: float = math.inf, shield: bool = False + ) -> CancelScope: + return get_async_backend().create_cancel_scope(shield=shield, deadline=deadline) + + def cancel(self, reason: str | None = None) -> None: + """ + Cancel this scope immediately. + + :param reason: a message describing the reason for the cancellation + + """ + raise NotImplementedError + + @property + def deadline(self) -> float: + """ + The time (clock value) when this scope is cancelled automatically. + + Will be ``float('inf')`` if no timeout has been set. + + """ + raise NotImplementedError + + @deadline.setter + def deadline(self, value: float) -> None: + raise NotImplementedError + + @property + def cancel_called(self) -> bool: + """``True`` if :meth:`cancel` has been called.""" + raise NotImplementedError + + @property + def cancelled_caught(self) -> bool: + """ + ``True`` if this scope suppressed a cancellation exception it itself raised. + + This is typically used to check if any work was interrupted, or to see if the + scope was cancelled due to its deadline being reached. The value will, however, + only be ``True`` if the cancellation was triggered by the scope itself (and not + an outer scope). + + """ + raise NotImplementedError + + @property + def shield(self) -> bool: + """ + ``True`` if this scope is shielded from external cancellation. + + While a scope is shielded, it will not receive cancellations from outside. + + """ + raise NotImplementedError + + @shield.setter + def shield(self, value: bool) -> None: + raise NotImplementedError + + def __enter__(self) -> CancelScope: + raise NotImplementedError + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> bool: + raise NotImplementedError + + +@contextmanager +def fail_after( + delay: float | None, shield: bool = False +) -> Generator[CancelScope, None, None]: + """ + Create a context manager which raises a :class:`TimeoutError` if does not finish in + time. + + :param delay: maximum allowed time (in seconds) before raising the exception, or + ``None`` to disable the timeout + :param shield: ``True`` to shield the cancel scope from external cancellation + :return: a context manager that yields a cancel scope + :rtype: :class:`~typing.ContextManager`\\[:class:`~anyio.CancelScope`\\] + :raises NoEventLoopError: if no supported asynchronous event loop is running in the + current thread + + """ + current_time = get_async_backend().current_time + deadline = (current_time() + delay) if delay is not None else math.inf + with get_async_backend().create_cancel_scope( + deadline=deadline, shield=shield + ) as cancel_scope: + yield cancel_scope + + if cancel_scope.cancelled_caught and current_time() >= cancel_scope.deadline: + raise TimeoutError + + +def move_on_after(delay: float | None, shield: bool = False) -> CancelScope: + """ + Create a cancel scope with a deadline that expires after the given delay. + + :param delay: maximum allowed time (in seconds) before exiting the context block, or + ``None`` to disable the timeout + :param shield: ``True`` to shield the cancel scope from external cancellation + :return: a cancel scope + :raises NoEventLoopError: if no supported asynchronous event loop is running in the + current thread + + """ + deadline = ( + (get_async_backend().current_time() + delay) if delay is not None else math.inf + ) + return get_async_backend().create_cancel_scope(deadline=deadline, shield=shield) + + +def current_effective_deadline() -> float: + """ + Return the nearest deadline among all the cancel scopes effective for the current + task. + + :return: a clock value from the event loop's internal clock (or ``float('inf')`` if + there is no deadline in effect, or ``float('-inf')`` if the current scope has + been cancelled) + :rtype: float + :raises NoEventLoopError: if no supported asynchronous event loop is running in the + current thread + + """ + return get_async_backend().current_effective_deadline() + + +def create_task_group() -> TaskGroup: + """ + Create a task group. + + :return: a task group + :raises NoEventLoopError: if no supported asynchronous event loop is running in the + current thread + + """ + return get_async_backend().create_task_group() diff --git a/venv/lib/python3.12/site-packages/anyio/_core/_tempfile.py b/venv/lib/python3.12/site-packages/anyio/_core/_tempfile.py new file mode 100644 index 0000000..75a09f7 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/_core/_tempfile.py @@ -0,0 +1,613 @@ +from __future__ import annotations + +import os +import sys +import tempfile +from collections.abc import Iterable +from io import BytesIO, TextIOWrapper +from types import TracebackType +from typing import ( + TYPE_CHECKING, + Any, + AnyStr, + Generic, + overload, +) + +from .. import to_thread +from .._core._fileio import AsyncFile +from ..lowlevel import checkpoint_if_cancelled + +if TYPE_CHECKING: + from _typeshed import OpenBinaryMode, OpenTextMode, ReadableBuffer, WriteableBuffer + + +class TemporaryFile(Generic[AnyStr]): + """ + An asynchronous temporary file that is automatically created and cleaned up. + + This class provides an asynchronous context manager interface to a temporary file. + The file is created using Python's standard `tempfile.TemporaryFile` function in a + background thread, and is wrapped as an asynchronous file using `AsyncFile`. + + :param mode: The mode in which the file is opened. Defaults to "w+b". + :param buffering: The buffering policy (-1 means the default buffering). + :param encoding: The encoding used to decode or encode the file. Only applicable in + text mode. + :param newline: Controls how universal newlines mode works (only applicable in text + mode). + :param suffix: The suffix for the temporary file name. + :param prefix: The prefix for the temporary file name. + :param dir: The directory in which the temporary file is created. + :param errors: The error handling scheme used for encoding/decoding errors. + """ + + _async_file: AsyncFile[AnyStr] + + @overload + def __init__( + self: TemporaryFile[bytes], + mode: OpenBinaryMode = ..., + buffering: int = ..., + encoding: str | None = ..., + newline: str | None = ..., + suffix: str | None = ..., + prefix: str | None = ..., + dir: str | None = ..., + *, + errors: str | None = ..., + ): ... + @overload + def __init__( + self: TemporaryFile[str], + mode: OpenTextMode, + buffering: int = ..., + encoding: str | None = ..., + newline: str | None = ..., + suffix: str | None = ..., + prefix: str | None = ..., + dir: str | None = ..., + *, + errors: str | None = ..., + ): ... + + def __init__( + self, + mode: OpenTextMode | OpenBinaryMode = "w+b", + buffering: int = -1, + encoding: str | None = None, + newline: str | None = None, + suffix: str | None = None, + prefix: str | None = None, + dir: str | None = None, + *, + errors: str | None = None, + ) -> None: + self.mode = mode + self.buffering = buffering + self.encoding = encoding + self.newline = newline + self.suffix: str | None = suffix + self.prefix: str | None = prefix + self.dir: str | None = dir + self.errors = errors + + async def __aenter__(self) -> AsyncFile[AnyStr]: + fp = await to_thread.run_sync( + lambda: tempfile.TemporaryFile( + self.mode, + self.buffering, + self.encoding, + self.newline, + self.suffix, + self.prefix, + self.dir, + errors=self.errors, + ) + ) + self._async_file = AsyncFile(fp) + return self._async_file + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_value: BaseException | None, + traceback: TracebackType | None, + ) -> None: + await self._async_file.aclose() + + +class NamedTemporaryFile(Generic[AnyStr]): + """ + An asynchronous named temporary file that is automatically created and cleaned up. + + This class provides an asynchronous context manager for a temporary file with a + visible name in the file system. It uses Python's standard + :func:`~tempfile.NamedTemporaryFile` function and wraps the file object with + :class:`AsyncFile` for asynchronous operations. + + :param mode: The mode in which the file is opened. Defaults to "w+b". + :param buffering: The buffering policy (-1 means the default buffering). + :param encoding: The encoding used to decode or encode the file. Only applicable in + text mode. + :param newline: Controls how universal newlines mode works (only applicable in text + mode). + :param suffix: The suffix for the temporary file name. + :param prefix: The prefix for the temporary file name. + :param dir: The directory in which the temporary file is created. + :param delete: Whether to delete the file when it is closed. + :param errors: The error handling scheme used for encoding/decoding errors. + :param delete_on_close: (Python 3.12+) Whether to delete the file on close. + """ + + _async_file: AsyncFile[AnyStr] + + @overload + def __init__( + self: NamedTemporaryFile[bytes], + mode: OpenBinaryMode = ..., + buffering: int = ..., + encoding: str | None = ..., + newline: str | None = ..., + suffix: str | None = ..., + prefix: str | None = ..., + dir: str | None = ..., + delete: bool = ..., + *, + errors: str | None = ..., + delete_on_close: bool = ..., + ): ... + @overload + def __init__( + self: NamedTemporaryFile[str], + mode: OpenTextMode, + buffering: int = ..., + encoding: str | None = ..., + newline: str | None = ..., + suffix: str | None = ..., + prefix: str | None = ..., + dir: str | None = ..., + delete: bool = ..., + *, + errors: str | None = ..., + delete_on_close: bool = ..., + ): ... + + def __init__( + self, + mode: OpenBinaryMode | OpenTextMode = "w+b", + buffering: int = -1, + encoding: str | None = None, + newline: str | None = None, + suffix: str | None = None, + prefix: str | None = None, + dir: str | None = None, + delete: bool = True, + *, + errors: str | None = None, + delete_on_close: bool = True, + ) -> None: + self._params: dict[str, Any] = { + "mode": mode, + "buffering": buffering, + "encoding": encoding, + "newline": newline, + "suffix": suffix, + "prefix": prefix, + "dir": dir, + "delete": delete, + "errors": errors, + } + if sys.version_info >= (3, 12): + self._params["delete_on_close"] = delete_on_close + + async def __aenter__(self) -> AsyncFile[AnyStr]: + fp = await to_thread.run_sync( + lambda: tempfile.NamedTemporaryFile(**self._params) + ) + self._async_file = AsyncFile(fp) + return self._async_file + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_value: BaseException | None, + traceback: TracebackType | None, + ) -> None: + await self._async_file.aclose() + + +class SpooledTemporaryFile(AsyncFile[AnyStr]): + """ + An asynchronous spooled temporary file that starts in memory and is spooled to disk. + + This class provides an asynchronous interface to a spooled temporary file, much like + Python's standard :class:`~tempfile.SpooledTemporaryFile`. It supports asynchronous + write operations and provides a method to force a rollover to disk. + + :param max_size: Maximum size in bytes before the file is rolled over to disk. + :param mode: The mode in which the file is opened. Defaults to "w+b". + :param buffering: The buffering policy (-1 means the default buffering). + :param encoding: The encoding used to decode or encode the file (text mode only). + :param newline: Controls how universal newlines mode works (text mode only). + :param suffix: The suffix for the temporary file name. + :param prefix: The prefix for the temporary file name. + :param dir: The directory in which the temporary file is created. + :param errors: The error handling scheme used for encoding/decoding errors. + """ + + _rolled: bool = False + + @overload + def __init__( + self: SpooledTemporaryFile[bytes], + max_size: int = ..., + mode: OpenBinaryMode = ..., + buffering: int = ..., + encoding: str | None = ..., + newline: str | None = ..., + suffix: str | None = ..., + prefix: str | None = ..., + dir: str | None = ..., + *, + errors: str | None = ..., + ): ... + @overload + def __init__( + self: SpooledTemporaryFile[str], + max_size: int = ..., + mode: OpenTextMode = ..., + buffering: int = ..., + encoding: str | None = ..., + newline: str | None = ..., + suffix: str | None = ..., + prefix: str | None = ..., + dir: str | None = ..., + *, + errors: str | None = ..., + ): ... + + def __init__( + self, + max_size: int = 0, + mode: OpenBinaryMode | OpenTextMode = "w+b", + buffering: int = -1, + encoding: str | None = None, + newline: str | None = None, + suffix: str | None = None, + prefix: str | None = None, + dir: str | None = None, + *, + errors: str | None = None, + ) -> None: + self._tempfile_params: dict[str, Any] = { + "mode": mode, + "buffering": buffering, + "encoding": encoding, + "newline": newline, + "suffix": suffix, + "prefix": prefix, + "dir": dir, + "errors": errors, + } + self._max_size = max_size + if "b" in mode: + super().__init__(BytesIO()) # type: ignore[arg-type] + else: + super().__init__( + TextIOWrapper( # type: ignore[arg-type] + BytesIO(), + encoding=encoding, + errors=errors, + newline=newline, + write_through=True, + ) + ) + + async def aclose(self) -> None: + if not self._rolled: + self._fp.close() + return + + await super().aclose() + + async def _check(self) -> None: + if self._rolled or self._fp.tell() <= self._max_size: + return + + await self.rollover() + + async def rollover(self) -> None: + if self._rolled: + return + + self._rolled = True + buffer = self._fp + buffer.seek(0) + self._fp = await to_thread.run_sync( + lambda: tempfile.TemporaryFile(**self._tempfile_params) + ) + await self.write(buffer.read()) + buffer.close() + + @property + def closed(self) -> bool: + return self._fp.closed + + async def read(self, size: int = -1) -> AnyStr: + if not self._rolled: + await checkpoint_if_cancelled() + return self._fp.read(size) + + return await super().read(size) # type: ignore[return-value] + + async def read1(self: SpooledTemporaryFile[bytes], size: int = -1) -> bytes: + if not self._rolled: + await checkpoint_if_cancelled() + return self._fp.read1(size) + + return await super().read1(size) + + async def readline(self) -> AnyStr: + if not self._rolled: + await checkpoint_if_cancelled() + return self._fp.readline() + + return await super().readline() # type: ignore[return-value] + + async def readlines(self) -> list[AnyStr]: + if not self._rolled: + await checkpoint_if_cancelled() + return self._fp.readlines() + + return await super().readlines() # type: ignore[return-value] + + async def readinto(self: SpooledTemporaryFile[bytes], b: WriteableBuffer) -> int: + if not self._rolled: + await checkpoint_if_cancelled() + self._fp.readinto(b) + + return await super().readinto(b) + + async def readinto1(self: SpooledTemporaryFile[bytes], b: WriteableBuffer) -> int: + if not self._rolled: + await checkpoint_if_cancelled() + self._fp.readinto(b) + + return await super().readinto1(b) + + async def seek(self, offset: int, whence: int | None = os.SEEK_SET) -> int: + if not self._rolled: + await checkpoint_if_cancelled() + return self._fp.seek(offset, whence) + + return await super().seek(offset, whence) + + async def tell(self) -> int: + if not self._rolled: + await checkpoint_if_cancelled() + return self._fp.tell() + + return await super().tell() + + async def truncate(self, size: int | None = None) -> int: + if not self._rolled: + await checkpoint_if_cancelled() + return self._fp.truncate(size) + + return await super().truncate(size) + + @overload + async def write(self: SpooledTemporaryFile[bytes], b: ReadableBuffer) -> int: ... + @overload + async def write(self: SpooledTemporaryFile[str], b: str) -> int: ... + + async def write(self, b: ReadableBuffer | str) -> int: + """ + Asynchronously write data to the spooled temporary file. + + If the file has not yet been rolled over, the data is written synchronously, + and a rollover is triggered if the size exceeds the maximum size. + + :param s: The data to write. + :return: The number of bytes written. + :raises RuntimeError: If the underlying file is not initialized. + + """ + if not self._rolled: + await checkpoint_if_cancelled() + result = self._fp.write(b) + await self._check() + return result + + return await super().write(b) # type: ignore[misc] + + @overload + async def writelines( + self: SpooledTemporaryFile[bytes], lines: Iterable[ReadableBuffer] + ) -> None: ... + @overload + async def writelines( + self: SpooledTemporaryFile[str], lines: Iterable[str] + ) -> None: ... + + async def writelines(self, lines: Iterable[str] | Iterable[ReadableBuffer]) -> None: + """ + Asynchronously write a list of lines to the spooled temporary file. + + If the file has not yet been rolled over, the lines are written synchronously, + and a rollover is triggered if the size exceeds the maximum size. + + :param lines: An iterable of lines to write. + :raises RuntimeError: If the underlying file is not initialized. + + """ + if not self._rolled: + await checkpoint_if_cancelled() + result = self._fp.writelines(lines) + await self._check() + return result + + return await super().writelines(lines) # type: ignore[misc] + + +class TemporaryDirectory(Generic[AnyStr]): + """ + An asynchronous temporary directory that is created and cleaned up automatically. + + This class provides an asynchronous context manager for creating a temporary + directory. It wraps Python's standard :class:`~tempfile.TemporaryDirectory` to + perform directory creation and cleanup operations in a background thread. + + :param suffix: Suffix to be added to the temporary directory name. + :param prefix: Prefix to be added to the temporary directory name. + :param dir: The parent directory where the temporary directory is created. + :param ignore_cleanup_errors: Whether to ignore errors during cleanup + :param delete: Whether to delete the directory upon closing (Python 3.12+). + """ + + def __init__( + self, + suffix: AnyStr | None = None, + prefix: AnyStr | None = None, + dir: AnyStr | None = None, + *, + ignore_cleanup_errors: bool = False, + delete: bool = True, + ) -> None: + self.suffix: AnyStr | None = suffix + self.prefix: AnyStr | None = prefix + self.dir: AnyStr | None = dir + self.ignore_cleanup_errors = ignore_cleanup_errors + self.delete = delete + + self._tempdir: tempfile.TemporaryDirectory | None = None + + async def __aenter__(self) -> str: + params: dict[str, Any] = { + "suffix": self.suffix, + "prefix": self.prefix, + "dir": self.dir, + "ignore_cleanup_errors": self.ignore_cleanup_errors, + } + if sys.version_info >= (3, 12): + params["delete"] = self.delete + + self._tempdir = await to_thread.run_sync( + lambda: tempfile.TemporaryDirectory(**params) + ) + return await to_thread.run_sync(self._tempdir.__enter__) + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_value: BaseException | None, + traceback: TracebackType | None, + ) -> None: + if self._tempdir is not None: + await to_thread.run_sync( + self._tempdir.__exit__, exc_type, exc_value, traceback + ) + + async def cleanup(self) -> None: + if self._tempdir is not None: + await to_thread.run_sync(self._tempdir.cleanup) + + +@overload +async def mkstemp( + suffix: str | None = None, + prefix: str | None = None, + dir: str | None = None, + text: bool = False, +) -> tuple[int, str]: ... + + +@overload +async def mkstemp( + suffix: bytes | None = None, + prefix: bytes | None = None, + dir: bytes | None = None, + text: bool = False, +) -> tuple[int, bytes]: ... + + +async def mkstemp( + suffix: AnyStr | None = None, + prefix: AnyStr | None = None, + dir: AnyStr | None = None, + text: bool = False, +) -> tuple[int, str | bytes]: + """ + Asynchronously create a temporary file and return an OS-level handle and the file + name. + + This function wraps `tempfile.mkstemp` and executes it in a background thread. + + :param suffix: Suffix to be added to the file name. + :param prefix: Prefix to be added to the file name. + :param dir: Directory in which the temporary file is created. + :param text: Whether the file is opened in text mode. + :return: A tuple containing the file descriptor and the file name. + + """ + return await to_thread.run_sync(tempfile.mkstemp, suffix, prefix, dir, text) + + +@overload +async def mkdtemp( + suffix: str | None = None, + prefix: str | None = None, + dir: str | None = None, +) -> str: ... + + +@overload +async def mkdtemp( + suffix: bytes | None = None, + prefix: bytes | None = None, + dir: bytes | None = None, +) -> bytes: ... + + +async def mkdtemp( + suffix: AnyStr | None = None, + prefix: AnyStr | None = None, + dir: AnyStr | None = None, +) -> str | bytes: + """ + Asynchronously create a temporary directory and return its path. + + This function wraps `tempfile.mkdtemp` and executes it in a background thread. + + :param suffix: Suffix to be added to the directory name. + :param prefix: Prefix to be added to the directory name. + :param dir: Parent directory where the temporary directory is created. + :return: The path of the created temporary directory. + + """ + return await to_thread.run_sync(tempfile.mkdtemp, suffix, prefix, dir) + + +async def gettempdir() -> str: + """ + Asynchronously return the name of the directory used for temporary files. + + This function wraps `tempfile.gettempdir` and executes it in a background thread. + + :return: The path of the temporary directory as a string. + + """ + return await to_thread.run_sync(tempfile.gettempdir) + + +async def gettempdirb() -> bytes: + """ + Asynchronously return the name of the directory used for temporary files in bytes. + + This function wraps `tempfile.gettempdirb` and executes it in a background thread. + + :return: The path of the temporary directory as bytes. + + """ + return await to_thread.run_sync(tempfile.gettempdirb) diff --git a/venv/lib/python3.12/site-packages/anyio/_core/_testing.py b/venv/lib/python3.12/site-packages/anyio/_core/_testing.py new file mode 100644 index 0000000..369e65c --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/_core/_testing.py @@ -0,0 +1,82 @@ +from __future__ import annotations + +from collections.abc import Awaitable, Generator +from typing import Any, cast + +from ._eventloop import get_async_backend + + +class TaskInfo: + """ + Represents an asynchronous task. + + :ivar int id: the unique identifier of the task + :ivar parent_id: the identifier of the parent task, if any + :vartype parent_id: Optional[int] + :ivar str name: the description of the task (if any) + :ivar ~collections.abc.Coroutine coro: the coroutine object of the task + """ + + __slots__ = "_name", "id", "parent_id", "name", "coro" + + def __init__( + self, + id: int, + parent_id: int | None, + name: str | None, + coro: Generator[Any, Any, Any] | Awaitable[Any], + ): + func = get_current_task + self._name = f"{func.__module__}.{func.__qualname__}" + self.id: int = id + self.parent_id: int | None = parent_id + self.name: str | None = name + self.coro: Generator[Any, Any, Any] | Awaitable[Any] = coro + + def __eq__(self, other: object) -> bool: + if isinstance(other, TaskInfo): + return self.id == other.id + + return NotImplemented + + def __hash__(self) -> int: + return hash(self.id) + + def __repr__(self) -> str: + return f"{self.__class__.__name__}(id={self.id!r}, name={self.name!r})" + + def has_pending_cancellation(self) -> bool: + """ + Return ``True`` if the task has a cancellation pending, ``False`` otherwise. + + """ + return False + + +def get_current_task() -> TaskInfo: + """ + Return the current task. + + :return: a representation of the current task + :raises NoEventLoopError: if no supported asynchronous event loop is running in the + current thread + + """ + return get_async_backend().get_current_task() + + +def get_running_tasks() -> list[TaskInfo]: + """ + Return a list of running tasks in the current event loop. + + :return: a list of task info objects + :raises NoEventLoopError: if no supported asynchronous event loop is running in the + current thread + + """ + return cast("list[TaskInfo]", get_async_backend().get_running_tasks()) + + +async def wait_all_tasks_blocked() -> None: + """Wait until all other tasks are waiting for something.""" + await get_async_backend().wait_all_tasks_blocked() diff --git a/venv/lib/python3.12/site-packages/anyio/_core/_typedattr.py b/venv/lib/python3.12/site-packages/anyio/_core/_typedattr.py new file mode 100644 index 0000000..f358a44 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/_core/_typedattr.py @@ -0,0 +1,81 @@ +from __future__ import annotations + +from collections.abc import Callable, Mapping +from typing import Any, TypeVar, final, overload + +from ._exceptions import TypedAttributeLookupError + +T_Attr = TypeVar("T_Attr") +T_Default = TypeVar("T_Default") +undefined = object() + + +def typed_attribute() -> Any: + """Return a unique object, used to mark typed attributes.""" + return object() + + +class TypedAttributeSet: + """ + Superclass for typed attribute collections. + + Checks that every public attribute of every subclass has a type annotation. + """ + + def __init_subclass__(cls) -> None: + annotations: dict[str, Any] = getattr(cls, "__annotations__", {}) + for attrname in dir(cls): + if not attrname.startswith("_") and attrname not in annotations: + raise TypeError( + f"Attribute {attrname!r} is missing its type annotation" + ) + + super().__init_subclass__() + + +class TypedAttributeProvider: + """Base class for classes that wish to provide typed extra attributes.""" + + @property + def extra_attributes(self) -> Mapping[T_Attr, Callable[[], T_Attr]]: + """ + A mapping of the extra attributes to callables that return the corresponding + values. + + If the provider wraps another provider, the attributes from that wrapper should + also be included in the returned mapping (but the wrapper may override the + callables from the wrapped instance). + + """ + return {} + + @overload + def extra(self, attribute: T_Attr) -> T_Attr: ... + + @overload + def extra(self, attribute: T_Attr, default: T_Default) -> T_Attr | T_Default: ... + + @final + def extra(self, attribute: Any, default: object = undefined) -> object: + """ + extra(attribute, default=undefined) + + Return the value of the given typed extra attribute. + + :param attribute: the attribute (member of a :class:`~TypedAttributeSet`) to + look for + :param default: the value that should be returned if no value is found for the + attribute + :raises ~anyio.TypedAttributeLookupError: if the search failed and no default + value was given + + """ + try: + getter = self.extra_attributes[attribute] + except KeyError: + if default is undefined: + raise TypedAttributeLookupError("Attribute not found") from None + else: + return default + + return getter() diff --git a/venv/lib/python3.12/site-packages/anyio/abc/__init__.py b/venv/lib/python3.12/site-packages/anyio/abc/__init__.py new file mode 100644 index 0000000..d560ce3 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/abc/__init__.py @@ -0,0 +1,58 @@ +from __future__ import annotations + +from ._eventloop import AsyncBackend as AsyncBackend +from ._resources import AsyncResource as AsyncResource +from ._sockets import ConnectedUDPSocket as ConnectedUDPSocket +from ._sockets import ConnectedUNIXDatagramSocket as ConnectedUNIXDatagramSocket +from ._sockets import IPAddressType as IPAddressType +from ._sockets import IPSockAddrType as IPSockAddrType +from ._sockets import SocketAttribute as SocketAttribute +from ._sockets import SocketListener as SocketListener +from ._sockets import SocketStream as SocketStream +from ._sockets import UDPPacketType as UDPPacketType +from ._sockets import UDPSocket as UDPSocket +from ._sockets import UNIXDatagramPacketType as UNIXDatagramPacketType +from ._sockets import UNIXDatagramSocket as UNIXDatagramSocket +from ._sockets import UNIXSocketStream as UNIXSocketStream +from ._streams import AnyByteReceiveStream as AnyByteReceiveStream +from ._streams import AnyByteSendStream as AnyByteSendStream +from ._streams import AnyByteStream as AnyByteStream +from ._streams import AnyByteStreamConnectable as AnyByteStreamConnectable +from ._streams import AnyUnreliableByteReceiveStream as AnyUnreliableByteReceiveStream +from ._streams import AnyUnreliableByteSendStream as AnyUnreliableByteSendStream +from ._streams import AnyUnreliableByteStream as AnyUnreliableByteStream +from ._streams import ByteReceiveStream as ByteReceiveStream +from ._streams import ByteSendStream as ByteSendStream +from ._streams import ByteStream as ByteStream +from ._streams import ByteStreamConnectable as ByteStreamConnectable +from ._streams import Listener as Listener +from ._streams import ObjectReceiveStream as ObjectReceiveStream +from ._streams import ObjectSendStream as ObjectSendStream +from ._streams import ObjectStream as ObjectStream +from ._streams import ObjectStreamConnectable as ObjectStreamConnectable +from ._streams import UnreliableObjectReceiveStream as UnreliableObjectReceiveStream +from ._streams import UnreliableObjectSendStream as UnreliableObjectSendStream +from ._streams import UnreliableObjectStream as UnreliableObjectStream +from ._subprocesses import Process as Process +from ._tasks import TaskGroup as TaskGroup +from ._tasks import TaskStatus as TaskStatus +from ._testing import TestRunner as TestRunner + +# Re-exported here, for backwards compatibility +# isort: off +from .._core._synchronization import ( + CapacityLimiter as CapacityLimiter, + Condition as Condition, + Event as Event, + Lock as Lock, + Semaphore as Semaphore, +) +from .._core._tasks import CancelScope as CancelScope +from ..from_thread import BlockingPortal as BlockingPortal + +# Re-export imports so they look like they live directly in this package +for __value in list(locals().values()): + if getattr(__value, "__module__", "").startswith("anyio.abc."): + __value.__module__ = __name__ + +del __value diff --git a/venv/lib/python3.12/site-packages/anyio/abc/__pycache__/__init__.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/abc/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..968ff1e1247b26ffe0635a9fd73fd15d209f062f GIT binary patch literal 2379 zcmZvd%Wo4`6vpo)@iTtp;k@4uhd2*U62hYdQ4&%h6@rL_s=9488hb9uka<{l#)(X& zs*5gIut8n4%Wf++{Xg1Gg;2{#UR7PNgQBVutDbXgCoy2jpMUo|=RSPznLEEGlW_*0 zZ!#~;bM1`%g^k81Tm$9JcP)(lzzk+67PA$uD9mUvTCEnlmA4YNS#5TRhloQ~*pBcB zaTqwtqr?&57>^N0f#W<*90P9W?Zk251WypR11EWsI02mEDdHq>nx~0Vz#Y7UI1Sv% zJBd4hyLcCIr`2s|c!szOxQF);cLVqGUg8XJAMYdX0q*Dh#J#`+e1NzQc#sbg_X7{{ zA>skxVLnVe2t2|^h=+hj`6%%)@E9K>9swTbh?+89qZiZJn`a`7CkP%Gq;#j(7%mp3f7Xu@>w_z6d;PI*us%!nn7&z2icj5AM*3dwc8i zP2Jb`q;4OFlUv*Ch9QOL?N&-SN@|PxqFHy+wd8f*mu8{tQ&P>kWqQ7FgoJL1nzQ3e zq1(_-!Wy=5t$ux!*y%;}-aECHrnIipk>gc%p!?1YnRTbKQSrrHQ55E(IG(w)?(e`h z9h=F9*;rqHlTqIzy_CM+(bC<3n={y_eB6Ti^TP#=M;$8ZL!q(+F{L8l8Gh zTFonso;rcN6l^;JyG`>rAA%hsK z*f8-~2|}M73daxHZb9`2u^nOSrF~c8nYLfkouaUIif*mSH!MgooxN>W`nnawHO+R7 zvL!SvU=QQEQ!(AVUMS{o=dNP#e%UWe2ugg!!4No)<+>#qsu}PE(R1iYe60jg&7%j< zlM!gjC`t?kUq=$&L`)`7k|-&ZG)f0bCrTFxjzZhz$!_#AC_N~>D19jXC<7>iC_^a2 zC?hDNC}Sw&C=)1?C~$KzIgOG936h#uE|h8qB0M>RURd+tBs_Trvu4qWYCfC>Y?{nr zvsWv^-sUyDmiDFVm=Ec~lJnSM0c8;-kD`JEiF$|HxJziY-^N)IHNHEqX<%mxNT|Ko3>REU2Z5zwbI{^UEu$2lcfG zsR#O=@Kh=a6^cUDG}AGCP0N=mZ=;uMg>yx2!K8Rsd%uCaYE=}a$|nD2t5tTs%C1z| zcD2qI$yuT1LX};o=%p&#sItpsep+RpQT|PGpnJZ`Hmhu|%C1%!WI|sE?N-@s>b^)J z7%Kl?G_17z%TQ8GfsU76hgnDF$@TAV{&45XooAWsv-HeAtVNmm_Qs1y>e11UiJuD3 mBDp^ztG`E9fBEuxWaH0~?4!u@=-{gmWWA2EP(t2-KlDEUB(KN- literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/anyio/abc/__pycache__/_eventloop.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/abc/__pycache__/_eventloop.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f141b7fc4b829641eb128302d6d9a8ea3633b8f0 GIT binary patch literal 16544 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 J34D~Fe*k1Pqvikr literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/anyio/abc/__pycache__/_sockets.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/abc/__pycache__/_sockets.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cde661e5b782743f4ae5f5dc522ae805a3d72e9d GIT binary patch literal 18303 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/anyio/abc/__pycache__/_subprocesses.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/abc/__pycache__/_subprocesses.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a1977cfaa90a171f55814e8fb35c0c9ff6dfdebf GIT binary patch literal 3254 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 ZmuB5t`C;v@`n>X?V*T{dKLi$;)4!tP^AZ36 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/anyio/abc/_eventloop.py b/venv/lib/python3.12/site-packages/anyio/abc/_eventloop.py new file mode 100644 index 0000000..ae06288 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/abc/_eventloop.py @@ -0,0 +1,409 @@ +from __future__ import annotations + +import math +import sys +from abc import ABCMeta, abstractmethod +from collections.abc import AsyncIterator, Awaitable, Callable, Sequence +from contextlib import AbstractContextManager +from os import PathLike +from signal import Signals +from socket import AddressFamily, SocketKind, socket +from typing import ( + IO, + TYPE_CHECKING, + Any, + TypeAlias, + TypeVar, + overload, +) + +if sys.version_info >= (3, 11): + from typing import TypeVarTuple, Unpack +else: + from typing_extensions import TypeVarTuple, Unpack + +if TYPE_CHECKING: + from _typeshed import FileDescriptorLike + + from .._core._synchronization import CapacityLimiter, Event, Lock, Semaphore + from .._core._tasks import CancelScope + from .._core._testing import TaskInfo + from ._sockets import ( + ConnectedUDPSocket, + ConnectedUNIXDatagramSocket, + IPSockAddrType, + SocketListener, + SocketStream, + UDPSocket, + UNIXDatagramSocket, + UNIXSocketStream, + ) + from ._subprocesses import Process + from ._tasks import TaskGroup + from ._testing import TestRunner + +T_Retval = TypeVar("T_Retval") +PosArgsT = TypeVarTuple("PosArgsT") +StrOrBytesPath: TypeAlias = str | bytes | PathLike[str] | PathLike[bytes] + + +class AsyncBackend(metaclass=ABCMeta): + @classmethod + @abstractmethod + def run( + cls, + func: Callable[[Unpack[PosArgsT]], Awaitable[T_Retval]], + args: tuple[Unpack[PosArgsT]], + kwargs: dict[str, Any], + options: dict[str, Any], + ) -> T_Retval: + """ + Run the given coroutine function in an asynchronous event loop. + + The current thread must not be already running an event loop. + + :param func: a coroutine function + :param args: positional arguments to ``func`` + :param kwargs: positional arguments to ``func`` + :param options: keyword arguments to call the backend ``run()`` implementation + with + :return: the return value of the coroutine function + """ + + @classmethod + @abstractmethod + def current_token(cls) -> object: + """ + Return an object that allows other threads to run code inside the event loop. + + :return: a token object, specific to the event loop running in the current + thread + """ + + @classmethod + @abstractmethod + def current_time(cls) -> float: + """ + Return the current value of the event loop's internal clock. + + :return: the clock value (seconds) + """ + + @classmethod + @abstractmethod + def cancelled_exception_class(cls) -> type[BaseException]: + """Return the exception class that is raised in a task if it's cancelled.""" + + @classmethod + @abstractmethod + async def checkpoint(cls) -> None: + """ + Check if the task has been cancelled, and allow rescheduling of other tasks. + + This is effectively the same as running :meth:`checkpoint_if_cancelled` and then + :meth:`cancel_shielded_checkpoint`. + """ + + @classmethod + async def checkpoint_if_cancelled(cls) -> None: + """ + Check if the current task group has been cancelled. + + This will check if the task has been cancelled, but will not allow other tasks + to be scheduled if not. + + """ + if cls.current_effective_deadline() == -math.inf: + await cls.checkpoint() + + @classmethod + async def cancel_shielded_checkpoint(cls) -> None: + """ + Allow the rescheduling of other tasks. + + This will give other tasks the opportunity to run, but without checking if the + current task group has been cancelled, unlike with :meth:`checkpoint`. + + """ + with cls.create_cancel_scope(shield=True): + await cls.sleep(0) + + @classmethod + @abstractmethod + async def sleep(cls, delay: float) -> None: + """ + Pause the current task for the specified duration. + + :param delay: the duration, in seconds + """ + + @classmethod + @abstractmethod + def create_cancel_scope( + cls, *, deadline: float = math.inf, shield: bool = False + ) -> CancelScope: + pass + + @classmethod + @abstractmethod + def current_effective_deadline(cls) -> float: + """ + Return the nearest deadline among all the cancel scopes effective for the + current task. + + :return: + - a clock value from the event loop's internal clock + - ``inf`` if there is no deadline in effect + - ``-inf`` if the current scope has been cancelled + :rtype: float + """ + + @classmethod + @abstractmethod + def create_task_group(cls) -> TaskGroup: + pass + + @classmethod + @abstractmethod + def create_event(cls) -> Event: + pass + + @classmethod + @abstractmethod + def create_lock(cls, *, fast_acquire: bool) -> Lock: + pass + + @classmethod + @abstractmethod + def create_semaphore( + cls, + initial_value: int, + *, + max_value: int | None = None, + fast_acquire: bool = False, + ) -> Semaphore: + pass + + @classmethod + @abstractmethod + def create_capacity_limiter(cls, total_tokens: float) -> CapacityLimiter: + pass + + @classmethod + @abstractmethod + async def run_sync_in_worker_thread( + cls, + func: Callable[[Unpack[PosArgsT]], T_Retval], + args: tuple[Unpack[PosArgsT]], + abandon_on_cancel: bool = False, + limiter: CapacityLimiter | None = None, + ) -> T_Retval: + pass + + @classmethod + @abstractmethod + def check_cancelled(cls) -> None: + pass + + @classmethod + @abstractmethod + def run_async_from_thread( + cls, + func: Callable[[Unpack[PosArgsT]], Awaitable[T_Retval]], + args: tuple[Unpack[PosArgsT]], + token: object, + ) -> T_Retval: + pass + + @classmethod + @abstractmethod + def run_sync_from_thread( + cls, + func: Callable[[Unpack[PosArgsT]], T_Retval], + args: tuple[Unpack[PosArgsT]], + token: object, + ) -> T_Retval: + pass + + @classmethod + @abstractmethod + async def open_process( + cls, + command: StrOrBytesPath | Sequence[StrOrBytesPath], + *, + stdin: int | IO[Any] | None, + stdout: int | IO[Any] | None, + stderr: int | IO[Any] | None, + **kwargs: Any, + ) -> Process: + pass + + @classmethod + @abstractmethod + def setup_process_pool_exit_at_shutdown(cls, workers: set[Process]) -> None: + pass + + @classmethod + @abstractmethod + async def connect_tcp( + cls, host: str, port: int, local_address: IPSockAddrType | None = None + ) -> SocketStream: + pass + + @classmethod + @abstractmethod + async def connect_unix(cls, path: str | bytes) -> UNIXSocketStream: + pass + + @classmethod + @abstractmethod + def create_tcp_listener(cls, sock: socket) -> SocketListener: + pass + + @classmethod + @abstractmethod + def create_unix_listener(cls, sock: socket) -> SocketListener: + pass + + @classmethod + @abstractmethod + async def create_udp_socket( + cls, + family: AddressFamily, + local_address: IPSockAddrType | None, + remote_address: IPSockAddrType | None, + reuse_port: bool, + ) -> UDPSocket | ConnectedUDPSocket: + pass + + @classmethod + @overload + async def create_unix_datagram_socket( + cls, raw_socket: socket, remote_path: None + ) -> UNIXDatagramSocket: ... + + @classmethod + @overload + async def create_unix_datagram_socket( + cls, raw_socket: socket, remote_path: str | bytes + ) -> ConnectedUNIXDatagramSocket: ... + + @classmethod + @abstractmethod + async def create_unix_datagram_socket( + cls, raw_socket: socket, remote_path: str | bytes | None + ) -> UNIXDatagramSocket | ConnectedUNIXDatagramSocket: + pass + + @classmethod + @abstractmethod + async def getaddrinfo( + cls, + host: bytes | str | None, + port: str | int | None, + *, + family: int | AddressFamily = 0, + type: int | SocketKind = 0, + proto: int = 0, + flags: int = 0, + ) -> Sequence[ + tuple[ + AddressFamily, + SocketKind, + int, + str, + tuple[str, int] | tuple[str, int, int, int] | tuple[int, bytes], + ] + ]: + pass + + @classmethod + @abstractmethod + async def getnameinfo( + cls, sockaddr: IPSockAddrType, flags: int = 0 + ) -> tuple[str, str]: + pass + + @classmethod + @abstractmethod + async def wait_readable(cls, obj: FileDescriptorLike) -> None: + pass + + @classmethod + @abstractmethod + async def wait_writable(cls, obj: FileDescriptorLike) -> None: + pass + + @classmethod + @abstractmethod + def notify_closing(cls, obj: FileDescriptorLike) -> None: + pass + + @classmethod + @abstractmethod + async def wrap_listener_socket(cls, sock: socket) -> SocketListener: + pass + + @classmethod + @abstractmethod + async def wrap_stream_socket(cls, sock: socket) -> SocketStream: + pass + + @classmethod + @abstractmethod + async def wrap_unix_stream_socket(cls, sock: socket) -> UNIXSocketStream: + pass + + @classmethod + @abstractmethod + async def wrap_udp_socket(cls, sock: socket) -> UDPSocket: + pass + + @classmethod + @abstractmethod + async def wrap_connected_udp_socket(cls, sock: socket) -> ConnectedUDPSocket: + pass + + @classmethod + @abstractmethod + async def wrap_unix_datagram_socket(cls, sock: socket) -> UNIXDatagramSocket: + pass + + @classmethod + @abstractmethod + async def wrap_connected_unix_datagram_socket( + cls, sock: socket + ) -> ConnectedUNIXDatagramSocket: + pass + + @classmethod + @abstractmethod + def current_default_thread_limiter(cls) -> CapacityLimiter: + pass + + @classmethod + @abstractmethod + def open_signal_receiver( + cls, *signals: Signals + ) -> AbstractContextManager[AsyncIterator[Signals]]: + pass + + @classmethod + @abstractmethod + def get_current_task(cls) -> TaskInfo: + pass + + @classmethod + @abstractmethod + def get_running_tasks(cls) -> Sequence[TaskInfo]: + pass + + @classmethod + @abstractmethod + async def wait_all_tasks_blocked(cls) -> None: + pass + + @classmethod + @abstractmethod + def create_test_runner(cls, options: dict[str, Any]) -> TestRunner: + pass diff --git a/venv/lib/python3.12/site-packages/anyio/abc/_resources.py b/venv/lib/python3.12/site-packages/anyio/abc/_resources.py new file mode 100644 index 0000000..10df115 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/abc/_resources.py @@ -0,0 +1,33 @@ +from __future__ import annotations + +from abc import ABCMeta, abstractmethod +from types import TracebackType +from typing import TypeVar + +T = TypeVar("T") + + +class AsyncResource(metaclass=ABCMeta): + """ + Abstract base class for all closeable asynchronous resources. + + Works as an asynchronous context manager which returns the instance itself on enter, + and calls :meth:`aclose` on exit. + """ + + __slots__ = () + + async def __aenter__(self: T) -> T: + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: + await self.aclose() + + @abstractmethod + async def aclose(self) -> None: + """Close the resource.""" diff --git a/venv/lib/python3.12/site-packages/anyio/abc/_sockets.py b/venv/lib/python3.12/site-packages/anyio/abc/_sockets.py new file mode 100644 index 0000000..feb26bd --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/abc/_sockets.py @@ -0,0 +1,399 @@ +from __future__ import annotations + +import errno +import socket +from abc import abstractmethod +from collections.abc import Callable, Collection, Mapping +from contextlib import AsyncExitStack +from io import IOBase +from ipaddress import IPv4Address, IPv6Address +from socket import AddressFamily +from typing import Any, TypeAlias, TypeVar + +from .._core._eventloop import get_async_backend +from .._core._typedattr import ( + TypedAttributeProvider, + TypedAttributeSet, + typed_attribute, +) +from ._streams import ByteStream, Listener, UnreliableObjectStream +from ._tasks import TaskGroup + +IPAddressType: TypeAlias = str | IPv4Address | IPv6Address +IPSockAddrType: TypeAlias = tuple[str, int] +SockAddrType: TypeAlias = IPSockAddrType | str +UDPPacketType: TypeAlias = tuple[bytes, IPSockAddrType] +UNIXDatagramPacketType: TypeAlias = tuple[bytes, str] +T_Retval = TypeVar("T_Retval") + + +def _validate_socket( + sock_or_fd: socket.socket | int, + sock_type: socket.SocketKind, + addr_family: socket.AddressFamily = socket.AF_UNSPEC, + *, + require_connected: bool = False, + require_bound: bool = False, +) -> socket.socket: + if isinstance(sock_or_fd, int): + try: + sock = socket.socket(fileno=sock_or_fd) + except OSError as exc: + if exc.errno == errno.ENOTSOCK: + raise ValueError( + "the file descriptor does not refer to a socket" + ) from exc + elif require_connected: + raise ValueError("the socket must be connected") from exc + elif require_bound: + raise ValueError("the socket must be bound to a local address") from exc + else: + raise + elif isinstance(sock_or_fd, socket.socket): + sock = sock_or_fd + else: + raise TypeError( + f"expected an int or socket, got {type(sock_or_fd).__qualname__} instead" + ) + + try: + if require_connected: + try: + sock.getpeername() + except OSError as exc: + raise ValueError("the socket must be connected") from exc + + if require_bound: + try: + if sock.family in (socket.AF_INET, socket.AF_INET6): + bound_addr = sock.getsockname()[1] + else: + bound_addr = sock.getsockname() + except OSError: + bound_addr = None + + if not bound_addr: + raise ValueError("the socket must be bound to a local address") + + if addr_family != socket.AF_UNSPEC and sock.family != addr_family: + raise ValueError( + f"address family mismatch: expected {addr_family.name}, got " + f"{sock.family.name}" + ) + + if sock.type != sock_type: + raise ValueError( + f"socket type mismatch: expected {sock_type.name}, got {sock.type.name}" + ) + except BaseException: + # Avoid ResourceWarning from the locally constructed socket object + if isinstance(sock_or_fd, int): + sock.detach() + + raise + + sock.setblocking(False) + return sock + + +class SocketAttribute(TypedAttributeSet): + """ + .. attribute:: family + :type: socket.AddressFamily + + the address family of the underlying socket + + .. attribute:: local_address + :type: tuple[str, int] | str + + the local address the underlying socket is connected to + + .. attribute:: local_port + :type: int + + for IP based sockets, the local port the underlying socket is bound to + + .. attribute:: raw_socket + :type: socket.socket + + the underlying stdlib socket object + + .. attribute:: remote_address + :type: tuple[str, int] | str + + the remote address the underlying socket is connected to + + .. attribute:: remote_port + :type: int + + for IP based sockets, the remote port the underlying socket is connected to + """ + + family: AddressFamily = typed_attribute() + local_address: SockAddrType = typed_attribute() + local_port: int = typed_attribute() + raw_socket: socket.socket = typed_attribute() + remote_address: SockAddrType = typed_attribute() + remote_port: int = typed_attribute() + + +class _SocketProvider(TypedAttributeProvider): + @property + def extra_attributes(self) -> Mapping[Any, Callable[[], Any]]: + from .._core._sockets import convert_ipv6_sockaddr as convert + + attributes: dict[Any, Callable[[], Any]] = { + SocketAttribute.family: lambda: self._raw_socket.family, + SocketAttribute.local_address: lambda: convert( + self._raw_socket.getsockname() + ), + SocketAttribute.raw_socket: lambda: self._raw_socket, + } + try: + peername: tuple[str, int] | None = convert(self._raw_socket.getpeername()) + except OSError: + peername = None + + # Provide the remote address for connected sockets + if peername is not None: + attributes[SocketAttribute.remote_address] = lambda: peername + + # Provide local and remote ports for IP based sockets + if self._raw_socket.family in (AddressFamily.AF_INET, AddressFamily.AF_INET6): + attributes[SocketAttribute.local_port] = lambda: ( + self._raw_socket.getsockname()[1] + ) + if peername is not None: + remote_port = peername[1] + attributes[SocketAttribute.remote_port] = lambda: remote_port + + return attributes + + @property + @abstractmethod + def _raw_socket(self) -> socket.socket: + pass + + +class SocketStream(ByteStream, _SocketProvider): + """ + Transports bytes over a socket. + + Supports all relevant extra attributes from :class:`~SocketAttribute`. + """ + + @classmethod + async def from_socket(cls, sock_or_fd: socket.socket | int) -> SocketStream: + """ + Wrap an existing socket object or file descriptor as a socket stream. + + The newly created socket wrapper takes ownership of the socket being passed in. + The existing socket must already be connected. + + :param sock_or_fd: a socket object or file descriptor + :return: a socket stream + + """ + sock = _validate_socket(sock_or_fd, socket.SOCK_STREAM, require_connected=True) + return await get_async_backend().wrap_stream_socket(sock) + + +class UNIXSocketStream(SocketStream): + @classmethod + async def from_socket(cls, sock_or_fd: socket.socket | int) -> UNIXSocketStream: + """ + Wrap an existing socket object or file descriptor as a UNIX socket stream. + + The newly created socket wrapper takes ownership of the socket being passed in. + The existing socket must already be connected. + + :param sock_or_fd: a socket object or file descriptor + :return: a UNIX socket stream + + """ + sock = _validate_socket( + sock_or_fd, socket.SOCK_STREAM, socket.AF_UNIX, require_connected=True + ) + return await get_async_backend().wrap_unix_stream_socket(sock) + + @abstractmethod + async def send_fds(self, message: bytes, fds: Collection[int | IOBase]) -> None: + """ + Send file descriptors along with a message to the peer. + + :param message: a non-empty bytestring + :param fds: a collection of files (either numeric file descriptors or open file + or socket objects) + """ + + @abstractmethod + async def receive_fds(self, msglen: int, maxfds: int) -> tuple[bytes, list[int]]: + """ + Receive file descriptors along with a message from the peer. + + :param msglen: length of the message to expect from the peer + :param maxfds: maximum number of file descriptors to expect from the peer + :return: a tuple of (message, file descriptors) + """ + + +class SocketListener(Listener[SocketStream], _SocketProvider): + """ + Listens to incoming socket connections. + + Supports all relevant extra attributes from :class:`~SocketAttribute`. + """ + + @classmethod + async def from_socket( + cls, + sock_or_fd: socket.socket | int, + ) -> SocketListener: + """ + Wrap an existing socket object or file descriptor as a socket listener. + + The newly created listener takes ownership of the socket being passed in. + + :param sock_or_fd: a socket object or file descriptor + :return: a socket listener + + """ + sock = _validate_socket(sock_or_fd, socket.SOCK_STREAM, require_bound=True) + return await get_async_backend().wrap_listener_socket(sock) + + @abstractmethod + async def accept(self) -> SocketStream: + """Accept an incoming connection.""" + + async def serve( + self, + handler: Callable[[SocketStream], Any], + task_group: TaskGroup | None = None, + ) -> None: + from .. import create_task_group + + async with AsyncExitStack() as stack: + if task_group is None: + task_group = await stack.enter_async_context(create_task_group()) + + while True: + stream = await self.accept() + task_group.start_soon(handler, stream) + + +class UDPSocket(UnreliableObjectStream[UDPPacketType], _SocketProvider): + """ + Represents an unconnected UDP socket. + + Supports all relevant extra attributes from :class:`~SocketAttribute`. + """ + + @classmethod + async def from_socket(cls, sock_or_fd: socket.socket | int) -> UDPSocket: + """ + Wrap an existing socket object or file descriptor as a UDP socket. + + The newly created socket wrapper takes ownership of the socket being passed in. + The existing socket must be bound to a local address. + + :param sock_or_fd: a socket object or file descriptor + :return: a UDP socket + + """ + sock = _validate_socket(sock_or_fd, socket.SOCK_DGRAM, require_bound=True) + return await get_async_backend().wrap_udp_socket(sock) + + async def sendto(self, data: bytes, host: str, port: int) -> None: + """ + Alias for :meth:`~.UnreliableObjectSendStream.send` ((data, (host, port))). + + """ + return await self.send((data, (host, port))) + + +class ConnectedUDPSocket(UnreliableObjectStream[bytes], _SocketProvider): + """ + Represents an connected UDP socket. + + Supports all relevant extra attributes from :class:`~SocketAttribute`. + """ + + @classmethod + async def from_socket(cls, sock_or_fd: socket.socket | int) -> ConnectedUDPSocket: + """ + Wrap an existing socket object or file descriptor as a connected UDP socket. + + The newly created socket wrapper takes ownership of the socket being passed in. + The existing socket must already be connected. + + :param sock_or_fd: a socket object or file descriptor + :return: a connected UDP socket + + """ + sock = _validate_socket( + sock_or_fd, + socket.SOCK_DGRAM, + require_connected=True, + ) + return await get_async_backend().wrap_connected_udp_socket(sock) + + +class UNIXDatagramSocket( + UnreliableObjectStream[UNIXDatagramPacketType], _SocketProvider +): + """ + Represents an unconnected Unix datagram socket. + + Supports all relevant extra attributes from :class:`~SocketAttribute`. + """ + + @classmethod + async def from_socket( + cls, + sock_or_fd: socket.socket | int, + ) -> UNIXDatagramSocket: + """ + Wrap an existing socket object or file descriptor as a UNIX datagram + socket. + + The newly created socket wrapper takes ownership of the socket being passed in. + + :param sock_or_fd: a socket object or file descriptor + :return: a UNIX datagram socket + + """ + sock = _validate_socket(sock_or_fd, socket.SOCK_DGRAM, socket.AF_UNIX) + return await get_async_backend().wrap_unix_datagram_socket(sock) + + async def sendto(self, data: bytes, path: str) -> None: + """Alias for :meth:`~.UnreliableObjectSendStream.send` ((data, path)).""" + return await self.send((data, path)) + + +class ConnectedUNIXDatagramSocket(UnreliableObjectStream[bytes], _SocketProvider): + """ + Represents a connected Unix datagram socket. + + Supports all relevant extra attributes from :class:`~SocketAttribute`. + """ + + @classmethod + async def from_socket( + cls, + sock_or_fd: socket.socket | int, + ) -> ConnectedUNIXDatagramSocket: + """ + Wrap an existing socket object or file descriptor as a connected UNIX datagram + socket. + + The newly created socket wrapper takes ownership of the socket being passed in. + The existing socket must already be connected. + + :param sock_or_fd: a socket object or file descriptor + :return: a connected UNIX datagram socket + + """ + sock = _validate_socket( + sock_or_fd, socket.SOCK_DGRAM, socket.AF_UNIX, require_connected=True + ) + return await get_async_backend().wrap_connected_unix_datagram_socket(sock) diff --git a/venv/lib/python3.12/site-packages/anyio/abc/_streams.py b/venv/lib/python3.12/site-packages/anyio/abc/_streams.py new file mode 100644 index 0000000..186e3f5 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/abc/_streams.py @@ -0,0 +1,233 @@ +from __future__ import annotations + +from abc import ABCMeta, abstractmethod +from collections.abc import Callable +from typing import Any, Generic, TypeAlias, TypeVar + +from .._core._exceptions import EndOfStream +from .._core._typedattr import TypedAttributeProvider +from ._resources import AsyncResource +from ._tasks import TaskGroup + +T_Item = TypeVar("T_Item") +T_co = TypeVar("T_co", covariant=True) +T_contra = TypeVar("T_contra", contravariant=True) + + +class UnreliableObjectReceiveStream( + Generic[T_co], AsyncResource, TypedAttributeProvider +): + """ + An interface for receiving objects. + + This interface makes no guarantees that the received messages arrive in the order in + which they were sent, or that no messages are missed. + + Asynchronously iterating over objects of this type will yield objects matching the + given type parameter. + """ + + def __aiter__(self) -> UnreliableObjectReceiveStream[T_co]: + return self + + async def __anext__(self) -> T_co: + try: + return await self.receive() + except EndOfStream: + raise StopAsyncIteration from None + + @abstractmethod + async def receive(self) -> T_co: + """ + Receive the next item. + + :raises ~anyio.ClosedResourceError: if the receive stream has been explicitly + closed + :raises ~anyio.EndOfStream: if this stream has been closed from the other end + :raises ~anyio.BrokenResourceError: if this stream has been rendered unusable + due to external causes + """ + + +class UnreliableObjectSendStream( + Generic[T_contra], AsyncResource, TypedAttributeProvider +): + """ + An interface for sending objects. + + This interface makes no guarantees that the messages sent will reach the + recipient(s) in the same order in which they were sent, or at all. + """ + + @abstractmethod + async def send(self, item: T_contra) -> None: + """ + Send an item to the peer(s). + + :param item: the item to send + :raises ~anyio.ClosedResourceError: if the send stream has been explicitly + closed + :raises ~anyio.BrokenResourceError: if this stream has been rendered unusable + due to external causes + """ + + +class UnreliableObjectStream( + UnreliableObjectReceiveStream[T_Item], UnreliableObjectSendStream[T_Item] +): + """ + A bidirectional message stream which does not guarantee the order or reliability of + message delivery. + """ + + +class ObjectReceiveStream(UnreliableObjectReceiveStream[T_co]): + """ + A receive message stream which guarantees that messages are received in the same + order in which they were sent, and that no messages are missed. + """ + + +class ObjectSendStream(UnreliableObjectSendStream[T_contra]): + """ + A send message stream which guarantees that messages are delivered in the same order + in which they were sent, without missing any messages in the middle. + """ + + +class ObjectStream( + ObjectReceiveStream[T_Item], + ObjectSendStream[T_Item], + UnreliableObjectStream[T_Item], +): + """ + A bidirectional message stream which guarantees the order and reliability of message + delivery. + """ + + @abstractmethod + async def send_eof(self) -> None: + """ + Send an end-of-file indication to the peer. + + You should not try to send any further data to this stream after calling this + method. This method is idempotent (does nothing on successive calls). + """ + + +class ByteReceiveStream(AsyncResource, TypedAttributeProvider): + """ + An interface for receiving bytes from a single peer. + + Iterating this byte stream will yield a byte string of arbitrary length, but no more + than 65536 bytes. + """ + + def __aiter__(self) -> ByteReceiveStream: + return self + + async def __anext__(self) -> bytes: + try: + return await self.receive() + except EndOfStream: + raise StopAsyncIteration from None + + @abstractmethod + async def receive(self, max_bytes: int = 65536) -> bytes: + """ + Receive at most ``max_bytes`` bytes from the peer. + + .. note:: Implementers of this interface should not return an empty + :class:`bytes` object, and users should ignore them. + + :param max_bytes: maximum number of bytes to receive + :return: the received bytes + :raises ~anyio.EndOfStream: if this stream has been closed from the other end + """ + + +class ByteSendStream(AsyncResource, TypedAttributeProvider): + """An interface for sending bytes to a single peer.""" + + @abstractmethod + async def send(self, item: bytes) -> None: + """ + Send the given bytes to the peer. + + :param item: the bytes to send + """ + + +class ByteStream(ByteReceiveStream, ByteSendStream): + """A bidirectional byte stream.""" + + @abstractmethod + async def send_eof(self) -> None: + """ + Send an end-of-file indication to the peer. + + You should not try to send any further data to this stream after calling this + method. This method is idempotent (does nothing on successive calls). + """ + + +#: Type alias for all unreliable bytes-oriented receive streams. +AnyUnreliableByteReceiveStream: TypeAlias = ( + UnreliableObjectReceiveStream[bytes] | ByteReceiveStream +) +#: Type alias for all unreliable bytes-oriented send streams. +AnyUnreliableByteSendStream: TypeAlias = ( + UnreliableObjectSendStream[bytes] | ByteSendStream +) +#: Type alias for all unreliable bytes-oriented streams. +AnyUnreliableByteStream: TypeAlias = UnreliableObjectStream[bytes] | ByteStream +#: Type alias for all bytes-oriented receive streams. +AnyByteReceiveStream: TypeAlias = ObjectReceiveStream[bytes] | ByteReceiveStream +#: Type alias for all bytes-oriented send streams. +AnyByteSendStream: TypeAlias = ObjectSendStream[bytes] | ByteSendStream +#: Type alias for all bytes-oriented streams. +AnyByteStream: TypeAlias = ObjectStream[bytes] | ByteStream + + +class Listener(Generic[T_co], AsyncResource, TypedAttributeProvider): + """An interface for objects that let you accept incoming connections.""" + + @abstractmethod + async def serve( + self, handler: Callable[[T_co], Any], task_group: TaskGroup | None = None + ) -> None: + """ + Accept incoming connections as they come in and start tasks to handle them. + + :param handler: a callable that will be used to handle each accepted connection + :param task_group: the task group that will be used to start tasks for handling + each accepted connection (if omitted, an ad-hoc task group will be created) + """ + + +class ObjectStreamConnectable(Generic[T_co], metaclass=ABCMeta): + @abstractmethod + async def connect(self) -> ObjectStream[T_co]: + """ + Connect to the remote endpoint. + + :return: an object stream connected to the remote end + :raises ConnectionFailed: if the connection fails + """ + + +class ByteStreamConnectable(metaclass=ABCMeta): + @abstractmethod + async def connect(self) -> ByteStream: + """ + Connect to the remote endpoint. + + :return: a bytestream connected to the remote end + :raises ConnectionFailed: if the connection fails + """ + + +#: Type alias for all connectables returning bytestreams or bytes-oriented object streams +AnyByteStreamConnectable: TypeAlias = ( + ObjectStreamConnectable[bytes] | ByteStreamConnectable +) diff --git a/venv/lib/python3.12/site-packages/anyio/abc/_subprocesses.py b/venv/lib/python3.12/site-packages/anyio/abc/_subprocesses.py new file mode 100644 index 0000000..ce0564c --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/abc/_subprocesses.py @@ -0,0 +1,79 @@ +from __future__ import annotations + +from abc import abstractmethod +from signal import Signals + +from ._resources import AsyncResource +from ._streams import ByteReceiveStream, ByteSendStream + + +class Process(AsyncResource): + """An asynchronous version of :class:`subprocess.Popen`.""" + + @abstractmethod + async def wait(self) -> int: + """ + Wait until the process exits. + + :return: the exit code of the process + """ + + @abstractmethod + def terminate(self) -> None: + """ + Terminates the process, gracefully if possible. + + On Windows, this calls ``TerminateProcess()``. + On POSIX systems, this sends ``SIGTERM`` to the process. + + .. seealso:: :meth:`subprocess.Popen.terminate` + """ + + @abstractmethod + def kill(self) -> None: + """ + Kills the process. + + On Windows, this calls ``TerminateProcess()``. + On POSIX systems, this sends ``SIGKILL`` to the process. + + .. seealso:: :meth:`subprocess.Popen.kill` + """ + + @abstractmethod + def send_signal(self, signal: Signals) -> None: + """ + Send a signal to the subprocess. + + .. seealso:: :meth:`subprocess.Popen.send_signal` + + :param signal: the signal number (e.g. :data:`signal.SIGHUP`) + """ + + @property + @abstractmethod + def pid(self) -> int: + """The process ID of the process.""" + + @property + @abstractmethod + def returncode(self) -> int | None: + """ + The return code of the process. If the process has not yet terminated, this will + be ``None``. + """ + + @property + @abstractmethod + def stdin(self) -> ByteSendStream | None: + """The stream for the standard input of the process.""" + + @property + @abstractmethod + def stdout(self) -> ByteReceiveStream | None: + """The stream for the standard output of the process.""" + + @property + @abstractmethod + def stderr(self) -> ByteReceiveStream | None: + """The stream for the standard error output of the process.""" diff --git a/venv/lib/python3.12/site-packages/anyio/abc/_tasks.py b/venv/lib/python3.12/site-packages/anyio/abc/_tasks.py new file mode 100644 index 0000000..516b3ec --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/abc/_tasks.py @@ -0,0 +1,117 @@ +from __future__ import annotations + +import sys +from abc import ABCMeta, abstractmethod +from collections.abc import Awaitable, Callable +from types import TracebackType +from typing import TYPE_CHECKING, Any, Protocol, overload + +if sys.version_info >= (3, 13): + from typing import TypeVar +else: + from typing_extensions import TypeVar + +if sys.version_info >= (3, 11): + from typing import TypeVarTuple, Unpack +else: + from typing_extensions import TypeVarTuple, Unpack + +if TYPE_CHECKING: + from .._core._tasks import CancelScope + +T_Retval = TypeVar("T_Retval") +T_contra = TypeVar("T_contra", contravariant=True, default=None) +PosArgsT = TypeVarTuple("PosArgsT") + + +class TaskStatus(Protocol[T_contra]): + @overload + def started(self: TaskStatus[None]) -> None: ... + + @overload + def started(self, value: T_contra) -> None: ... + + def started(self, value: T_contra | None = None) -> None: + """ + Signal that the task has started. + + :param value: object passed back to the starter of the task + """ + + +class TaskGroup(metaclass=ABCMeta): + """ + Groups several asynchronous tasks together. + + :ivar cancel_scope: the cancel scope inherited by all child tasks + :vartype cancel_scope: CancelScope + + .. note:: On asyncio, support for eager task factories is considered to be + **experimental**. In particular, they don't follow the usual semantics of new + tasks being scheduled on the next iteration of the event loop, and may thus + cause unexpected behavior in code that wasn't written with such semantics in + mind. + """ + + cancel_scope: CancelScope + + @abstractmethod + def start_soon( + self, + func: Callable[[Unpack[PosArgsT]], Awaitable[Any]], + *args: Unpack[PosArgsT], + name: object = None, + ) -> None: + """ + Start a new task in this task group. + + :param func: a coroutine function + :param args: positional arguments to call the function with + :param name: name of the task, for the purposes of introspection and debugging + + .. versionadded:: 3.0 + """ + + @abstractmethod + async def start( + self, + func: Callable[..., Awaitable[Any]], + *args: object, + name: object = None, + ) -> Any: + """ + Start a new task and wait until it signals for readiness. + + The target callable must accept a keyword argument ``task_status`` (of type + :class:`TaskStatus`). Awaiting on this method will return whatever was passed to + ``task_status.started()`` (``None`` by default). + + .. note:: The :class:`TaskStatus` class is generic, and the type argument should + indicate the type of the value that will be passed to + ``task_status.started()``. + + :param func: a coroutine function that accepts the ``task_status`` keyword + argument + :param args: positional arguments to call the function with + :param name: an optional name for the task, for introspection and debugging + :return: the value passed to ``task_status.started()`` + :raises RuntimeError: if the task finishes without calling + ``task_status.started()`` + + .. seealso:: :ref:`start_initialize` + + .. versionadded:: 3.0 + """ + + @abstractmethod + async def __aenter__(self) -> TaskGroup: + """Enter the task group context and allow starting new tasks.""" + + @abstractmethod + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> bool: + """Exit the task group context waiting for all tasks to finish.""" diff --git a/venv/lib/python3.12/site-packages/anyio/abc/_testing.py b/venv/lib/python3.12/site-packages/anyio/abc/_testing.py new file mode 100644 index 0000000..7c50ed7 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/abc/_testing.py @@ -0,0 +1,65 @@ +from __future__ import annotations + +import types +from abc import ABCMeta, abstractmethod +from collections.abc import AsyncGenerator, Callable, Coroutine, Iterable +from typing import Any, TypeVar + +_T = TypeVar("_T") + + +class TestRunner(metaclass=ABCMeta): + """ + Encapsulates a running event loop. Every call made through this object will use the + same event loop. + """ + + def __enter__(self) -> TestRunner: + return self + + @abstractmethod + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: types.TracebackType | None, + ) -> bool | None: ... + + @abstractmethod + def run_asyncgen_fixture( + self, + fixture_func: Callable[..., AsyncGenerator[_T, Any]], + kwargs: dict[str, Any], + ) -> Iterable[_T]: + """ + Run an async generator fixture. + + :param fixture_func: the fixture function + :param kwargs: keyword arguments to call the fixture function with + :return: an iterator yielding the value yielded from the async generator + """ + + @abstractmethod + def run_fixture( + self, + fixture_func: Callable[..., Coroutine[Any, Any, _T]], + kwargs: dict[str, Any], + ) -> _T: + """ + Run an async fixture. + + :param fixture_func: the fixture function + :param kwargs: keyword arguments to call the fixture function with + :return: the return value of the fixture function + """ + + @abstractmethod + def run_test( + self, test_func: Callable[..., Coroutine[Any, Any, Any]], kwargs: dict[str, Any] + ) -> None: + """ + Run an async test function. + + :param test_func: the test function + :param kwargs: keyword arguments to call the test function with + """ diff --git a/venv/lib/python3.12/site-packages/anyio/from_thread.py b/venv/lib/python3.12/site-packages/anyio/from_thread.py new file mode 100644 index 0000000..837de5e --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/from_thread.py @@ -0,0 +1,578 @@ +from __future__ import annotations + +__all__ = ( + "BlockingPortal", + "BlockingPortalProvider", + "check_cancelled", + "run", + "run_sync", + "start_blocking_portal", +) + +import sys +from collections.abc import Awaitable, Callable, Generator +from concurrent.futures import Future +from contextlib import ( + AbstractAsyncContextManager, + AbstractContextManager, + contextmanager, +) +from dataclasses import dataclass, field +from functools import partial +from inspect import isawaitable +from threading import Lock, Thread, current_thread, get_ident +from types import TracebackType +from typing import ( + Any, + Generic, + TypeVar, + cast, + overload, +) + +from ._core._eventloop import ( + get_cancelled_exc_class, + threadlocals, +) +from ._core._eventloop import run as run_eventloop +from ._core._exceptions import NoEventLoopError +from ._core._synchronization import Event +from ._core._tasks import CancelScope, create_task_group +from .abc._tasks import TaskStatus +from .lowlevel import EventLoopToken, current_token + +if sys.version_info >= (3, 11): + from typing import TypeVarTuple, Unpack +else: + from typing_extensions import TypeVarTuple, Unpack + +T_Retval = TypeVar("T_Retval") +T_co = TypeVar("T_co", covariant=True) +PosArgsT = TypeVarTuple("PosArgsT") + + +def _token_or_error(token: EventLoopToken | None) -> EventLoopToken: + if token is not None: + return token + + try: + return threadlocals.current_token + except AttributeError: + raise NoEventLoopError( + "Not running inside an AnyIO worker thread, and no event loop token was " + "provided" + ) from None + + +def run( + func: Callable[[Unpack[PosArgsT]], Awaitable[T_Retval]], + *args: Unpack[PosArgsT], + token: EventLoopToken | None = None, +) -> T_Retval: + """ + Call a coroutine function from a worker thread. + + :param func: a coroutine function + :param args: positional arguments for the callable + :param token: an event loop token to use to get back to the event loop thread + (required if calling this function from outside an AnyIO worker thread) + :return: the return value of the coroutine function + :raises MissingTokenError: if no token was provided and called from outside an + AnyIO worker thread + :raises RunFinishedError: if the event loop tied to ``token`` is no longer running + + .. versionchanged:: 4.11.0 + Added the ``token`` parameter. + + """ + explicit_token = token is not None + token = _token_or_error(token) + return token.backend_class.run_async_from_thread( + func, args, token=token.native_token if explicit_token else None + ) + + +def run_sync( + func: Callable[[Unpack[PosArgsT]], T_Retval], + *args: Unpack[PosArgsT], + token: EventLoopToken | None = None, +) -> T_Retval: + """ + Call a function in the event loop thread from a worker thread. + + :param func: a callable + :param args: positional arguments for the callable + :param token: an event loop token to use to get back to the event loop thread + (required if calling this function from outside an AnyIO worker thread) + :return: the return value of the callable + :raises MissingTokenError: if no token was provided and called from outside an + AnyIO worker thread + :raises RunFinishedError: if the event loop tied to ``token`` is no longer running + + .. versionchanged:: 4.11.0 + Added the ``token`` parameter. + + """ + explicit_token = token is not None + token = _token_or_error(token) + return token.backend_class.run_sync_from_thread( + func, args, token=token.native_token if explicit_token else None + ) + + +class _BlockingAsyncContextManager(Generic[T_co], AbstractContextManager): + _enter_future: Future[T_co] + _exit_future: Future[bool | None] + _exit_event: Event + _exit_exc_info: tuple[ + type[BaseException] | None, BaseException | None, TracebackType | None + ] = (None, None, None) + + def __init__( + self, async_cm: AbstractAsyncContextManager[T_co], portal: BlockingPortal + ): + self._async_cm = async_cm + self._portal = portal + + async def run_async_cm(self) -> bool | None: + try: + self._exit_event = Event() + value = await self._async_cm.__aenter__() + except BaseException as exc: + self._enter_future.set_exception(exc) + raise + else: + self._enter_future.set_result(value) + + try: + # Wait for the sync context manager to exit. + # This next statement can raise `get_cancelled_exc_class()` if + # something went wrong in a task group in this async context + # manager. + await self._exit_event.wait() + finally: + # In case of cancellation, it could be that we end up here before + # `_BlockingAsyncContextManager.__exit__` is called, and an + # `_exit_exc_info` has been set. + result = await self._async_cm.__aexit__(*self._exit_exc_info) + + return result + + def __enter__(self) -> T_co: + self._enter_future = Future() + self._exit_future = self._portal.start_task_soon(self.run_async_cm) + return self._enter_future.result() + + def __exit__( + self, + __exc_type: type[BaseException] | None, + __exc_value: BaseException | None, + __traceback: TracebackType | None, + ) -> bool | None: + self._exit_exc_info = __exc_type, __exc_value, __traceback + self._portal.call(self._exit_event.set) + return self._exit_future.result() + + +class _BlockingPortalTaskStatus(TaskStatus): + def __init__(self, future: Future): + self._future = future + + def started(self, value: object = None) -> None: + self._future.set_result(value) + + +class BlockingPortal: + """ + An object that lets external threads run code in an asynchronous event loop. + + :raises NoEventLoopError: if no supported asynchronous event loop is running in the + current thread + """ + + def __init__(self) -> None: + self._token = current_token() + self._event_loop_thread_id: int | None = get_ident() + self._stop_event = Event() + self._task_group = create_task_group() + + async def __aenter__(self) -> BlockingPortal: + await self._task_group.__aenter__() + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> bool: + await self.stop() + return await self._task_group.__aexit__(exc_type, exc_val, exc_tb) + + def _check_running(self) -> None: + if self._event_loop_thread_id is None: + raise RuntimeError("This portal is not running") + if self._event_loop_thread_id == get_ident(): + raise RuntimeError( + "This method cannot be called from the event loop thread" + ) + + async def sleep_until_stopped(self) -> None: + """Sleep until :meth:`stop` is called.""" + await self._stop_event.wait() + + async def stop(self, cancel_remaining: bool = False) -> None: + """ + Signal the portal to shut down. + + This marks the portal as no longer accepting new calls and exits from + :meth:`sleep_until_stopped`. + + :param cancel_remaining: ``True`` to cancel all the remaining tasks, ``False`` + to let them finish before returning + + """ + self._event_loop_thread_id = None + self._stop_event.set() + if cancel_remaining: + self._task_group.cancel_scope.cancel("the blocking portal is shutting down") + + async def _call_func( + self, + func: Callable[[Unpack[PosArgsT]], Awaitable[T_Retval] | T_Retval], + args: tuple[Unpack[PosArgsT]], + kwargs: dict[str, Any], + future: Future[T_Retval], + ) -> None: + def callback(f: Future[T_Retval]) -> None: + if f.cancelled(): + if self._event_loop_thread_id == get_ident(): + scope.cancel("the future was cancelled") + elif self._event_loop_thread_id is not None: + self.call(scope.cancel, "the future was cancelled") + + try: + retval_or_awaitable = func(*args, **kwargs) + if isawaitable(retval_or_awaitable): + with CancelScope() as scope: + future.add_done_callback(callback) + retval = await retval_or_awaitable + else: + retval = retval_or_awaitable + except get_cancelled_exc_class(): + future.cancel() + future.set_running_or_notify_cancel() + except BaseException as exc: + if not future.cancelled(): + future.set_exception(exc) + + # Let base exceptions fall through + if not isinstance(exc, Exception): + raise + else: + if not future.cancelled(): + future.set_result(retval) + finally: + scope = None # type: ignore[assignment] + + def _spawn_task_from_thread( + self, + func: Callable[[Unpack[PosArgsT]], Awaitable[T_Retval] | T_Retval], + args: tuple[Unpack[PosArgsT]], + kwargs: dict[str, Any], + name: object, + future: Future[T_Retval], + ) -> None: + """ + Spawn a new task using the given callable. + + :param func: a callable + :param args: positional arguments to be passed to the callable + :param kwargs: keyword arguments to be passed to the callable + :param name: name of the task (will be coerced to a string if not ``None``) + :param future: a future that will resolve to the return value of the callable, + or the exception raised during its execution + + """ + run_sync( + partial(self._task_group.start_soon, name=name), + self._call_func, + func, + args, + kwargs, + future, + token=self._token, + ) + + @overload + def call( + self, + func: Callable[[Unpack[PosArgsT]], Awaitable[T_Retval]], + *args: Unpack[PosArgsT], + ) -> T_Retval: ... + + @overload + def call( + self, func: Callable[[Unpack[PosArgsT]], T_Retval], *args: Unpack[PosArgsT] + ) -> T_Retval: ... + + def call( + self, + func: Callable[[Unpack[PosArgsT]], Awaitable[T_Retval] | T_Retval], + *args: Unpack[PosArgsT], + ) -> T_Retval: + """ + Call the given function in the event loop thread. + + If the callable returns a coroutine object, it is awaited on. + + :param func: any callable + :raises RuntimeError: if the portal is not running or if this method is called + from within the event loop thread + + """ + return cast(T_Retval, self.start_task_soon(func, *args).result()) + + @overload + def start_task_soon( + self, + func: Callable[[Unpack[PosArgsT]], Awaitable[T_Retval]], + *args: Unpack[PosArgsT], + name: object = None, + ) -> Future[T_Retval]: ... + + @overload + def start_task_soon( + self, + func: Callable[[Unpack[PosArgsT]], T_Retval], + *args: Unpack[PosArgsT], + name: object = None, + ) -> Future[T_Retval]: ... + + def start_task_soon( + self, + func: Callable[[Unpack[PosArgsT]], Awaitable[T_Retval] | T_Retval], + *args: Unpack[PosArgsT], + name: object = None, + ) -> Future[T_Retval]: + """ + Start a task in the portal's task group. + + The task will be run inside a cancel scope which can be cancelled by cancelling + the returned future. + + :param func: the target function + :param args: positional arguments passed to ``func`` + :param name: name of the task (will be coerced to a string if not ``None``) + :return: a future that resolves with the return value of the callable if the + task completes successfully, or with the exception raised in the task + :raises RuntimeError: if the portal is not running or if this method is called + from within the event loop thread + :rtype: concurrent.futures.Future[T_Retval] + + .. versionadded:: 3.0 + + """ + self._check_running() + f: Future[T_Retval] = Future() + self._spawn_task_from_thread(func, args, {}, name, f) + return f + + def start_task( + self, + func: Callable[..., Awaitable[T_Retval]], + *args: object, + name: object = None, + ) -> tuple[Future[T_Retval], Any]: + """ + Start a task in the portal's task group and wait until it signals for readiness. + + This method works the same way as :meth:`.abc.TaskGroup.start`. + + :param func: the target function + :param args: positional arguments passed to ``func`` + :param name: name of the task (will be coerced to a string if not ``None``) + :return: a tuple of (future, task_status_value) where the ``task_status_value`` + is the value passed to ``task_status.started()`` from within the target + function + :rtype: tuple[concurrent.futures.Future[T_Retval], Any] + + .. versionadded:: 3.0 + + """ + + def task_done(future: Future[T_Retval]) -> None: + if not task_status_future.done(): + if future.cancelled(): + task_status_future.cancel() + elif future.exception(): + task_status_future.set_exception(future.exception()) + else: + exc = RuntimeError( + "Task exited without calling task_status.started()" + ) + task_status_future.set_exception(exc) + + self._check_running() + task_status_future: Future = Future() + task_status = _BlockingPortalTaskStatus(task_status_future) + f: Future = Future() + f.add_done_callback(task_done) + self._spawn_task_from_thread(func, args, {"task_status": task_status}, name, f) + return f, task_status_future.result() + + def wrap_async_context_manager( + self, cm: AbstractAsyncContextManager[T_co] + ) -> AbstractContextManager[T_co]: + """ + Wrap an async context manager as a synchronous context manager via this portal. + + Spawns a task that will call both ``__aenter__()`` and ``__aexit__()``, stopping + in the middle until the synchronous context manager exits. + + :param cm: an asynchronous context manager + :return: a synchronous context manager + + .. versionadded:: 2.1 + + """ + return _BlockingAsyncContextManager(cm, self) + + +@dataclass +class BlockingPortalProvider: + """ + A manager for a blocking portal. Used as a context manager. The first thread to + enter this context manager causes a blocking portal to be started with the specific + parameters, and the last thread to exit causes the portal to be shut down. Thus, + there will be exactly one blocking portal running in this context as long as at + least one thread has entered this context manager. + + The parameters are the same as for :func:`~anyio.run`. + + :param backend: name of the backend + :param backend_options: backend options + + .. versionadded:: 4.4 + """ + + backend: str = "asyncio" + backend_options: dict[str, Any] | None = None + _lock: Lock = field(init=False, default_factory=Lock) + _leases: int = field(init=False, default=0) + _portal: BlockingPortal = field(init=False) + _portal_cm: AbstractContextManager[BlockingPortal] | None = field( + init=False, default=None + ) + + def __enter__(self) -> BlockingPortal: + with self._lock: + if self._portal_cm is None: + self._portal_cm = start_blocking_portal( + self.backend, self.backend_options + ) + self._portal = self._portal_cm.__enter__() + + self._leases += 1 + return self._portal + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: + portal_cm: AbstractContextManager[BlockingPortal] | None = None + with self._lock: + assert self._portal_cm + assert self._leases > 0 + self._leases -= 1 + if not self._leases: + portal_cm = self._portal_cm + self._portal_cm = None + del self._portal + + if portal_cm: + portal_cm.__exit__(None, None, None) + + +@contextmanager +def start_blocking_portal( + backend: str = "asyncio", + backend_options: dict[str, Any] | None = None, + *, + name: str | None = None, +) -> Generator[BlockingPortal, Any, None]: + """ + Start a new event loop in a new thread and run a blocking portal in its main task. + + The parameters are the same as for :func:`~anyio.run`. + + :param backend: name of the backend + :param backend_options: backend options + :param name: name of the thread + :return: a context manager that yields a blocking portal + + .. versionchanged:: 3.0 + Usage as a context manager is now required. + + """ + + async def run_portal() -> None: + async with BlockingPortal() as portal_: + if name is None: + current_thread().name = f"{backend}-portal-{id(portal_):x}" + + future.set_result(portal_) + await portal_.sleep_until_stopped() + + def run_blocking_portal() -> None: + if future.set_running_or_notify_cancel(): + try: + run_eventloop( + run_portal, backend=backend, backend_options=backend_options + ) + except BaseException as exc: + if not future.done(): + future.set_exception(exc) + + future: Future[BlockingPortal] = Future() + thread = Thread(target=run_blocking_portal, daemon=True, name=name) + thread.start() + try: + cancel_remaining_tasks = False + portal = future.result() + try: + yield portal + except BaseException: + cancel_remaining_tasks = True + raise + finally: + try: + portal.call(portal.stop, cancel_remaining_tasks) + except RuntimeError: + pass + finally: + thread.join() + + +def check_cancelled() -> None: + """ + Check if the cancel scope of the host task's running the current worker thread has + been cancelled. + + If the host task's current cancel scope has indeed been cancelled, the + backend-specific cancellation exception will be raised. + + :raises RuntimeError: if the current thread was not spawned by + :func:`.to_thread.run_sync` + + """ + try: + token: EventLoopToken = threadlocals.current_token + except AttributeError: + raise NoEventLoopError( + "This function can only be called inside an AnyIO worker thread" + ) from None + + token.backend_class.check_cancelled() diff --git a/venv/lib/python3.12/site-packages/anyio/functools.py b/venv/lib/python3.12/site-packages/anyio/functools.py new file mode 100644 index 0000000..f1d6c7c --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/functools.py @@ -0,0 +1,409 @@ +from __future__ import annotations + +__all__ = ( + "AsyncCacheInfo", + "AsyncCacheParameters", + "AsyncLRUCacheWrapper", + "cache", + "lru_cache", + "reduce", +) + +import functools +import sys +from collections import OrderedDict +from collections.abc import ( + AsyncIterable, + Awaitable, + Callable, + Coroutine, + Hashable, + Iterable, +) +from functools import update_wrapper +from inspect import iscoroutinefunction +from typing import ( + Any, + Generic, + NamedTuple, + TypedDict, + TypeVar, + cast, + final, + overload, +) +from weakref import WeakKeyDictionary + +from ._core._eventloop import current_time +from ._core._synchronization import Lock +from .lowlevel import RunVar, checkpoint + +if sys.version_info >= (3, 11): + from typing import ParamSpec +else: + from typing_extensions import ParamSpec + +T = TypeVar("T") +S = TypeVar("S") +P = ParamSpec("P") +lru_cache_items: RunVar[ + WeakKeyDictionary[ + AsyncLRUCacheWrapper[Any, Any], + OrderedDict[ + Hashable, + tuple[_InitialMissingType, Lock, float | None] + | tuple[Any, None, float | None], + ], + ] +] = RunVar("lru_cache_items") + + +class _InitialMissingType: + pass + + +initial_missing: _InitialMissingType = _InitialMissingType() + + +class AsyncCacheInfo(NamedTuple): + hits: int + misses: int + maxsize: int | None + currsize: int + ttl: int | None + + +class AsyncCacheParameters(TypedDict): + maxsize: int | None + typed: bool + always_checkpoint: bool + ttl: int | None + + +class _LRUMethodWrapper(Generic[T]): + def __init__(self, wrapper: AsyncLRUCacheWrapper[..., T], instance: object): + self.__wrapper = wrapper + self.__instance = instance + + def cache_info(self) -> AsyncCacheInfo: + return self.__wrapper.cache_info() + + def cache_parameters(self) -> AsyncCacheParameters: + return self.__wrapper.cache_parameters() + + def cache_clear(self) -> None: + self.__wrapper.cache_clear() + + async def __call__(self, *args: Any, **kwargs: Any) -> T: + if self.__instance is None: + return await self.__wrapper(*args, **kwargs) + + return await self.__wrapper(self.__instance, *args, **kwargs) + + +@final +class AsyncLRUCacheWrapper(Generic[P, T]): + def __init__( + self, + func: Callable[P, Awaitable[T]], + maxsize: int | None, + typed: bool, + always_checkpoint: bool, + ttl: int | None, + ): + self.__wrapped__ = func + self._hits: int = 0 + self._misses: int = 0 + self._maxsize = max(maxsize, 0) if maxsize is not None else None + self._currsize: int = 0 + self._typed = typed + self._always_checkpoint = always_checkpoint + self._ttl = ttl + update_wrapper(self, func) + + def cache_info(self) -> AsyncCacheInfo: + return AsyncCacheInfo( + self._hits, self._misses, self._maxsize, self._currsize, self._ttl + ) + + def cache_parameters(self) -> AsyncCacheParameters: + return { + "maxsize": self._maxsize, + "typed": self._typed, + "always_checkpoint": self._always_checkpoint, + "ttl": self._ttl, + } + + def cache_clear(self) -> None: + if cache := lru_cache_items.get(None): + cache.pop(self, None) + self._hits = self._misses = self._currsize = 0 + + async def __call__(self, *args: P.args, **kwargs: P.kwargs) -> T: + # Easy case first: if maxsize == 0, no caching is done + if self._maxsize == 0: + value = await self.__wrapped__(*args, **kwargs) + self._misses += 1 + return value + + # The key is constructed as a flat tuple to avoid memory overhead + key: tuple[Any, ...] = args + if kwargs: + # initial_missing is used as a separator + key += (initial_missing,) + sum(kwargs.items(), ()) + + if self._typed: + key += tuple(type(arg) for arg in args) + if kwargs: + key += (initial_missing,) + tuple(type(val) for val in kwargs.values()) + + try: + cache = lru_cache_items.get() + except LookupError: + cache = WeakKeyDictionary() + lru_cache_items.set(cache) + + try: + cache_entry = cache[self] + except KeyError: + cache_entry = cache[self] = OrderedDict() + + cached_value: T | _InitialMissingType + try: + cached_value, lock, expires_at = cache_entry[key] + except KeyError: + # We're the first task to call this function + cached_value, lock, expires_at = ( + initial_missing, + Lock(fast_acquire=not self._always_checkpoint), + None, + ) + cache_entry[key] = cached_value, lock, expires_at + + if lock is None: + if expires_at is not None and current_time() >= expires_at: + self._currsize -= 1 + cached_value, lock, expires_at = ( + initial_missing, + Lock(fast_acquire=not self._always_checkpoint), + None, + ) + cache_entry[key] = cached_value, lock, expires_at + else: + # The value was already cached + self._hits += 1 + cache_entry.move_to_end(key) + if self._always_checkpoint: + await checkpoint() + + return cast(T, cached_value) + + async with lock: + # Check if another task filled the cache while we acquired the lock + if (cached_value := cache_entry[key][0]) is initial_missing: + self._misses += 1 + if self._maxsize is not None and self._currsize >= self._maxsize: + cache_entry.popitem(last=False) + else: + self._currsize += 1 + + value = await self.__wrapped__(*args, **kwargs) + expires_at = ( + current_time() + self._ttl if self._ttl is not None else None + ) + cache_entry[key] = value, None, expires_at + else: + # Another task filled the cache while we were waiting for the lock + self._hits += 1 + cache_entry.move_to_end(key) + value = cast(T, cached_value) + + return value + + def __get__( + self, instance: object, owner: type | None = None + ) -> _LRUMethodWrapper[T]: + wrapper = _LRUMethodWrapper(self, instance) + update_wrapper(wrapper, self.__wrapped__) + return wrapper + + +class _LRUCacheWrapper(Generic[T]): + def __init__( + self, maxsize: int | None, typed: bool, always_checkpoint: bool, ttl: int | None + ): + self._maxsize = maxsize + self._typed = typed + self._always_checkpoint = always_checkpoint + self._ttl = ttl + + @overload + def __call__( # type: ignore[overload-overlap] + self, func: Callable[P, Coroutine[Any, Any, T]], / + ) -> AsyncLRUCacheWrapper[P, T]: ... + + @overload + def __call__( + self, func: Callable[..., T], / + ) -> functools._lru_cache_wrapper[T]: ... + + def __call__( + self, f: Callable[P, Coroutine[Any, Any, T]] | Callable[..., T], / + ) -> AsyncLRUCacheWrapper[P, T] | functools._lru_cache_wrapper[T]: + if iscoroutinefunction(f): + return AsyncLRUCacheWrapper( + f, self._maxsize, self._typed, self._always_checkpoint, self._ttl + ) + + return functools.lru_cache(maxsize=self._maxsize, typed=self._typed)(f) # type: ignore[arg-type] + + +@overload +def cache( # type: ignore[overload-overlap] + func: Callable[P, Coroutine[Any, Any, T]], / +) -> AsyncLRUCacheWrapper[P, T]: ... + + +@overload +def cache(func: Callable[..., T], /) -> functools._lru_cache_wrapper[T]: ... + + +def cache( + func: Callable[..., T] | Callable[P, Coroutine[Any, Any, T]], / +) -> AsyncLRUCacheWrapper[P, T] | functools._lru_cache_wrapper[T]: + """ + A convenient shortcut for :func:`lru_cache` with ``maxsize=None``. + + This is the asynchronous equivalent to :func:`functools.cache`. + + """ + return lru_cache(maxsize=None)(func) + + +@overload +def lru_cache( + *, + maxsize: int | None = ..., + typed: bool = ..., + always_checkpoint: bool = ..., + ttl: int | None = ..., +) -> _LRUCacheWrapper[Any]: ... + + +@overload +def lru_cache( # type: ignore[overload-overlap] + func: Callable[P, Coroutine[Any, Any, T]], / +) -> AsyncLRUCacheWrapper[P, T]: ... + + +@overload +def lru_cache(func: Callable[..., T], /) -> functools._lru_cache_wrapper[T]: ... + + +def lru_cache( + func: Callable[P, Coroutine[Any, Any, T]] | Callable[..., T] | None = None, + /, + *, + maxsize: int | None = 128, + typed: bool = False, + always_checkpoint: bool = False, + ttl: int | None = None, +) -> ( + AsyncLRUCacheWrapper[P, T] | functools._lru_cache_wrapper[T] | _LRUCacheWrapper[Any] +): + """ + An asynchronous version of :func:`functools.lru_cache`. + + If a synchronous function is passed, the standard library + :func:`functools.lru_cache` is applied instead. + + :param always_checkpoint: if ``True``, every call to the cached function will be + guaranteed to yield control to the event loop at least once + :param ttl: time in seconds after which to invalidate cache entries + + .. note:: Caches and locks are managed on a per-event loop basis. + + """ + if func is None: + return _LRUCacheWrapper[Any](maxsize, typed, always_checkpoint, ttl) + + if not callable(func): + raise TypeError("the first argument must be callable") + + return _LRUCacheWrapper[T](maxsize, typed, always_checkpoint, ttl)(func) + + +@overload +async def reduce( + function: Callable[[T, S], Awaitable[T]], + iterable: Iterable[S] | AsyncIterable[S], + /, + initial: T, +) -> T: ... + + +@overload +async def reduce( + function: Callable[[T, T], Awaitable[T]], + iterable: Iterable[T] | AsyncIterable[T], + /, +) -> T: ... + + +async def reduce( # type: ignore[misc] + function: Callable[[T, T], Awaitable[T]] | Callable[[T, S], Awaitable[T]], + iterable: Iterable[T] | Iterable[S] | AsyncIterable[T] | AsyncIterable[S], + /, + initial: T | _InitialMissingType = initial_missing, +) -> T: + """ + Asynchronous version of :func:`functools.reduce`. + + :param function: a coroutine function that takes two arguments: the accumulated + value and the next element from the iterable + :param iterable: an iterable or async iterable + :param initial: the initial value (if missing, the first element of the iterable is + used as the initial value) + + """ + element: Any + function_called = False + if isinstance(iterable, AsyncIterable): + async_it = iterable.__aiter__() + if initial is initial_missing: + try: + value = cast(T, await async_it.__anext__()) + except StopAsyncIteration: + raise TypeError( + "reduce() of empty sequence with no initial value" + ) from None + else: + value = cast(T, initial) + + async for element in async_it: + value = await function(value, element) + function_called = True + elif isinstance(iterable, Iterable): + it = iter(iterable) + if initial is initial_missing: + try: + value = cast(T, next(it)) + except StopIteration: + raise TypeError( + "reduce() of empty sequence with no initial value" + ) from None + else: + value = cast(T, initial) + + for element in it: + value = await function(value, element) + function_called = True + else: + raise TypeError("reduce() argument 2 must be an iterable or async iterable") + + # Make sure there is at least one checkpoint, even if an empty iterable and an + # initial value were given + if not function_called: + await checkpoint() + + return value diff --git a/venv/lib/python3.12/site-packages/anyio/lowlevel.py b/venv/lib/python3.12/site-packages/anyio/lowlevel.py new file mode 100644 index 0000000..ffbb75a --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/lowlevel.py @@ -0,0 +1,196 @@ +from __future__ import annotations + +__all__ = ( + "EventLoopToken", + "RunvarToken", + "RunVar", + "checkpoint", + "checkpoint_if_cancelled", + "cancel_shielded_checkpoint", + "current_token", +) + +import enum +from dataclasses import dataclass +from types import TracebackType +from typing import Any, Generic, Literal, TypeVar, final, overload +from weakref import WeakKeyDictionary + +from ._core._eventloop import get_async_backend +from .abc import AsyncBackend + +T = TypeVar("T") +D = TypeVar("D") + + +async def checkpoint() -> None: + """ + Check for cancellation and allow the scheduler to switch to another task. + + Equivalent to (but more efficient than):: + + await checkpoint_if_cancelled() + await cancel_shielded_checkpoint() + + .. versionadded:: 3.0 + + """ + await get_async_backend().checkpoint() + + +async def checkpoint_if_cancelled() -> None: + """ + Enter a checkpoint if the enclosing cancel scope has been cancelled. + + This does not allow the scheduler to switch to a different task. + + .. versionadded:: 3.0 + + """ + await get_async_backend().checkpoint_if_cancelled() + + +async def cancel_shielded_checkpoint() -> None: + """ + Allow the scheduler to switch to another task but without checking for cancellation. + + Equivalent to (but potentially more efficient than):: + + with CancelScope(shield=True): + await checkpoint() + + .. versionadded:: 3.0 + + """ + await get_async_backend().cancel_shielded_checkpoint() + + +@final +@dataclass(frozen=True, repr=False) +class EventLoopToken: + """ + An opaque object that holds a reference to an event loop. + + .. versionadded:: 4.11.0 + """ + + backend_class: type[AsyncBackend] + native_token: object + + +def current_token() -> EventLoopToken: + """ + Return a token object that can be used to call code in the current event loop from + another thread. + + :raises NoEventLoopError: if no supported asynchronous event loop is running in the + current thread + + .. versionadded:: 4.11.0 + + """ + backend_class = get_async_backend() + raw_token = backend_class.current_token() + return EventLoopToken(backend_class, raw_token) + + +_run_vars: WeakKeyDictionary[object, dict[RunVar[Any], Any]] = WeakKeyDictionary() + + +class _NoValueSet(enum.Enum): + NO_VALUE_SET = enum.auto() + + +class RunvarToken(Generic[T]): + __slots__ = "_var", "_value", "_redeemed" + + def __init__(self, var: RunVar[T], value: T | Literal[_NoValueSet.NO_VALUE_SET]): + self._var = var + self._value: T | Literal[_NoValueSet.NO_VALUE_SET] = value + self._redeemed = False + + def __enter__(self) -> RunvarToken[T]: + return self + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: + self._var.reset(self) + + +class RunVar(Generic[T]): + """ + Like a :class:`~contextvars.ContextVar`, except scoped to the running event loop. + + Can be used as a context manager, Just like :class:`~contextvars.ContextVar`, that + will reset the variable to its previous value when the context block is exited. + """ + + __slots__ = "_name", "_default" + + NO_VALUE_SET: Literal[_NoValueSet.NO_VALUE_SET] = _NoValueSet.NO_VALUE_SET + + def __init__( + self, name: str, default: T | Literal[_NoValueSet.NO_VALUE_SET] = NO_VALUE_SET + ): + self._name = name + self._default = default + + @property + def _current_vars(self) -> dict[RunVar[T], T]: + native_token = current_token().native_token + try: + return _run_vars[native_token] + except KeyError: + run_vars = _run_vars[native_token] = {} + return run_vars + + @overload + def get(self, default: D) -> T | D: ... + + @overload + def get(self) -> T: ... + + def get( + self, default: D | Literal[_NoValueSet.NO_VALUE_SET] = NO_VALUE_SET + ) -> T | D: + try: + return self._current_vars[self] + except KeyError: + if default is not RunVar.NO_VALUE_SET: + return default + elif self._default is not RunVar.NO_VALUE_SET: + return self._default + + raise LookupError( + f'Run variable "{self._name}" has no value and no default set' + ) + + def set(self, value: T) -> RunvarToken[T]: + current_vars = self._current_vars + token = RunvarToken(self, current_vars.get(self, RunVar.NO_VALUE_SET)) + current_vars[self] = value + return token + + def reset(self, token: RunvarToken[T]) -> None: + if token._var is not self: + raise ValueError("This token does not belong to this RunVar") + + if token._redeemed: + raise ValueError("This token has already been used") + + if token._value is _NoValueSet.NO_VALUE_SET: + try: + del self._current_vars[self] + except KeyError: + pass + else: + self._current_vars[self] = token._value + + token._redeemed = True + + def __repr__(self) -> str: + return f"" diff --git a/venv/lib/python3.12/site-packages/anyio/py.typed b/venv/lib/python3.12/site-packages/anyio/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.12/site-packages/anyio/pytest_plugin.py b/venv/lib/python3.12/site-packages/anyio/pytest_plugin.py new file mode 100644 index 0000000..a5183f0 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/pytest_plugin.py @@ -0,0 +1,363 @@ +from __future__ import annotations + +import dataclasses +import socket +import sys +from collections.abc import Callable, Generator, Iterator +from contextlib import ExitStack, contextmanager +from inspect import isasyncgenfunction, iscoroutinefunction, ismethod +from typing import Any, cast + +import pytest +from _pytest.fixtures import FuncFixtureInfo, SubRequest +from _pytest.outcomes import Exit +from _pytest.python import CallSpec2 +from _pytest.scope import Scope + +from . import get_available_backends +from ._core._eventloop import ( + current_async_library, + get_async_backend, + reset_current_async_library, + set_current_async_library, +) +from ._core._exceptions import iterate_exceptions +from .abc import TestRunner + +if sys.version_info < (3, 11): + from exceptiongroup import ExceptionGroup + +_current_runner: TestRunner | None = None +_runner_stack: ExitStack | None = None +_runner_leases = 0 + + +def extract_backend_and_options(backend: object) -> tuple[str, dict[str, Any]]: + if isinstance(backend, str): + return backend, {} + elif isinstance(backend, tuple) and len(backend) == 2: + if isinstance(backend[0], str) and isinstance(backend[1], dict): + return cast(tuple[str, dict[str, Any]], backend) + + raise TypeError("anyio_backend must be either a string or tuple of (string, dict)") + + +@contextmanager +def get_runner( + backend_name: str, backend_options: dict[str, Any] +) -> Iterator[TestRunner]: + global _current_runner, _runner_leases, _runner_stack + if _current_runner is None: + asynclib = get_async_backend(backend_name) + _runner_stack = ExitStack() + if current_async_library() is None: + # Since we're in control of the event loop, we can cache the name of the + # async library + token = set_current_async_library(backend_name) + _runner_stack.callback(reset_current_async_library, token) + + backend_options = backend_options or {} + _current_runner = _runner_stack.enter_context( + asynclib.create_test_runner(backend_options) + ) + + _runner_leases += 1 + try: + yield _current_runner + finally: + _runner_leases -= 1 + if not _runner_leases: + assert _runner_stack is not None + _runner_stack.close() + _runner_stack = _current_runner = None + + +def pytest_addoption(parser: pytest.Parser) -> None: + parser.addini( + "anyio_mode", + default="strict", + help='AnyIO plugin mode (either "strict" or "auto")', + ) + + +def pytest_configure(config: pytest.Config) -> None: + config.addinivalue_line( + "markers", + "anyio: mark the (coroutine function) test to be run asynchronously via anyio.", + ) + if ( + config.getini("anyio_mode") == "auto" + and config.pluginmanager.has_plugin("asyncio") + and config.getini("asyncio_mode") == "auto" + ): + config.issue_config_time_warning( + pytest.PytestConfigWarning( + "AnyIO auto mode has been enabled together with pytest-asyncio auto " + "mode. This may cause unexpected behavior." + ), + 1, + ) + + +@pytest.hookimpl(hookwrapper=True) +def pytest_fixture_setup(fixturedef: Any, request: Any) -> Generator[Any]: + def wrapper(anyio_backend: Any, request: SubRequest, **kwargs: Any) -> Any: + # Rebind any fixture methods to the request instance + if ( + request.instance + and ismethod(func) + and type(func.__self__) is type(request.instance) + ): + local_func = func.__func__.__get__(request.instance) + else: + local_func = func + + backend_name, backend_options = extract_backend_and_options(anyio_backend) + if has_backend_arg: + kwargs["anyio_backend"] = anyio_backend + + if has_request_arg: + kwargs["request"] = request + + with get_runner(backend_name, backend_options) as runner: + if isasyncgenfunction(local_func): + yield from runner.run_asyncgen_fixture(local_func, kwargs) + else: + yield runner.run_fixture(local_func, kwargs) + + # Only apply this to coroutine functions and async generator functions in requests + # that involve the anyio_backend fixture + func = fixturedef.func + if isasyncgenfunction(func) or iscoroutinefunction(func): + if "anyio_backend" in request.fixturenames: + fixturedef.func = wrapper + original_argname = fixturedef.argnames + + if not (has_backend_arg := "anyio_backend" in fixturedef.argnames): + fixturedef.argnames += ("anyio_backend",) + + if not (has_request_arg := "request" in fixturedef.argnames): + fixturedef.argnames += ("request",) + + try: + return (yield) + finally: + fixturedef.func = func + fixturedef.argnames = original_argname + + return (yield) + + +@pytest.hookimpl(tryfirst=True) +def pytest_pycollect_makeitem( + collector: pytest.Module | pytest.Class, name: str, obj: object +) -> None: + if collector.istestfunction(obj, name): + inner_func = obj.hypothesis.inner_test if hasattr(obj, "hypothesis") else obj + if iscoroutinefunction(inner_func): + anyio_auto_mode = collector.config.getini("anyio_mode") == "auto" + marker = collector.get_closest_marker("anyio") + own_markers = getattr(obj, "pytestmark", ()) + if ( + anyio_auto_mode + or marker + or any(marker.name == "anyio" for marker in own_markers) + ): + pytest.mark.usefixtures("anyio_backend")(obj) + + +def pytest_collection_finish(session: pytest.Session) -> None: + for i, item in reversed(list(enumerate(session.items))): + if ( + isinstance(item, pytest.Function) + and iscoroutinefunction(item.function) + and item.get_closest_marker("anyio") is not None + and "anyio_backend" not in item.fixturenames + ): + new_items = [] + try: + cs_fields = {f.name for f in dataclasses.fields(CallSpec2)} + except TypeError: + cs_fields = set() + + for param_index, backend in enumerate(get_available_backends()): + if "_arg2scope" in cs_fields: # pytest >= 8 + callspec = CallSpec2( + params={"anyio_backend": backend}, + indices={"anyio_backend": param_index}, + _arg2scope={"anyio_backend": Scope.Module}, + _idlist=[backend], + marks=[], + ) + else: # pytest 7.x + callspec = CallSpec2( # type: ignore[call-arg] + funcargs={}, + params={"anyio_backend": backend}, + indices={"anyio_backend": param_index}, + arg2scope={"anyio_backend": Scope.Module}, + idlist=[backend], + marks=[], + ) + + fi = item._fixtureinfo + new_names_closure = list(fi.names_closure) + if "anyio_backend" not in new_names_closure: + new_names_closure.append("anyio_backend") + + new_fixtureinfo = FuncFixtureInfo( + argnames=fi.argnames, + initialnames=fi.initialnames, + names_closure=new_names_closure, + name2fixturedefs=fi.name2fixturedefs, + ) + new_item = pytest.Function.from_parent( + item.parent, + name=f"{item.originalname}[{backend}]", + callspec=callspec, + callobj=item.obj, + fixtureinfo=new_fixtureinfo, + keywords=item.keywords, + originalname=item.originalname, + ) + new_items.append(new_item) + + session.items[i : i + 1] = new_items + + +@pytest.hookimpl(tryfirst=True) +def pytest_pyfunc_call(pyfuncitem: Any) -> bool | None: + def run_with_hypothesis(**kwargs: Any) -> None: + with get_runner(backend_name, backend_options) as runner: + runner.run_test(original_func, kwargs) + + backend = pyfuncitem.funcargs.get("anyio_backend") + if backend: + backend_name, backend_options = extract_backend_and_options(backend) + + if hasattr(pyfuncitem.obj, "hypothesis"): + # Wrap the inner test function unless it's already wrapped + original_func = pyfuncitem.obj.hypothesis.inner_test + if original_func.__qualname__ != run_with_hypothesis.__qualname__: + if iscoroutinefunction(original_func): + pyfuncitem.obj.hypothesis.inner_test = run_with_hypothesis + + return None + + if iscoroutinefunction(pyfuncitem.obj): + funcargs = pyfuncitem.funcargs + testargs = {arg: funcargs[arg] for arg in pyfuncitem._fixtureinfo.argnames} + with get_runner(backend_name, backend_options) as runner: + try: + runner.run_test(pyfuncitem.obj, testargs) + except ExceptionGroup as excgrp: + for exc in iterate_exceptions(excgrp): + if isinstance(exc, (Exit, KeyboardInterrupt, SystemExit)): + raise exc from excgrp + + raise + + return True + + return None + + +@pytest.fixture(scope="module", params=get_available_backends()) +def anyio_backend(request: Any) -> Any: + return request.param + + +@pytest.fixture +def anyio_backend_name(anyio_backend: Any) -> str: + if isinstance(anyio_backend, str): + return anyio_backend + else: + return anyio_backend[0] + + +@pytest.fixture +def anyio_backend_options(anyio_backend: Any) -> dict[str, Any]: + if isinstance(anyio_backend, str): + return {} + else: + return anyio_backend[1] + + +class FreePortFactory: + """ + Manages port generation based on specified socket kind, ensuring no duplicate + ports are generated. + + This class provides functionality for generating available free ports on the + system. It is initialized with a specific socket kind and can generate ports + for given address families while avoiding reuse of previously generated ports. + + Users should not instantiate this class directly, but use the + ``free_tcp_port_factory`` and ``free_udp_port_factory`` fixtures instead. For simple + uses cases, ``free_tcp_port`` and ``free_udp_port`` can be used instead. + """ + + def __init__(self, kind: socket.SocketKind) -> None: + self._kind = kind + self._generated = set[int]() + + @property + def kind(self) -> socket.SocketKind: + """ + The type of socket connection (e.g., :data:`~socket.SOCK_STREAM` or + :data:`~socket.SOCK_DGRAM`) used to bind for checking port availability + + """ + return self._kind + + def __call__(self, family: socket.AddressFamily | None = None) -> int: + """ + Return an unbound port for the given address family. + + :param family: if omitted, both IPv4 and IPv6 addresses will be tried + :return: a port number + + """ + if family is not None: + families = [family] + else: + families = [socket.AF_INET] + if socket.has_ipv6: + families.append(socket.AF_INET6) + + while True: + port = 0 + with ExitStack() as stack: + for family in families: + sock = stack.enter_context(socket.socket(family, self._kind)) + addr = "::1" if family == socket.AF_INET6 else "127.0.0.1" + try: + sock.bind((addr, port)) + except OSError: + break + + if not port: + port = sock.getsockname()[1] + else: + if port not in self._generated: + self._generated.add(port) + return port + + +@pytest.fixture(scope="session") +def free_tcp_port_factory() -> FreePortFactory: + return FreePortFactory(socket.SOCK_STREAM) + + +@pytest.fixture(scope="session") +def free_udp_port_factory() -> FreePortFactory: + return FreePortFactory(socket.SOCK_DGRAM) + + +@pytest.fixture +def free_tcp_port(free_tcp_port_factory: Callable[[], int]) -> int: + return free_tcp_port_factory() + + +@pytest.fixture +def free_udp_port(free_udp_port_factory: Callable[[], int]) -> int: + return free_udp_port_factory() diff --git a/venv/lib/python3.12/site-packages/anyio/streams/__init__.py b/venv/lib/python3.12/site-packages/anyio/streams/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.12/site-packages/anyio/streams/__pycache__/__init__.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/streams/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..82a484b057cdf25470be9280389e350258ad3fc8 GIT binary patch literal 201 zcmZ9FK?=e!5JeNKAVPOu!bLl%Tk!~9A;flQL(?QAu_YU?;Tb%OCvfcvq`R(6wto2Y z-wYq-mFF80b>F^4%1;{qnwIhMAc5@Y(C1);%ti@bNhm{7tqR+=!cPra^h T63=!OAJb@;;G0oOZ5HVV_2V|= literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/anyio/streams/__pycache__/buffered.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/streams/__pycache__/buffered.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9d3a767d09807fcaac003e95ad2cbdf1b32eb6b6 GIT binary patch literal 9080 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/anyio/streams/__pycache__/file.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/streams/__pycache__/file.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4fd6857acae9a9e484564c7d606f53688db494cd GIT binary patch literal 7478 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 Rx|GJQ7}w7KodChb_;0?@og@GN literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/anyio/streams/__pycache__/memory.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/streams/__pycache__/memory.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..641bda2525a09901fa8d504f623d93ba14539b9a GIT binary patch literal 15032 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/anyio/streams/__pycache__/stapled.cpython-312.pyc b/venv/lib/python3.12/site-packages/anyio/streams/__pycache__/stapled.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fc00562c2fbf09648f264a52f7d5f8dbd800bb73 GIT binary patch literal 7601 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/anyio/streams/buffered.py b/venv/lib/python3.12/site-packages/anyio/streams/buffered.py new file mode 100644 index 0000000..57c7cd7 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/streams/buffered.py @@ -0,0 +1,188 @@ +from __future__ import annotations + +__all__ = ( + "BufferedByteReceiveStream", + "BufferedByteStream", + "BufferedConnectable", +) + +import sys +from collections.abc import Callable, Iterable, Mapping +from dataclasses import dataclass, field +from typing import Any, SupportsIndex + +from .. import ClosedResourceError, DelimiterNotFound, EndOfStream, IncompleteRead +from ..abc import ( + AnyByteReceiveStream, + AnyByteStream, + AnyByteStreamConnectable, + ByteReceiveStream, + ByteStream, + ByteStreamConnectable, +) + +if sys.version_info >= (3, 12): + from typing import override +else: + from typing_extensions import override + + +@dataclass(eq=False) +class BufferedByteReceiveStream(ByteReceiveStream): + """ + Wraps any bytes-based receive stream and uses a buffer to provide sophisticated + receiving capabilities in the form of a byte stream. + """ + + receive_stream: AnyByteReceiveStream + _buffer: bytearray = field(init=False, default_factory=bytearray) + _closed: bool = field(init=False, default=False) + + async def aclose(self) -> None: + await self.receive_stream.aclose() + self._closed = True + + @property + def buffer(self) -> bytes: + """The bytes currently in the buffer.""" + return bytes(self._buffer) + + @property + def extra_attributes(self) -> Mapping[Any, Callable[[], Any]]: + return self.receive_stream.extra_attributes + + def feed_data(self, data: Iterable[SupportsIndex], /) -> None: + """ + Append data directly into the buffer. + + Any data in the buffer will be consumed by receive operations before receiving + anything from the wrapped stream. + + :param data: the data to append to the buffer (can be bytes or anything else + that supports ``__index__()``) + + """ + self._buffer.extend(data) + + async def receive(self, max_bytes: int = 65536) -> bytes: + if self._closed: + raise ClosedResourceError + + if self._buffer: + chunk = bytes(self._buffer[:max_bytes]) + del self._buffer[:max_bytes] + return chunk + elif isinstance(self.receive_stream, ByteReceiveStream): + return await self.receive_stream.receive(max_bytes) + else: + # With a bytes-oriented object stream, we need to handle any surplus bytes + # we get from the receive() call + chunk = await self.receive_stream.receive() + if len(chunk) > max_bytes: + # Save the surplus bytes in the buffer + self._buffer.extend(chunk[max_bytes:]) + return chunk[:max_bytes] + else: + return chunk + + async def receive_exactly(self, nbytes: int) -> bytes: + """ + Read exactly the given amount of bytes from the stream. + + :param nbytes: the number of bytes to read + :return: the bytes read + :raises ~anyio.IncompleteRead: if the stream was closed before the requested + amount of bytes could be read from the stream + + """ + while True: + remaining = nbytes - len(self._buffer) + if remaining <= 0: + retval = self._buffer[:nbytes] + del self._buffer[:nbytes] + return bytes(retval) + + try: + if isinstance(self.receive_stream, ByteReceiveStream): + chunk = await self.receive_stream.receive(remaining) + else: + chunk = await self.receive_stream.receive() + except EndOfStream as exc: + raise IncompleteRead from exc + + self._buffer.extend(chunk) + + async def receive_until(self, delimiter: bytes, max_bytes: int) -> bytes: + """ + Read from the stream until the delimiter is found or max_bytes have been read. + + :param delimiter: the marker to look for in the stream + :param max_bytes: maximum number of bytes that will be read before raising + :exc:`~anyio.DelimiterNotFound` + :return: the bytes read (not including the delimiter) + :raises ~anyio.IncompleteRead: if the stream was closed before the delimiter + was found + :raises ~anyio.DelimiterNotFound: if the delimiter is not found within the + bytes read up to the maximum allowed + + """ + delimiter_size = len(delimiter) + offset = 0 + while True: + # Check if the delimiter can be found in the current buffer + index = self._buffer.find(delimiter, offset) + if index >= 0: + found = self._buffer[:index] + del self._buffer[: index + len(delimiter) :] + return bytes(found) + + # Check if the buffer is already at or over the limit + if len(self._buffer) >= max_bytes: + raise DelimiterNotFound(max_bytes) + + # Read more data into the buffer from the socket + try: + data = await self.receive_stream.receive() + except EndOfStream as exc: + raise IncompleteRead from exc + + # Move the offset forward and add the new data to the buffer + offset = max(len(self._buffer) - delimiter_size + 1, 0) + self._buffer.extend(data) + + +class BufferedByteStream(BufferedByteReceiveStream, ByteStream): + """ + A full-duplex variant of :class:`BufferedByteReceiveStream`. All writes are passed + through to the wrapped stream as-is. + """ + + def __init__(self, stream: AnyByteStream): + """ + :param stream: the stream to be wrapped + + """ + super().__init__(stream) + self._stream = stream + + @override + async def send_eof(self) -> None: + await self._stream.send_eof() + + @override + async def send(self, item: bytes) -> None: + await self._stream.send(item) + + +class BufferedConnectable(ByteStreamConnectable): + def __init__(self, connectable: AnyByteStreamConnectable): + """ + :param connectable: the connectable to wrap + + """ + self.connectable = connectable + + @override + async def connect(self) -> BufferedByteStream: + stream = await self.connectable.connect() + return BufferedByteStream(stream) diff --git a/venv/lib/python3.12/site-packages/anyio/streams/file.py b/venv/lib/python3.12/site-packages/anyio/streams/file.py new file mode 100644 index 0000000..79c3d50 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/streams/file.py @@ -0,0 +1,154 @@ +from __future__ import annotations + +__all__ = ( + "FileReadStream", + "FileStreamAttribute", + "FileWriteStream", +) + +from collections.abc import Callable, Mapping +from io import SEEK_SET, UnsupportedOperation +from os import PathLike +from pathlib import Path +from typing import IO, Any + +from .. import ( + BrokenResourceError, + ClosedResourceError, + EndOfStream, + TypedAttributeSet, + to_thread, + typed_attribute, +) +from ..abc import ByteReceiveStream, ByteSendStream + + +class FileStreamAttribute(TypedAttributeSet): + #: the open file descriptor + file: IO[bytes] = typed_attribute() + #: the path of the file on the file system, if available (file must be a real file) + path: Path = typed_attribute() + #: the file number, if available (file must be a real file or a TTY) + fileno: int = typed_attribute() + + +class _BaseFileStream: + def __init__(self, file: IO[bytes]): + self._file = file + + async def aclose(self) -> None: + await to_thread.run_sync(self._file.close) + + @property + def extra_attributes(self) -> Mapping[Any, Callable[[], Any]]: + attributes: dict[Any, Callable[[], Any]] = { + FileStreamAttribute.file: lambda: self._file, + } + + if hasattr(self._file, "name"): + attributes[FileStreamAttribute.path] = lambda: Path(self._file.name) + + try: + self._file.fileno() + except UnsupportedOperation: + pass + else: + attributes[FileStreamAttribute.fileno] = lambda: self._file.fileno() + + return attributes + + +class FileReadStream(_BaseFileStream, ByteReceiveStream): + """ + A byte stream that reads from a file in the file system. + + :param file: a file that has been opened for reading in binary mode + + .. versionadded:: 3.0 + """ + + @classmethod + async def from_path(cls, path: str | PathLike[str]) -> FileReadStream: + """ + Create a file read stream by opening the given file. + + :param path: path of the file to read from + + """ + file = await to_thread.run_sync(Path(path).open, "rb") + return cls(file) + + async def receive(self, max_bytes: int = 65536) -> bytes: + try: + data = await to_thread.run_sync(self._file.read, max_bytes) + except ValueError: + raise ClosedResourceError from None + except OSError as exc: + raise BrokenResourceError from exc + + if data: + return data + else: + raise EndOfStream + + async def seek(self, position: int, whence: int = SEEK_SET) -> int: + """ + Seek the file to the given position. + + .. seealso:: :meth:`io.IOBase.seek` + + .. note:: Not all file descriptors are seekable. + + :param position: position to seek the file to + :param whence: controls how ``position`` is interpreted + :return: the new absolute position + :raises OSError: if the file is not seekable + + """ + return await to_thread.run_sync(self._file.seek, position, whence) + + async def tell(self) -> int: + """ + Return the current stream position. + + .. note:: Not all file descriptors are seekable. + + :return: the current absolute position + :raises OSError: if the file is not seekable + + """ + return await to_thread.run_sync(self._file.tell) + + +class FileWriteStream(_BaseFileStream, ByteSendStream): + """ + A byte stream that writes to a file in the file system. + + :param file: a file that has been opened for writing in binary mode + + .. versionadded:: 3.0 + """ + + @classmethod + async def from_path( + cls, path: str | PathLike[str], append: bool = False + ) -> FileWriteStream: + """ + Create a file write stream by opening the given file for writing. + + :param path: path of the file to write to + :param append: if ``True``, open the file for appending; if ``False``, any + existing file at the given path will be truncated + + """ + mode = "ab" if append else "wb" + file = await to_thread.run_sync(Path(path).open, mode) + return cls(file) + + async def send(self, item: bytes) -> None: + try: + await to_thread.run_sync(self._file.write, item) + except ValueError: + raise ClosedResourceError from None + except OSError as exc: + raise BrokenResourceError from exc diff --git a/venv/lib/python3.12/site-packages/anyio/streams/memory.py b/venv/lib/python3.12/site-packages/anyio/streams/memory.py new file mode 100644 index 0000000..a3fa0c3 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/streams/memory.py @@ -0,0 +1,325 @@ +from __future__ import annotations + +__all__ = ( + "MemoryObjectReceiveStream", + "MemoryObjectSendStream", + "MemoryObjectStreamStatistics", +) + +import warnings +from collections import OrderedDict, deque +from dataclasses import dataclass, field +from types import TracebackType +from typing import Generic, NamedTuple, TypeVar + +from .. import ( + BrokenResourceError, + ClosedResourceError, + EndOfStream, + WouldBlock, +) +from .._core._testing import TaskInfo, get_current_task +from ..abc import Event, ObjectReceiveStream, ObjectSendStream +from ..lowlevel import checkpoint + +T_Item = TypeVar("T_Item") +T_co = TypeVar("T_co", covariant=True) +T_contra = TypeVar("T_contra", contravariant=True) + + +class MemoryObjectStreamStatistics(NamedTuple): + current_buffer_used: int #: number of items stored in the buffer + #: maximum number of items that can be stored on this stream (or :data:`math.inf`) + max_buffer_size: float + open_send_streams: int #: number of unclosed clones of the send stream + open_receive_streams: int #: number of unclosed clones of the receive stream + #: number of tasks blocked on :meth:`MemoryObjectSendStream.send` + tasks_waiting_send: int + #: number of tasks blocked on :meth:`MemoryObjectReceiveStream.receive` + tasks_waiting_receive: int + + +@dataclass(eq=False) +class _MemoryObjectItemReceiver(Generic[T_Item]): + task_info: TaskInfo = field(init=False, default_factory=get_current_task) + item: T_Item = field(init=False) + + def __repr__(self) -> str: + # When item is not defined, we get following error with default __repr__: + # AttributeError: 'MemoryObjectItemReceiver' object has no attribute 'item' + item = getattr(self, "item", None) + return f"{self.__class__.__name__}(task_info={self.task_info}, item={item!r})" + + +@dataclass(eq=False) +class _MemoryObjectStreamState(Generic[T_Item]): + max_buffer_size: float = field() + buffer: deque[T_Item] = field(init=False, default_factory=deque) + open_send_channels: int = field(init=False, default=0) + open_receive_channels: int = field(init=False, default=0) + waiting_receivers: OrderedDict[Event, _MemoryObjectItemReceiver[T_Item]] = field( + init=False, default_factory=OrderedDict + ) + waiting_senders: OrderedDict[Event, T_Item] = field( + init=False, default_factory=OrderedDict + ) + + def statistics(self) -> MemoryObjectStreamStatistics: + return MemoryObjectStreamStatistics( + len(self.buffer), + self.max_buffer_size, + self.open_send_channels, + self.open_receive_channels, + len(self.waiting_senders), + len(self.waiting_receivers), + ) + + +@dataclass(eq=False) +class MemoryObjectReceiveStream(Generic[T_co], ObjectReceiveStream[T_co]): + _state: _MemoryObjectStreamState[T_co] + _closed: bool = field(init=False, default=False) + + def __post_init__(self) -> None: + self._state.open_receive_channels += 1 + + def receive_nowait(self) -> T_co: + """ + Receive the next item if it can be done without waiting. + + :return: the received item + :raises ~anyio.ClosedResourceError: if this send stream has been closed + :raises ~anyio.EndOfStream: if the buffer is empty and this stream has been + closed from the sending end + :raises ~anyio.WouldBlock: if there are no items in the buffer and no tasks + waiting to send + + """ + if self._closed: + raise ClosedResourceError + + if self._state.waiting_senders: + # Get the item from the next sender + send_event, item = self._state.waiting_senders.popitem(last=False) + self._state.buffer.append(item) + send_event.set() + + if self._state.buffer: + return self._state.buffer.popleft() + elif not self._state.open_send_channels: + raise EndOfStream + + raise WouldBlock + + async def receive(self) -> T_co: + await checkpoint() + try: + return self.receive_nowait() + except WouldBlock: + # Add ourselves in the queue + receive_event = Event() + receiver = _MemoryObjectItemReceiver[T_co]() + self._state.waiting_receivers[receive_event] = receiver + + try: + await receive_event.wait() + finally: + self._state.waiting_receivers.pop(receive_event, None) + + try: + return receiver.item + except AttributeError: + raise EndOfStream from None + + def clone(self) -> MemoryObjectReceiveStream[T_co]: + """ + Create a clone of this receive stream. + + Each clone can be closed separately. Only when all clones have been closed will + the receiving end of the memory stream be considered closed by the sending ends. + + :return: the cloned stream + + """ + if self._closed: + raise ClosedResourceError + + return MemoryObjectReceiveStream(_state=self._state) + + def close(self) -> None: + """ + Close the stream. + + This works the exact same way as :meth:`aclose`, but is provided as a special + case for the benefit of synchronous callbacks. + + """ + if not self._closed: + self._closed = True + self._state.open_receive_channels -= 1 + if self._state.open_receive_channels == 0: + send_events = list(self._state.waiting_senders.keys()) + for event in send_events: + event.set() + + async def aclose(self) -> None: + self.close() + + def statistics(self) -> MemoryObjectStreamStatistics: + """ + Return statistics about the current state of this stream. + + .. versionadded:: 3.0 + """ + return self._state.statistics() + + def __enter__(self) -> MemoryObjectReceiveStream[T_co]: + return self + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: + self.close() + + def __del__(self) -> None: + if not self._closed: + warnings.warn( + f"Unclosed <{self.__class__.__name__} at {id(self):x}>", + ResourceWarning, + stacklevel=1, + source=self, + ) + + +@dataclass(eq=False) +class MemoryObjectSendStream(Generic[T_contra], ObjectSendStream[T_contra]): + _state: _MemoryObjectStreamState[T_contra] + _closed: bool = field(init=False, default=False) + + def __post_init__(self) -> None: + self._state.open_send_channels += 1 + + def send_nowait(self, item: T_contra) -> None: + """ + Send an item immediately if it can be done without waiting. + + :param item: the item to send + :raises ~anyio.ClosedResourceError: if this send stream has been closed + :raises ~anyio.BrokenResourceError: if the stream has been closed from the + receiving end + :raises ~anyio.WouldBlock: if the buffer is full and there are no tasks waiting + to receive + + """ + if self._closed: + raise ClosedResourceError + if not self._state.open_receive_channels: + raise BrokenResourceError + + while self._state.waiting_receivers: + receive_event, receiver = self._state.waiting_receivers.popitem(last=False) + if not receiver.task_info.has_pending_cancellation(): + receiver.item = item + receive_event.set() + return + + if len(self._state.buffer) < self._state.max_buffer_size: + self._state.buffer.append(item) + else: + raise WouldBlock + + async def send(self, item: T_contra) -> None: + """ + Send an item to the stream. + + If the buffer is full, this method blocks until there is again room in the + buffer or the item can be sent directly to a receiver. + + :param item: the item to send + :raises ~anyio.ClosedResourceError: if this send stream has been closed + :raises ~anyio.BrokenResourceError: if the stream has been closed from the + receiving end + + """ + await checkpoint() + try: + self.send_nowait(item) + except WouldBlock: + # Wait until there's someone on the receiving end + send_event = Event() + self._state.waiting_senders[send_event] = item + try: + await send_event.wait() + except BaseException: + self._state.waiting_senders.pop(send_event, None) + raise + + if send_event in self._state.waiting_senders: + del self._state.waiting_senders[send_event] + raise BrokenResourceError from None + + def clone(self) -> MemoryObjectSendStream[T_contra]: + """ + Create a clone of this send stream. + + Each clone can be closed separately. Only when all clones have been closed will + the sending end of the memory stream be considered closed by the receiving ends. + + :return: the cloned stream + + """ + if self._closed: + raise ClosedResourceError + + return MemoryObjectSendStream(_state=self._state) + + def close(self) -> None: + """ + Close the stream. + + This works the exact same way as :meth:`aclose`, but is provided as a special + case for the benefit of synchronous callbacks. + + """ + if not self._closed: + self._closed = True + self._state.open_send_channels -= 1 + if self._state.open_send_channels == 0: + receive_events = list(self._state.waiting_receivers.keys()) + self._state.waiting_receivers.clear() + for event in receive_events: + event.set() + + async def aclose(self) -> None: + self.close() + + def statistics(self) -> MemoryObjectStreamStatistics: + """ + Return statistics about the current state of this stream. + + .. versionadded:: 3.0 + """ + return self._state.statistics() + + def __enter__(self) -> MemoryObjectSendStream[T_contra]: + return self + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: + self.close() + + def __del__(self) -> None: + if not self._closed: + warnings.warn( + f"Unclosed <{self.__class__.__name__} at {id(self):x}>", + ResourceWarning, + stacklevel=1, + source=self, + ) diff --git a/venv/lib/python3.12/site-packages/anyio/streams/stapled.py b/venv/lib/python3.12/site-packages/anyio/streams/stapled.py new file mode 100644 index 0000000..9248b68 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/streams/stapled.py @@ -0,0 +1,147 @@ +from __future__ import annotations + +__all__ = ( + "MultiListener", + "StapledByteStream", + "StapledObjectStream", +) + +from collections.abc import Callable, Mapping, Sequence +from dataclasses import dataclass +from typing import Any, Generic, TypeVar + +from ..abc import ( + ByteReceiveStream, + ByteSendStream, + ByteStream, + Listener, + ObjectReceiveStream, + ObjectSendStream, + ObjectStream, + TaskGroup, +) + +T_Item = TypeVar("T_Item") +T_Stream = TypeVar("T_Stream") + + +@dataclass(eq=False) +class StapledByteStream(ByteStream): + """ + Combines two byte streams into a single, bidirectional byte stream. + + Extra attributes will be provided from both streams, with the receive stream + providing the values in case of a conflict. + + :param ByteSendStream send_stream: the sending byte stream + :param ByteReceiveStream receive_stream: the receiving byte stream + """ + + send_stream: ByteSendStream + receive_stream: ByteReceiveStream + + async def receive(self, max_bytes: int = 65536) -> bytes: + return await self.receive_stream.receive(max_bytes) + + async def send(self, item: bytes) -> None: + await self.send_stream.send(item) + + async def send_eof(self) -> None: + await self.send_stream.aclose() + + async def aclose(self) -> None: + await self.send_stream.aclose() + await self.receive_stream.aclose() + + @property + def extra_attributes(self) -> Mapping[Any, Callable[[], Any]]: + return { + **self.send_stream.extra_attributes, + **self.receive_stream.extra_attributes, + } + + +@dataclass(eq=False) +class StapledObjectStream(Generic[T_Item], ObjectStream[T_Item]): + """ + Combines two object streams into a single, bidirectional object stream. + + Extra attributes will be provided from both streams, with the receive stream + providing the values in case of a conflict. + + :param ObjectSendStream send_stream: the sending object stream + :param ObjectReceiveStream receive_stream: the receiving object stream + """ + + send_stream: ObjectSendStream[T_Item] + receive_stream: ObjectReceiveStream[T_Item] + + async def receive(self) -> T_Item: + return await self.receive_stream.receive() + + async def send(self, item: T_Item) -> None: + await self.send_stream.send(item) + + async def send_eof(self) -> None: + await self.send_stream.aclose() + + async def aclose(self) -> None: + await self.send_stream.aclose() + await self.receive_stream.aclose() + + @property + def extra_attributes(self) -> Mapping[Any, Callable[[], Any]]: + return { + **self.send_stream.extra_attributes, + **self.receive_stream.extra_attributes, + } + + +@dataclass(eq=False) +class MultiListener(Generic[T_Stream], Listener[T_Stream]): + """ + Combines multiple listeners into one, serving connections from all of them at once. + + Any MultiListeners in the given collection of listeners will have their listeners + moved into this one. + + Extra attributes are provided from each listener, with each successive listener + overriding any conflicting attributes from the previous one. + + :param listeners: listeners to serve + :type listeners: Sequence[Listener[T_Stream]] + """ + + listeners: Sequence[Listener[T_Stream]] + + def __post_init__(self) -> None: + listeners: list[Listener[T_Stream]] = [] + for listener in self.listeners: + if isinstance(listener, MultiListener): + listeners.extend(listener.listeners) + del listener.listeners[:] # type: ignore[attr-defined] + else: + listeners.append(listener) + + self.listeners = listeners + + async def serve( + self, handler: Callable[[T_Stream], Any], task_group: TaskGroup | None = None + ) -> None: + from .. import create_task_group + + async with create_task_group() as tg: + for listener in self.listeners: + tg.start_soon(listener.serve, handler, task_group) + + async def aclose(self) -> None: + for listener in self.listeners: + await listener.aclose() + + @property + def extra_attributes(self) -> Mapping[Any, Callable[[], Any]]: + attributes: dict = {} + for listener in self.listeners: + attributes.update(listener.extra_attributes) + + return attributes diff --git a/venv/lib/python3.12/site-packages/anyio/streams/text.py b/venv/lib/python3.12/site-packages/anyio/streams/text.py new file mode 100644 index 0000000..296cd25 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/streams/text.py @@ -0,0 +1,176 @@ +from __future__ import annotations + +__all__ = ( + "TextConnectable", + "TextReceiveStream", + "TextSendStream", + "TextStream", +) + +import codecs +import sys +from collections.abc import Callable, Mapping +from dataclasses import InitVar, dataclass, field +from typing import Any + +from ..abc import ( + AnyByteReceiveStream, + AnyByteSendStream, + AnyByteStream, + AnyByteStreamConnectable, + ObjectReceiveStream, + ObjectSendStream, + ObjectStream, + ObjectStreamConnectable, +) + +if sys.version_info >= (3, 12): + from typing import override +else: + from typing_extensions import override + + +@dataclass(eq=False) +class TextReceiveStream(ObjectReceiveStream[str]): + """ + Stream wrapper that decodes bytes to strings using the given encoding. + + Decoding is done using :class:`~codecs.IncrementalDecoder` which returns any + completely received unicode characters as soon as they come in. + + :param transport_stream: any bytes-based receive stream + :param encoding: character encoding to use for decoding bytes to strings (defaults + to ``utf-8``) + :param errors: handling scheme for decoding errors (defaults to ``strict``; see the + `codecs module documentation`_ for a comprehensive list of options) + + .. _codecs module documentation: + https://docs.python.org/3/library/codecs.html#codec-objects + """ + + transport_stream: AnyByteReceiveStream + encoding: InitVar[str] = "utf-8" + errors: InitVar[str] = "strict" + _decoder: codecs.IncrementalDecoder = field(init=False) + + def __post_init__(self, encoding: str, errors: str) -> None: + decoder_class = codecs.getincrementaldecoder(encoding) + self._decoder = decoder_class(errors=errors) + + async def receive(self) -> str: + while True: + chunk = await self.transport_stream.receive() + decoded = self._decoder.decode(chunk) + if decoded: + return decoded + + async def aclose(self) -> None: + await self.transport_stream.aclose() + self._decoder.reset() + + @property + def extra_attributes(self) -> Mapping[Any, Callable[[], Any]]: + return self.transport_stream.extra_attributes + + +@dataclass(eq=False) +class TextSendStream(ObjectSendStream[str]): + """ + Sends strings to the wrapped stream as bytes using the given encoding. + + :param AnyByteSendStream transport_stream: any bytes-based send stream + :param str encoding: character encoding to use for encoding strings to bytes + (defaults to ``utf-8``) + :param str errors: handling scheme for encoding errors (defaults to ``strict``; see + the `codecs module documentation`_ for a comprehensive list of options) + + .. _codecs module documentation: + https://docs.python.org/3/library/codecs.html#codec-objects + """ + + transport_stream: AnyByteSendStream + encoding: InitVar[str] = "utf-8" + errors: str = "strict" + _encoder: Callable[..., tuple[bytes, int]] = field(init=False) + + def __post_init__(self, encoding: str) -> None: + self._encoder = codecs.getencoder(encoding) + + async def send(self, item: str) -> None: + encoded = self._encoder(item, self.errors)[0] + await self.transport_stream.send(encoded) + + async def aclose(self) -> None: + await self.transport_stream.aclose() + + @property + def extra_attributes(self) -> Mapping[Any, Callable[[], Any]]: + return self.transport_stream.extra_attributes + + +@dataclass(eq=False) +class TextStream(ObjectStream[str]): + """ + A bidirectional stream that decodes bytes to strings on receive and encodes strings + to bytes on send. + + Extra attributes will be provided from both streams, with the receive stream + providing the values in case of a conflict. + + :param AnyByteStream transport_stream: any bytes-based stream + :param str encoding: character encoding to use for encoding/decoding strings to/from + bytes (defaults to ``utf-8``) + :param str errors: handling scheme for encoding errors (defaults to ``strict``; see + the `codecs module documentation`_ for a comprehensive list of options) + + .. _codecs module documentation: + https://docs.python.org/3/library/codecs.html#codec-objects + """ + + transport_stream: AnyByteStream + encoding: InitVar[str] = "utf-8" + errors: InitVar[str] = "strict" + _receive_stream: TextReceiveStream = field(init=False) + _send_stream: TextSendStream = field(init=False) + + def __post_init__(self, encoding: str, errors: str) -> None: + self._receive_stream = TextReceiveStream( + self.transport_stream, encoding=encoding, errors=errors + ) + self._send_stream = TextSendStream( + self.transport_stream, encoding=encoding, errors=errors + ) + + async def receive(self) -> str: + return await self._receive_stream.receive() + + async def send(self, item: str) -> None: + await self._send_stream.send(item) + + async def send_eof(self) -> None: + await self.transport_stream.send_eof() + + async def aclose(self) -> None: + await self._send_stream.aclose() + await self._receive_stream.aclose() + + @property + def extra_attributes(self) -> Mapping[Any, Callable[[], Any]]: + return { + **self._send_stream.extra_attributes, + **self._receive_stream.extra_attributes, + } + + +class TextConnectable(ObjectStreamConnectable[str]): + def __init__(self, connectable: AnyByteStreamConnectable): + """ + :param connectable: the bytestream endpoint to wrap + + """ + self.connectable = connectable + + @override + async def connect(self) -> TextStream: + stream = await self.connectable.connect() + return TextStream(stream) diff --git a/venv/lib/python3.12/site-packages/anyio/streams/tls.py b/venv/lib/python3.12/site-packages/anyio/streams/tls.py new file mode 100644 index 0000000..e2a7ca5 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/streams/tls.py @@ -0,0 +1,421 @@ +from __future__ import annotations + +__all__ = ( + "TLSAttribute", + "TLSConnectable", + "TLSListener", + "TLSStream", +) + +import logging +import re +import ssl +import sys +from collections.abc import Callable, Mapping +from dataclasses import dataclass +from functools import wraps +from ssl import SSLContext +from typing import Any, TypeAlias, TypeVar + +from .. import ( + BrokenResourceError, + EndOfStream, + aclose_forcefully, + get_cancelled_exc_class, + to_thread, +) +from .._core._typedattr import TypedAttributeSet, typed_attribute +from ..abc import ( + AnyByteStream, + AnyByteStreamConnectable, + ByteStream, + ByteStreamConnectable, + Listener, + TaskGroup, +) + +if sys.version_info >= (3, 11): + from typing import TypeVarTuple, Unpack +else: + from typing_extensions import TypeVarTuple, Unpack + +if sys.version_info >= (3, 12): + from typing import override +else: + from typing_extensions import override + +T_Retval = TypeVar("T_Retval") +PosArgsT = TypeVarTuple("PosArgsT") +_PCTRTT: TypeAlias = tuple[tuple[str, str], ...] +_PCTRTTT: TypeAlias = tuple[_PCTRTT, ...] + + +class TLSAttribute(TypedAttributeSet): + """Contains Transport Layer Security related attributes.""" + + #: the selected ALPN protocol + alpn_protocol: str | None = typed_attribute() + #: the channel binding for type ``tls-unique`` + channel_binding_tls_unique: bytes = typed_attribute() + #: the selected cipher + cipher: tuple[str, str, int] = typed_attribute() + #: the peer certificate in dictionary form (see :meth:`ssl.SSLSocket.getpeercert` + # for more information) + peer_certificate: None | (dict[str, str | _PCTRTTT | _PCTRTT]) = typed_attribute() + #: the peer certificate in binary form + peer_certificate_binary: bytes | None = typed_attribute() + #: ``True`` if this is the server side of the connection + server_side: bool = typed_attribute() + #: ciphers shared by the client during the TLS handshake (``None`` if this is the + #: client side) + shared_ciphers: list[tuple[str, str, int]] | None = typed_attribute() + #: the :class:`~ssl.SSLObject` used for encryption + ssl_object: ssl.SSLObject = typed_attribute() + #: ``True`` if this stream does (and expects) a closing TLS handshake when the + #: stream is being closed + standard_compatible: bool = typed_attribute() + #: the TLS protocol version (e.g. ``TLSv1.2``) + tls_version: str = typed_attribute() + + +@dataclass(eq=False) +class TLSStream(ByteStream): + """ + A stream wrapper that encrypts all sent data and decrypts received data. + + This class has no public initializer; use :meth:`wrap` instead. + All extra attributes from :class:`~TLSAttribute` are supported. + + :var AnyByteStream transport_stream: the wrapped stream + + """ + + transport_stream: AnyByteStream + standard_compatible: bool + _ssl_object: ssl.SSLObject + _read_bio: ssl.MemoryBIO + _write_bio: ssl.MemoryBIO + + @classmethod + async def wrap( + cls, + transport_stream: AnyByteStream, + *, + server_side: bool | None = None, + hostname: str | None = None, + ssl_context: ssl.SSLContext | None = None, + standard_compatible: bool = True, + ) -> TLSStream: + """ + Wrap an existing stream with Transport Layer Security. + + This performs a TLS handshake with the peer. + + :param transport_stream: a bytes-transporting stream to wrap + :param server_side: ``True`` if this is the server side of the connection, + ``False`` if this is the client side (if omitted, will be set to ``False`` + if ``hostname`` has been provided, ``False`` otherwise). Used only to create + a default context when an explicit context has not been provided. + :param hostname: host name of the peer (if host name checking is desired) + :param ssl_context: the SSLContext object to use (if not provided, a secure + default will be created) + :param standard_compatible: if ``False``, skip the closing handshake when + closing the connection, and don't raise an exception if the peer does the + same + :raises ~ssl.SSLError: if the TLS handshake fails + + """ + if server_side is None: + server_side = not hostname + + if not ssl_context: + purpose = ( + ssl.Purpose.CLIENT_AUTH if server_side else ssl.Purpose.SERVER_AUTH + ) + ssl_context = ssl.create_default_context(purpose) + + # Re-enable detection of unexpected EOFs if it was disabled by Python + if hasattr(ssl, "OP_IGNORE_UNEXPECTED_EOF"): + ssl_context.options &= ~ssl.OP_IGNORE_UNEXPECTED_EOF + + bio_in = ssl.MemoryBIO() + bio_out = ssl.MemoryBIO() + + # External SSLContext implementations may do blocking I/O in wrap_bio(), + # but the standard library implementation won't + if type(ssl_context) is ssl.SSLContext: + ssl_object = ssl_context.wrap_bio( + bio_in, bio_out, server_side=server_side, server_hostname=hostname + ) + else: + ssl_object = await to_thread.run_sync( + ssl_context.wrap_bio, + bio_in, + bio_out, + server_side, + hostname, + None, + ) + + wrapper = cls( + transport_stream=transport_stream, + standard_compatible=standard_compatible, + _ssl_object=ssl_object, + _read_bio=bio_in, + _write_bio=bio_out, + ) + await wrapper._call_sslobject_method(ssl_object.do_handshake) + return wrapper + + async def _call_sslobject_method( + self, func: Callable[[Unpack[PosArgsT]], T_Retval], *args: Unpack[PosArgsT] + ) -> T_Retval: + while True: + try: + result = func(*args) + except ssl.SSLWantReadError: + try: + # Flush any pending writes first + if self._write_bio.pending: + await self.transport_stream.send(self._write_bio.read()) + + data = await self.transport_stream.receive() + except EndOfStream: + self._read_bio.write_eof() + except OSError as exc: + self._read_bio.write_eof() + self._write_bio.write_eof() + raise BrokenResourceError from exc + else: + self._read_bio.write(data) + except ssl.SSLWantWriteError: + await self.transport_stream.send(self._write_bio.read()) + except ssl.SSLSyscallError as exc: + self._read_bio.write_eof() + self._write_bio.write_eof() + raise BrokenResourceError from exc + except ssl.SSLError as exc: + self._read_bio.write_eof() + self._write_bio.write_eof() + if isinstance(exc, ssl.SSLEOFError) or ( + exc.strerror and "UNEXPECTED_EOF_WHILE_READING" in exc.strerror + ): + if self.standard_compatible: + raise BrokenResourceError from exc + else: + raise EndOfStream from None + + raise + else: + # Flush any pending writes first + if self._write_bio.pending: + await self.transport_stream.send(self._write_bio.read()) + + return result + + async def unwrap(self) -> tuple[AnyByteStream, bytes]: + """ + Does the TLS closing handshake. + + :return: a tuple of (wrapped byte stream, bytes left in the read buffer) + + """ + await self._call_sslobject_method(self._ssl_object.unwrap) + self._read_bio.write_eof() + self._write_bio.write_eof() + return self.transport_stream, self._read_bio.read() + + async def aclose(self) -> None: + if self.standard_compatible: + try: + await self.unwrap() + except BaseException: + await aclose_forcefully(self.transport_stream) + raise + + await self.transport_stream.aclose() + + async def receive(self, max_bytes: int = 65536) -> bytes: + data = await self._call_sslobject_method(self._ssl_object.read, max_bytes) + if not data: + raise EndOfStream + + return data + + async def send(self, item: bytes) -> None: + await self._call_sslobject_method(self._ssl_object.write, item) + + async def send_eof(self) -> None: + tls_version = self.extra(TLSAttribute.tls_version) + match = re.match(r"TLSv(\d+)(?:\.(\d+))?", tls_version) + if match: + major, minor = int(match.group(1)), int(match.group(2) or 0) + if (major, minor) < (1, 3): + raise NotImplementedError( + f"send_eof() requires at least TLSv1.3; current " + f"session uses {tls_version}" + ) + + raise NotImplementedError( + "send_eof() has not yet been implemented for TLS streams" + ) + + @property + def extra_attributes(self) -> Mapping[Any, Callable[[], Any]]: + return { + **self.transport_stream.extra_attributes, + TLSAttribute.alpn_protocol: self._ssl_object.selected_alpn_protocol, + TLSAttribute.channel_binding_tls_unique: ( + self._ssl_object.get_channel_binding + ), + TLSAttribute.cipher: self._ssl_object.cipher, + TLSAttribute.peer_certificate: lambda: self._ssl_object.getpeercert(False), + TLSAttribute.peer_certificate_binary: lambda: self._ssl_object.getpeercert( + True + ), + TLSAttribute.server_side: lambda: self._ssl_object.server_side, + TLSAttribute.shared_ciphers: lambda: ( + self._ssl_object.shared_ciphers() + if self._ssl_object.server_side + else None + ), + TLSAttribute.standard_compatible: lambda: self.standard_compatible, + TLSAttribute.ssl_object: lambda: self._ssl_object, + TLSAttribute.tls_version: self._ssl_object.version, + } + + +@dataclass(eq=False) +class TLSListener(Listener[TLSStream]): + """ + A convenience listener that wraps another listener and auto-negotiates a TLS session + on every accepted connection. + + If the TLS handshake times out or raises an exception, + :meth:`handle_handshake_error` is called to do whatever post-mortem processing is + deemed necessary. + + Supports only the :attr:`~TLSAttribute.standard_compatible` extra attribute. + + :param Listener listener: the listener to wrap + :param ssl_context: the SSL context object + :param standard_compatible: a flag passed through to :meth:`TLSStream.wrap` + :param handshake_timeout: time limit for the TLS handshake + (passed to :func:`~anyio.fail_after`) + """ + + listener: Listener[Any] + ssl_context: ssl.SSLContext + standard_compatible: bool = True + handshake_timeout: float = 30 + + @staticmethod + async def handle_handshake_error(exc: BaseException, stream: AnyByteStream) -> None: + """ + Handle an exception raised during the TLS handshake. + + This method does 3 things: + + #. Forcefully closes the original stream + #. Logs the exception (unless it was a cancellation exception) using the + ``anyio.streams.tls`` logger + #. Reraises the exception if it was a base exception or a cancellation exception + + :param exc: the exception + :param stream: the original stream + + """ + await aclose_forcefully(stream) + + # Log all except cancellation exceptions + if not isinstance(exc, get_cancelled_exc_class()): + # CPython (as of 3.11.5) returns incorrect `sys.exc_info()` here when using + # any asyncio implementation, so we explicitly pass the exception to log + # (https://github.com/python/cpython/issues/108668). Trio does not have this + # issue because it works around the CPython bug. + logging.getLogger(__name__).exception( + "Error during TLS handshake", exc_info=exc + ) + + # Only reraise base exceptions and cancellation exceptions + if not isinstance(exc, Exception) or isinstance(exc, get_cancelled_exc_class()): + raise + + async def serve( + self, + handler: Callable[[TLSStream], Any], + task_group: TaskGroup | None = None, + ) -> None: + @wraps(handler) + async def handler_wrapper(stream: AnyByteStream) -> None: + from .. import fail_after + + try: + with fail_after(self.handshake_timeout): + wrapped_stream = await TLSStream.wrap( + stream, + ssl_context=self.ssl_context, + standard_compatible=self.standard_compatible, + ) + except BaseException as exc: + await self.handle_handshake_error(exc, stream) + else: + await handler(wrapped_stream) + + await self.listener.serve(handler_wrapper, task_group) + + async def aclose(self) -> None: + await self.listener.aclose() + + @property + def extra_attributes(self) -> Mapping[Any, Callable[[], Any]]: + return { + TLSAttribute.standard_compatible: lambda: self.standard_compatible, + } + + +class TLSConnectable(ByteStreamConnectable): + """ + Wraps another connectable and does TLS negotiation after a successful connection. + + :param connectable: the connectable to wrap + :param hostname: host name of the server (if host name checking is desired) + :param ssl_context: the SSLContext object to use (if not provided, a secure default + will be created) + :param standard_compatible: if ``False``, skip the closing handshake when closing + the connection, and don't raise an exception if the server does the same + """ + + def __init__( + self, + connectable: AnyByteStreamConnectable, + *, + hostname: str | None = None, + ssl_context: ssl.SSLContext | None = None, + standard_compatible: bool = True, + ) -> None: + self.connectable = connectable + self.ssl_context: SSLContext = ssl_context or ssl.create_default_context( + ssl.Purpose.SERVER_AUTH + ) + if not isinstance(self.ssl_context, ssl.SSLContext): + raise TypeError( + "ssl_context must be an instance of ssl.SSLContext, not " + f"{type(self.ssl_context).__name__}" + ) + self.hostname = hostname + self.standard_compatible = standard_compatible + + @override + async def connect(self) -> TLSStream: + stream = await self.connectable.connect() + try: + return await TLSStream.wrap( + stream, + hostname=self.hostname, + ssl_context=self.ssl_context, + standard_compatible=self.standard_compatible, + ) + except BaseException: + await aclose_forcefully(stream) + raise diff --git a/venv/lib/python3.12/site-packages/anyio/to_interpreter.py b/venv/lib/python3.12/site-packages/anyio/to_interpreter.py new file mode 100644 index 0000000..694dbe7 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/to_interpreter.py @@ -0,0 +1,246 @@ +from __future__ import annotations + +__all__ = ( + "run_sync", + "current_default_interpreter_limiter", +) + +import atexit +import os +import sys +from collections import deque +from collections.abc import Callable +from typing import Any, Final, TypeVar + +from . import current_time, to_thread +from ._core._exceptions import BrokenWorkerInterpreter +from ._core._synchronization import CapacityLimiter +from .lowlevel import RunVar + +if sys.version_info >= (3, 11): + from typing import TypeVarTuple, Unpack +else: + from typing_extensions import TypeVarTuple, Unpack + +if sys.version_info >= (3, 14): + from concurrent.interpreters import ExecutionFailed, create + + def _interp_call( + func: Callable[..., Any], args: tuple[Any, ...] + ) -> tuple[Any, bool]: + try: + retval = func(*args) + except BaseException as exc: + return exc, True + else: + return retval, False + + class _Worker: + last_used: float = 0 + + def __init__(self) -> None: + self._interpreter = create() + + def destroy(self) -> None: + self._interpreter.close() + + def call( + self, + func: Callable[..., T_Retval], + args: tuple[Any, ...], + ) -> T_Retval: + try: + res, is_exception = self._interpreter.call(_interp_call, func, args) + except ExecutionFailed as exc: + raise BrokenWorkerInterpreter(exc.excinfo) from exc + + if is_exception: + raise res + + return res +elif sys.version_info >= (3, 13): + import _interpqueues + import _interpreters + + UNBOUND: Final = 2 # I have no clue how this works, but it was used in the stdlib + FMT_UNPICKLED: Final = 0 + FMT_PICKLED: Final = 1 + QUEUE_PICKLE_ARGS: Final = (FMT_PICKLED, UNBOUND) + QUEUE_UNPICKLE_ARGS: Final = (FMT_UNPICKLED, UNBOUND) + + _run_func = compile( + """ +import _interpqueues +from _interpreters import NotShareableError +from pickle import loads, dumps, HIGHEST_PROTOCOL + +QUEUE_PICKLE_ARGS = (1, 2) +QUEUE_UNPICKLE_ARGS = (0, 2) + +item = _interpqueues.get(queue_id)[0] +try: + func, args = loads(item) + retval = func(*args) +except BaseException as exc: + is_exception = True + retval = exc +else: + is_exception = False + +try: + _interpqueues.put(queue_id, (retval, is_exception), *QUEUE_UNPICKLE_ARGS) +except NotShareableError: + retval = dumps(retval, HIGHEST_PROTOCOL) + _interpqueues.put(queue_id, (retval, is_exception), *QUEUE_PICKLE_ARGS) + """, + "", + "exec", + ) + + class _Worker: + last_used: float = 0 + + def __init__(self) -> None: + self._interpreter_id = _interpreters.create() + self._queue_id = _interpqueues.create(1, *QUEUE_UNPICKLE_ARGS) + _interpreters.set___main___attrs( + self._interpreter_id, {"queue_id": self._queue_id} + ) + + def destroy(self) -> None: + _interpqueues.destroy(self._queue_id) + _interpreters.destroy(self._interpreter_id) + + def call( + self, + func: Callable[..., T_Retval], + args: tuple[Any, ...], + ) -> T_Retval: + import pickle + + item = pickle.dumps((func, args), pickle.HIGHEST_PROTOCOL) + _interpqueues.put(self._queue_id, item, *QUEUE_PICKLE_ARGS) + exc_info = _interpreters.exec(self._interpreter_id, _run_func) + if exc_info: + raise BrokenWorkerInterpreter(exc_info) + + res = _interpqueues.get(self._queue_id) + (res, is_exception), fmt = res[:2] + if fmt == FMT_PICKLED: + res = pickle.loads(res) + + if is_exception: + raise res + + return res +else: + + class _Worker: + last_used: float = 0 + + def __init__(self) -> None: + raise RuntimeError("subinterpreters require at least Python 3.13") + + def call( + self, + func: Callable[..., T_Retval], + args: tuple[Any, ...], + ) -> T_Retval: + raise NotImplementedError + + def destroy(self) -> None: + pass + + +DEFAULT_CPU_COUNT: Final = 8 # this is just an arbitrarily selected value +MAX_WORKER_IDLE_TIME = ( + 30 # seconds a subinterpreter can be idle before becoming eligible for pruning +) + +T_Retval = TypeVar("T_Retval") +PosArgsT = TypeVarTuple("PosArgsT") + +_idle_workers = RunVar[deque[_Worker]]("_available_workers") +_default_interpreter_limiter = RunVar[CapacityLimiter]("_default_interpreter_limiter") + + +def _stop_workers(workers: deque[_Worker]) -> None: + for worker in workers: + worker.destroy() + + workers.clear() + + +async def run_sync( + func: Callable[[Unpack[PosArgsT]], T_Retval], + *args: Unpack[PosArgsT], + limiter: CapacityLimiter | None = None, +) -> T_Retval: + """ + Call the given function with the given arguments in a subinterpreter. + + .. warning:: On Python 3.13, the :mod:`concurrent.interpreters` module was not yet + available, so the code path for that Python version relies on an undocumented, + private API. As such, it is recommended to not rely on this function for anything + mission-critical on Python 3.13. + + :param func: a callable + :param args: the positional arguments for the callable + :param limiter: capacity limiter to use to limit the total number of subinterpreters + running (if omitted, the default limiter is used) + :return: the result of the call + :raises BrokenWorkerInterpreter: if there's an internal error in a subinterpreter + + """ + if limiter is None: + limiter = current_default_interpreter_limiter() + + try: + idle_workers = _idle_workers.get() + except LookupError: + idle_workers = deque() + _idle_workers.set(idle_workers) + atexit.register(_stop_workers, idle_workers) + + async with limiter: + try: + worker = idle_workers.pop() + except IndexError: + worker = _Worker() + + try: + return await to_thread.run_sync( + worker.call, + func, + args, + limiter=limiter, + ) + finally: + # Prune workers that have been idle for too long + now = current_time() + while idle_workers: + if now - idle_workers[0].last_used <= MAX_WORKER_IDLE_TIME: + break + + await to_thread.run_sync(idle_workers.popleft().destroy, limiter=limiter) + + worker.last_used = current_time() + idle_workers.append(worker) + + +def current_default_interpreter_limiter() -> CapacityLimiter: + """ + Return the capacity limiter used by default to limit the number of concurrently + running subinterpreters. + + Defaults to the number of CPU cores. + + :return: a capacity limiter object + + """ + try: + return _default_interpreter_limiter.get() + except LookupError: + limiter = CapacityLimiter(os.cpu_count() or DEFAULT_CPU_COUNT) + _default_interpreter_limiter.set(limiter) + return limiter diff --git a/venv/lib/python3.12/site-packages/anyio/to_process.py b/venv/lib/python3.12/site-packages/anyio/to_process.py new file mode 100644 index 0000000..b289234 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/to_process.py @@ -0,0 +1,266 @@ +from __future__ import annotations + +__all__ = ( + "current_default_process_limiter", + "process_worker", + "run_sync", +) + +import os +import pickle +import subprocess +import sys +from collections import deque +from collections.abc import Callable +from importlib.util import module_from_spec, spec_from_file_location +from typing import TypeVar, cast + +from ._core._eventloop import current_time, get_async_backend, get_cancelled_exc_class +from ._core._exceptions import BrokenWorkerProcess +from ._core._subprocesses import open_process +from ._core._synchronization import CapacityLimiter +from ._core._tasks import CancelScope, fail_after +from .abc import ByteReceiveStream, ByteSendStream, Process +from .lowlevel import RunVar, checkpoint_if_cancelled +from .streams.buffered import BufferedByteReceiveStream + +if sys.version_info >= (3, 11): + from typing import TypeVarTuple, Unpack +else: + from typing_extensions import TypeVarTuple, Unpack + +WORKER_MAX_IDLE_TIME = 300 # 5 minutes + +T_Retval = TypeVar("T_Retval") +PosArgsT = TypeVarTuple("PosArgsT") + +_process_pool_workers: RunVar[set[Process]] = RunVar("_process_pool_workers") +_process_pool_idle_workers: RunVar[deque[tuple[Process, float]]] = RunVar( + "_process_pool_idle_workers" +) +_default_process_limiter: RunVar[CapacityLimiter] = RunVar("_default_process_limiter") + + +async def run_sync( # type: ignore[return] + func: Callable[[Unpack[PosArgsT]], T_Retval], + *args: Unpack[PosArgsT], + cancellable: bool = False, + limiter: CapacityLimiter | None = None, +) -> T_Retval: + """ + Call the given function with the given arguments in a worker process. + + If the ``cancellable`` option is enabled and the task waiting for its completion is + cancelled, the worker process running it will be abruptly terminated using SIGKILL + (or ``terminateProcess()`` on Windows). + + :param func: a callable + :param args: positional arguments for the callable + :param cancellable: ``True`` to allow cancellation of the operation while it's + running + :param limiter: capacity limiter to use to limit the total amount of processes + running (if omitted, the default limiter is used) + :raises NoEventLoopError: if no supported asynchronous event loop is running in the + current thread + :return: an awaitable that yields the return value of the function. + + """ + + async def send_raw_command(pickled_cmd: bytes) -> object: + try: + await stdin.send(pickled_cmd) + response = await buffered.receive_until(b"\n", 50) + status, length = response.split(b" ") + if status not in (b"RETURN", b"EXCEPTION"): + raise RuntimeError( + f"Worker process returned unexpected response: {response!r}" + ) + + pickled_response = await buffered.receive_exactly(int(length)) + except BaseException as exc: + workers.discard(process) + try: + process.kill() + with CancelScope(shield=True): + await process.aclose() + except ProcessLookupError: + pass + + if isinstance(exc, get_cancelled_exc_class()): + raise + else: + raise BrokenWorkerProcess from exc + + retval = pickle.loads(pickled_response) + if status == b"EXCEPTION": + assert isinstance(retval, BaseException) + raise retval + else: + return retval + + # First pickle the request before trying to reserve a worker process + await checkpoint_if_cancelled() + request = pickle.dumps(("run", func, args), protocol=pickle.HIGHEST_PROTOCOL) + + # If this is the first run in this event loop thread, set up the necessary variables + try: + workers = _process_pool_workers.get() + idle_workers = _process_pool_idle_workers.get() + except LookupError: + workers = set() + idle_workers = deque() + _process_pool_workers.set(workers) + _process_pool_idle_workers.set(idle_workers) + get_async_backend().setup_process_pool_exit_at_shutdown(workers) + + async with limiter or current_default_process_limiter(): + # Pop processes from the pool (starting from the most recently used) until we + # find one that hasn't exited yet + process: Process + while idle_workers: + process, idle_since = idle_workers.pop() + if process.returncode is None: + stdin = cast(ByteSendStream, process.stdin) + buffered = BufferedByteReceiveStream( + cast(ByteReceiveStream, process.stdout) + ) + + # Prune any other workers that have been idle for WORKER_MAX_IDLE_TIME + # seconds or longer + now = current_time() + killed_processes: list[Process] = [] + while idle_workers: + if now - idle_workers[0][1] < WORKER_MAX_IDLE_TIME: + break + + process_to_kill, idle_since = idle_workers.popleft() + process_to_kill.kill() + workers.remove(process_to_kill) + killed_processes.append(process_to_kill) + + with CancelScope(shield=True): + for killed_process in killed_processes: + await killed_process.aclose() + + break + + workers.remove(process) + else: + command = [sys.executable, "-u", "-m", __name__] + process = await open_process( + command, stdin=subprocess.PIPE, stdout=subprocess.PIPE + ) + try: + stdin = cast(ByteSendStream, process.stdin) + buffered = BufferedByteReceiveStream( + cast(ByteReceiveStream, process.stdout) + ) + with fail_after(20): + message = await buffered.receive(6) + + if message != b"READY\n": + raise BrokenWorkerProcess( + f"Worker process returned unexpected response: {message!r}" + ) + + main_module_path = getattr(sys.modules["__main__"], "__file__", None) + pickled = pickle.dumps( + ("init", sys.path, main_module_path), + protocol=pickle.HIGHEST_PROTOCOL, + ) + await send_raw_command(pickled) + except (BrokenWorkerProcess, get_cancelled_exc_class()): + raise + except BaseException as exc: + process.kill() + raise BrokenWorkerProcess( + "Error during worker process initialization" + ) from exc + + workers.add(process) + + with CancelScope(shield=not cancellable): + try: + return cast(T_Retval, await send_raw_command(request)) + finally: + if process in workers: + idle_workers.append((process, current_time())) + + +def current_default_process_limiter() -> CapacityLimiter: + """ + Return the capacity limiter that is used by default to limit the number of worker + processes. + + :return: a capacity limiter object + + """ + try: + return _default_process_limiter.get() + except LookupError: + limiter = CapacityLimiter(os.cpu_count() or 2) + _default_process_limiter.set(limiter) + return limiter + + +def process_worker() -> None: + # Redirect standard streams to os.devnull so that user code won't interfere with the + # parent-worker communication + stdin = sys.stdin + stdout = sys.stdout + sys.stdin = open(os.devnull) + sys.stdout = open(os.devnull, "w") + + stdout.buffer.write(b"READY\n") + while True: + retval = exception = None + try: + command, *args = pickle.load(stdin.buffer) + except EOFError: + return + except BaseException as exc: + exception = exc + else: + if command == "run": + func, args = args + try: + retval = func(*args) + except BaseException as exc: + exception = exc + elif command == "init": + main_module_path: str | None + sys.path, main_module_path = args + del sys.modules["__main__"] + if main_module_path and os.path.isfile(main_module_path): + # Load the parent's main module but as __mp_main__ instead of + # __main__ (like multiprocessing does) to avoid infinite recursion + try: + spec = spec_from_file_location("__mp_main__", main_module_path) + if spec and spec.loader: + main = module_from_spec(spec) + spec.loader.exec_module(main) + sys.modules["__main__"] = main + except BaseException as exc: + exception = exc + try: + if exception is not None: + status = b"EXCEPTION" + pickled = pickle.dumps(exception, pickle.HIGHEST_PROTOCOL) + else: + status = b"RETURN" + pickled = pickle.dumps(retval, pickle.HIGHEST_PROTOCOL) + except BaseException as exc: + exception = exc + status = b"EXCEPTION" + pickled = pickle.dumps(exc, pickle.HIGHEST_PROTOCOL) + + stdout.buffer.write(b"%s %d\n" % (status, len(pickled))) + stdout.buffer.write(pickled) + + # Respect SIGTERM + if isinstance(exception, SystemExit): + raise exception + + +if __name__ == "__main__": + process_worker() diff --git a/venv/lib/python3.12/site-packages/anyio/to_thread.py b/venv/lib/python3.12/site-packages/anyio/to_thread.py new file mode 100644 index 0000000..83c79d1 --- /dev/null +++ b/venv/lib/python3.12/site-packages/anyio/to_thread.py @@ -0,0 +1,78 @@ +from __future__ import annotations + +__all__ = ( + "run_sync", + "current_default_thread_limiter", +) + +import sys +from collections.abc import Callable +from typing import TypeVar +from warnings import warn + +from ._core._eventloop import get_async_backend +from .abc import CapacityLimiter + +if sys.version_info >= (3, 11): + from typing import TypeVarTuple, Unpack +else: + from typing_extensions import TypeVarTuple, Unpack + +T_Retval = TypeVar("T_Retval") +PosArgsT = TypeVarTuple("PosArgsT") + + +async def run_sync( + func: Callable[[Unpack[PosArgsT]], T_Retval], + *args: Unpack[PosArgsT], + abandon_on_cancel: bool = False, + cancellable: bool | None = None, + limiter: CapacityLimiter | None = None, +) -> T_Retval: + """ + Call the given function with the given arguments in a worker thread. + + If the ``abandon_on_cancel`` option is enabled and the task waiting for its + completion is cancelled, the thread will still run its course but its + return value (or any raised exception) will be ignored. + + :param func: a callable + :param args: positional arguments for the callable + :param abandon_on_cancel: ``True`` to abandon the thread (leaving it to run + unchecked on own) if the host task is cancelled, ``False`` to ignore + cancellations in the host task until the operation has completed in the worker + thread + :param cancellable: deprecated alias of ``abandon_on_cancel``; will override + ``abandon_on_cancel`` if both parameters are passed + :param limiter: capacity limiter to use to limit the total amount of threads running + (if omitted, the default limiter is used) + :raises NoEventLoopError: if no supported asynchronous event loop is running in the + current thread + :return: an awaitable that yields the return value of the function. + + """ + if cancellable is not None: + abandon_on_cancel = cancellable + warn( + "The `cancellable=` keyword argument to `anyio.to_thread.run_sync` is " + "deprecated since AnyIO 4.1.0; use `abandon_on_cancel=` instead", + DeprecationWarning, + stacklevel=2, + ) + + return await get_async_backend().run_sync_in_worker_thread( + func, args, abandon_on_cancel=abandon_on_cancel, limiter=limiter + ) + + +def current_default_thread_limiter() -> CapacityLimiter: + """ + Return the capacity limiter that is used by default to limit the number of + concurrent threads. + + :return: a capacity limiter object + :raises NoEventLoopError: if no supported asynchronous event loop is running in the + current thread + + """ + return get_async_backend().current_default_thread_limiter() diff --git a/venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/INSTALLER b/venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/METADATA b/venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/METADATA new file mode 100644 index 0000000..73df8c8 --- /dev/null +++ b/venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/METADATA @@ -0,0 +1,78 @@ +Metadata-Version: 2.4 +Name: certifi +Version: 2026.2.25 +Summary: Python package for providing Mozilla's CA Bundle. +Home-page: https://github.com/certifi/python-certifi +Author: Kenneth Reitz +Author-email: me@kennethreitz.com +License: MPL-2.0 +Project-URL: Source, https://github.com/certifi/python-certifi +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0) +Classifier: Natural Language :: English +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Requires-Python: >=3.7 +License-File: LICENSE +Dynamic: author +Dynamic: author-email +Dynamic: classifier +Dynamic: description +Dynamic: home-page +Dynamic: license +Dynamic: license-file +Dynamic: project-url +Dynamic: requires-python +Dynamic: summary + +Certifi: Python SSL Certificates +================================ + +Certifi provides Mozilla's carefully curated collection of Root Certificates for +validating the trustworthiness of SSL certificates while verifying the identity +of TLS hosts. It has been extracted from the `Requests`_ project. + +Installation +------------ + +``certifi`` is available on PyPI. Simply install it with ``pip``:: + + $ pip install certifi + +Usage +----- + +To reference the installed certificate authority (CA) bundle, you can use the +built-in function:: + + >>> import certifi + + >>> certifi.where() + '/usr/local/lib/python3.7/site-packages/certifi/cacert.pem' + +Or from the command line:: + + $ python -m certifi + /usr/local/lib/python3.7/site-packages/certifi/cacert.pem + +Enjoy! + +.. _`Requests`: https://requests.readthedocs.io/en/master/ + +Addition/Removal of Certificates +-------------------------------- + +Certifi does not support any addition/removal or other modification of the +CA trust store content. This project is intended to provide a reliable and +highly portable root of trust to python deployments. Look to upstream projects +for methods to use alternate trust. diff --git a/venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/RECORD b/venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/RECORD new file mode 100644 index 0000000..8d4811a --- /dev/null +++ b/venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/RECORD @@ -0,0 +1,14 @@ +certifi-2026.2.25.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +certifi-2026.2.25.dist-info/METADATA,sha256=4NMuGXdg_hBiRA3paKVXYcDmE3VXEBWxTvCL2xlDyPU,2474 +certifi-2026.2.25.dist-info/RECORD,, +certifi-2026.2.25.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91 +certifi-2026.2.25.dist-info/licenses/LICENSE,sha256=6TcW2mucDVpKHfYP5pWzcPBpVgPSH2-D8FPkLPwQyvc,989 +certifi-2026.2.25.dist-info/top_level.txt,sha256=KMu4vUCfsjLrkPbSNdgdekS-pVJzBAJFO__nI8NF6-U,8 +certifi/__init__.py,sha256=c9eaYufv1pSLl0Q8QNcMiMLLH4WquDcxdPyKjmI4opY,94 +certifi/__main__.py,sha256=xBBoj905TUWBLRGANOcf7oi6e-3dMP4cEoG9OyMs11g,243 +certifi/__pycache__/__init__.cpython-312.pyc,, +certifi/__pycache__/__main__.cpython-312.pyc,, +certifi/__pycache__/core.cpython-312.pyc,, +certifi/cacert.pem,sha256=_JFloSQDJj5-v72te-ej6sD6XTJdPHBGXyjTaQByyig,272441 +certifi/core.py,sha256=XFXycndG5pf37ayeF8N32HUuDafsyhkVMbO4BAPWHa0,3394 +certifi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/WHEEL b/venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/WHEEL new file mode 100644 index 0000000..1ef5583 --- /dev/null +++ b/venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: setuptools (82.0.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/licenses/LICENSE b/venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/licenses/LICENSE new file mode 100644 index 0000000..62b076c --- /dev/null +++ b/venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/licenses/LICENSE @@ -0,0 +1,20 @@ +This package contains a modified version of ca-bundle.crt: + +ca-bundle.crt -- Bundle of CA Root Certificates + +This is a bundle of X.509 certificates of public Certificate Authorities +(CA). These were automatically extracted from Mozilla's root certificates +file (certdata.txt). This file can be found in the mozilla source tree: +https://hg.mozilla.org/mozilla-central/file/tip/security/nss/lib/ckfw/builtins/certdata.txt +It contains the certificates in PEM format and therefore +can be directly used with curl / libcurl / php_curl, or with +an Apache+mod_ssl webserver for SSL client authentication. +Just configure this file as the SSLCACertificateFile.# + +***** BEGIN LICENSE BLOCK ***** +This Source Code Form is subject to the terms of the Mozilla Public License, +v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain +one at http://mozilla.org/MPL/2.0/. + +***** END LICENSE BLOCK ***** +@(#) $RCSfile: certdata.txt,v $ $Revision: 1.80 $ $Date: 2011/11/03 15:11:58 $ diff --git a/venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/top_level.txt b/venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/top_level.txt new file mode 100644 index 0000000..963eac5 --- /dev/null +++ b/venv/lib/python3.12/site-packages/certifi-2026.2.25.dist-info/top_level.txt @@ -0,0 +1 @@ +certifi diff --git a/venv/lib/python3.12/site-packages/certifi/__init__.py b/venv/lib/python3.12/site-packages/certifi/__init__.py new file mode 100644 index 0000000..16c0c7c --- /dev/null +++ b/venv/lib/python3.12/site-packages/certifi/__init__.py @@ -0,0 +1,4 @@ +from .core import contents, where + +__all__ = ["contents", "where"] +__version__ = "2026.02.25" diff --git a/venv/lib/python3.12/site-packages/certifi/__main__.py b/venv/lib/python3.12/site-packages/certifi/__main__.py new file mode 100644 index 0000000..8945b5d --- /dev/null +++ b/venv/lib/python3.12/site-packages/certifi/__main__.py @@ -0,0 +1,12 @@ +import argparse + +from certifi import contents, where + +parser = argparse.ArgumentParser() +parser.add_argument("-c", "--contents", action="store_true") +args = parser.parse_args() + +if args.contents: + print(contents()) +else: + print(where()) diff --git a/venv/lib/python3.12/site-packages/certifi/__pycache__/__init__.cpython-312.pyc b/venv/lib/python3.12/site-packages/certifi/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8c1c8613fd741de59ad43d95d509fa4f8e4335c8 GIT binary patch literal 322 zcmYjMyH3O~5VZ5)jzmWVLZSi66c-;sP$52n4@iNPi|(fR1nATWBaD z4MU<{b=J0+gRib<6OxGWMc-uD?x*H?Oc17Zh~Z%oW`>xPEIZ&fADhk-yTMk zW*)@xf3JQt6$mm!_R-E8NJB->?+lp=^qFW%}; zP}YCq#if;Pxv7Rd2N%a0 z90CFeOhBiMMgmi#W29!sgunn4^t~!+5yx}bv8mm!E%*u%lUT(5>Ws}R1_JF{uGB@m zuH#X!Z!P!=@g?1XucuKt$M8ynUBWT7mK~?-rN~s@#}z$zCyD-iMcss-1$CocYc7jj7+9_{}5#-oA4JoGGYJK>g$MPme#p{toKLVC}@M qP2I-CZ5+9G_pLM2eYgH*{nYY5JUn>x!@BcJqx%OB-fr@ny7)gNO`V(o literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/certifi/__pycache__/core.cpython-312.pyc b/venv/lib/python3.12/site-packages/certifi/__pycache__/core.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b1ad9fcde37574f8282301f3d4fc9eabd19bd4be GIT binary patch literal 2069 zcmbVN&u<$=6rNqLV#) z%2sW?6WA+RUE?bi>bRD*N!DaEtJ@aC7NdpOF+bnD)7M!@@17Q+FnoldwI{$mL@b!A z@X;PK08j%RcryapMtNaAFFJ8`=Jw3Hi_7ZF^2d&>s(8y}s`>=AdHva^#j;()MMJa9 zYO!F~v87kF&Elp_)@U7eU0gM3{W{f&R>!2cfvt^V)%>hj-)3dox>0z2qDW1KuS4pZ zwu))dL#(LV1Osf2;{IIc{Ho5j2$u(MbO_uII+B!@lxj$+y`ep}zx=cG3gN`(#bbVu zAD;%@7WRPE?6_L+3g}^k@BElNjHG zYb?-Y1+?932i`zXiJ0Q&RQmm>+p_^b_A7*Q6fdDCp?N3b;dvJ8N+=(55 z@V$^L;2gPPn^s+8Wx~(vgeW6U6etI+5mj~iG{)(0WP*WK7<1Vm90wP566ICl%`zsK zj6(c8G&&1z2c7n#MCve}IUPpn+_x`2jy7`>t=v>2H}!O`nR~x^^@9hqN9nOgU$iol zjm%^-bF-Pg^9QN2H$_zAJN%SPcC*xvr%}4N} zG6`36UM7RkIr1uIYM?p7B}0a}8{sa+9l!5AP`dJR-5W4T-v)P1V=0t=VgJp?)#lZy z|E;RvUEoMxRFxsR>fmUDEg_PIE-w(C*}G3pw9ED)1e9xtvz^)--Jg4U>zOihD9?Dr z629JizTb(cs$uJJ-$Hboc3|KLIEf8RDEu|3rnO=_gJ!L669%tofnaK{6CKm;Rdz41 z3vdTfejD9wkSvdK++DKWGx@E~|I#~T98&mAqFdljLV_UtErtcDoj^kTH None: + _CACERT_CTX.__exit__(None, None, None) # type: ignore[union-attr] + + +if sys.version_info >= (3, 11): + + from importlib.resources import as_file, files + + _CACERT_CTX = None + _CACERT_PATH = None + + def where() -> str: + # This is slightly terrible, but we want to delay extracting the file + # in cases where we're inside of a zipimport situation until someone + # actually calls where(), but we don't want to re-extract the file + # on every call of where(), so we'll do it once then store it in a + # global variable. + global _CACERT_CTX + global _CACERT_PATH + if _CACERT_PATH is None: + # This is slightly janky, the importlib.resources API wants you to + # manage the cleanup of this file, so it doesn't actually return a + # path, it returns a context manager that will give you the path + # when you enter it and will do any cleanup when you leave it. In + # the common case of not needing a temporary file, it will just + # return the file system location and the __exit__() is a no-op. + # + # We also have to hold onto the actual context manager, because + # it will do the cleanup whenever it gets garbage collected, so + # we will also store that at the global level as well. + _CACERT_CTX = as_file(files("certifi").joinpath("cacert.pem")) + _CACERT_PATH = str(_CACERT_CTX.__enter__()) + atexit.register(exit_cacert_ctx) + + return _CACERT_PATH + + def contents() -> str: + return files("certifi").joinpath("cacert.pem").read_text(encoding="ascii") + +else: + + from importlib.resources import path as get_path, read_text + + _CACERT_CTX = None + _CACERT_PATH = None + + def where() -> str: + # This is slightly terrible, but we want to delay extracting the + # file in cases where we're inside of a zipimport situation until + # someone actually calls where(), but we don't want to re-extract + # the file on every call of where(), so we'll do it once then store + # it in a global variable. + global _CACERT_CTX + global _CACERT_PATH + if _CACERT_PATH is None: + # This is slightly janky, the importlib.resources API wants you + # to manage the cleanup of this file, so it doesn't actually + # return a path, it returns a context manager that will give + # you the path when you enter it and will do any cleanup when + # you leave it. In the common case of not needing a temporary + # file, it will just return the file system location and the + # __exit__() is a no-op. + # + # We also have to hold onto the actual context manager, because + # it will do the cleanup whenever it gets garbage collected, so + # we will also store that at the global level as well. + _CACERT_CTX = get_path("certifi", "cacert.pem") + _CACERT_PATH = str(_CACERT_CTX.__enter__()) + atexit.register(exit_cacert_ctx) + + return _CACERT_PATH + + def contents() -> str: + return read_text("certifi", "cacert.pem", encoding="ascii") diff --git a/venv/lib/python3.12/site-packages/certifi/py.typed b/venv/lib/python3.12/site-packages/certifi/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.12/site-packages/click-8.3.2.dist-info/INSTALLER b/venv/lib/python3.12/site-packages/click-8.3.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.12/site-packages/click-8.3.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.12/site-packages/click-8.3.2.dist-info/METADATA b/venv/lib/python3.12/site-packages/click-8.3.2.dist-info/METADATA new file mode 100644 index 0000000..00bad31 --- /dev/null +++ b/venv/lib/python3.12/site-packages/click-8.3.2.dist-info/METADATA @@ -0,0 +1,84 @@ +Metadata-Version: 2.4 +Name: click +Version: 8.3.2 +Summary: Composable command line interface toolkit +Maintainer-email: Pallets +Requires-Python: >=3.10 +Description-Content-Type: text/markdown +License-Expression: BSD-3-Clause +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Typing :: Typed +License-File: LICENSE.txt +Requires-Dist: colorama; platform_system == 'Windows' +Project-URL: Changes, https://click.palletsprojects.com/page/changes/ +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://click.palletsprojects.com/ +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Source, https://github.com/pallets/click/ + +
+ +# Click + +Click is a Python package for creating beautiful command line interfaces +in a composable way with as little code as necessary. It's the "Command +Line Interface Creation Kit". It's highly configurable but comes with +sensible defaults out of the box. + +It aims to make the process of writing command line tools quick and fun +while also preventing any frustration caused by the inability to +implement an intended CLI API. + +Click in three points: + +- Arbitrary nesting of commands +- Automatic help page generation +- Supports lazy loading of subcommands at runtime + + +## A Simple Example + +```python +import click + +@click.command() +@click.option("--count", default=1, help="Number of greetings.") +@click.option("--name", prompt="Your name", help="The person to greet.") +def hello(count, name): + """Simple program that greets NAME for a total of COUNT times.""" + for _ in range(count): + click.echo(f"Hello, {name}!") + +if __name__ == '__main__': + hello() +``` + +``` +$ python hello.py --count=3 +Your name: Click +Hello, Click! +Hello, Click! +Hello, Click! +``` + + +## Donate + +The Pallets organization develops and supports Click and other popular +packages. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, [please +donate today][]. + +[please donate today]: https://palletsprojects.com/donate + +## Contributing + +See our [detailed contributing documentation][contrib] for many ways to +contribute, including reporting issues, requesting features, asking or answering +questions, and making PRs. + +[contrib]: https://palletsprojects.com/contributing/ + diff --git a/venv/lib/python3.12/site-packages/click-8.3.2.dist-info/RECORD b/venv/lib/python3.12/site-packages/click-8.3.2.dist-info/RECORD new file mode 100644 index 0000000..5bd5e90 --- /dev/null +++ b/venv/lib/python3.12/site-packages/click-8.3.2.dist-info/RECORD @@ -0,0 +1,40 @@ +click-8.3.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +click-8.3.2.dist-info/METADATA,sha256=yA3Hu5bMxtntTd4QrI8hTFAc58rHSPhDbP6bklbUQkA,2621 +click-8.3.2.dist-info/RECORD,, +click-8.3.2.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82 +click-8.3.2.dist-info/licenses/LICENSE.txt,sha256=morRBqOU6FO_4h9C9OctWSgZoigF2ZG18ydQKSkrZY0,1475 +click/__init__.py,sha256=6YyS1aeyknZ0LYweWozNZy0A9nZ_11wmYIhv3cbQrYo,4473 +click/__pycache__/__init__.cpython-312.pyc,, +click/__pycache__/_compat.cpython-312.pyc,, +click/__pycache__/_termui_impl.cpython-312.pyc,, +click/__pycache__/_textwrap.cpython-312.pyc,, +click/__pycache__/_utils.cpython-312.pyc,, +click/__pycache__/_winconsole.cpython-312.pyc,, +click/__pycache__/core.cpython-312.pyc,, +click/__pycache__/decorators.cpython-312.pyc,, +click/__pycache__/exceptions.cpython-312.pyc,, +click/__pycache__/formatting.cpython-312.pyc,, +click/__pycache__/globals.cpython-312.pyc,, +click/__pycache__/parser.cpython-312.pyc,, +click/__pycache__/shell_completion.cpython-312.pyc,, +click/__pycache__/termui.cpython-312.pyc,, +click/__pycache__/testing.cpython-312.pyc,, +click/__pycache__/types.cpython-312.pyc,, +click/__pycache__/utils.cpython-312.pyc,, +click/_compat.py,sha256=v3xBZkFbvA1BXPRkFfBJc6-pIwPI7345m-kQEnpVAs4,18693 +click/_termui_impl.py,sha256=rgCb3On8X5A4200rA5L6i13u5iapmFer7sru57Jy6zA,27093 +click/_textwrap.py,sha256=BOae0RQ6vg3FkNgSJyOoGzG1meGMxJ_ukWVZKx_v-0o,1400 +click/_utils.py,sha256=kZwtTf5gMuCilJJceS2iTCvRvCY-0aN5rJq8gKw7p8g,943 +click/_winconsole.py,sha256=_vxUuUaxwBhoR0vUWCNuHY8VUefiMdCIyU2SXPqoF-A,8465 +click/core.py,sha256=7db9qr_wqXbQriDHCDc26OK0MsaLCSt4yrz14Kn7AEQ,132905 +click/decorators.py,sha256=5P7abhJtAQYp_KHgjUvhMv464ERwOzrv2enNknlwHyQ,18461 +click/exceptions.py,sha256=8utf8w6V5hJXMnO_ic1FNrtbwuEn1NUu1aDwV8UqnG4,9954 +click/formatting.py,sha256=RVfwwr0rwWNpgGr8NaHodPzkIr7_tUyVh_nDdanLMNc,9730 +click/globals.py,sha256=gM-Nh6A4M0HB_SgkaF5M4ncGGMDHc_flHXu9_oh4GEU,1923 +click/parser.py,sha256=Q31pH0FlQZEq-UXE_ABRzlygEfvxPTuZbWNh4xfXmzw,19010 +click/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +click/shell_completion.py,sha256=Cc4GQUFuWpfQBa9sF5qXeeYI7n3tI_1k6ZdSn4BZbT0,20994 +click/termui.py,sha256=hqCEjNndU-nzW08nRAkBaVgfZp_FdCA9KxfIWlKYaMc,31037 +click/testing.py,sha256=LjNfHqNctxc3GfRkLgifO6gnRetblh8yGXzjw4FPFCQ,18978 +click/types.py,sha256=ek54BNSFwPKsqtfT7jsqcc4WHui8AIFVMKM4oVZIXhc,39927 +click/utils.py,sha256=gCUoewdAhA-QLBUUHxrLh4uj6m7T1WjZZMNPvR0I7YA,20257 diff --git a/venv/lib/python3.12/site-packages/click-8.3.2.dist-info/WHEEL b/venv/lib/python3.12/site-packages/click-8.3.2.dist-info/WHEEL new file mode 100644 index 0000000..d8b9936 --- /dev/null +++ b/venv/lib/python3.12/site-packages/click-8.3.2.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.12.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/venv/lib/python3.12/site-packages/click-8.3.2.dist-info/licenses/LICENSE.txt b/venv/lib/python3.12/site-packages/click-8.3.2.dist-info/licenses/LICENSE.txt new file mode 100644 index 0000000..d12a849 --- /dev/null +++ b/venv/lib/python3.12/site-packages/click-8.3.2.dist-info/licenses/LICENSE.txt @@ -0,0 +1,28 @@ +Copyright 2014 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/venv/lib/python3.12/site-packages/click/__init__.py b/venv/lib/python3.12/site-packages/click/__init__.py new file mode 100644 index 0000000..1aa547c --- /dev/null +++ b/venv/lib/python3.12/site-packages/click/__init__.py @@ -0,0 +1,123 @@ +""" +Click is a simple Python module inspired by the stdlib optparse to make +writing command line scripts fun. Unlike other modules, it's based +around a simple API that does not come with too much magic and is +composable. +""" + +from __future__ import annotations + +from .core import Argument as Argument +from .core import Command as Command +from .core import CommandCollection as CommandCollection +from .core import Context as Context +from .core import Group as Group +from .core import Option as Option +from .core import Parameter as Parameter +from .decorators import argument as argument +from .decorators import command as command +from .decorators import confirmation_option as confirmation_option +from .decorators import group as group +from .decorators import help_option as help_option +from .decorators import make_pass_decorator as make_pass_decorator +from .decorators import option as option +from .decorators import pass_context as pass_context +from .decorators import pass_obj as pass_obj +from .decorators import password_option as password_option +from .decorators import version_option as version_option +from .exceptions import Abort as Abort +from .exceptions import BadArgumentUsage as BadArgumentUsage +from .exceptions import BadOptionUsage as BadOptionUsage +from .exceptions import BadParameter as BadParameter +from .exceptions import ClickException as ClickException +from .exceptions import FileError as FileError +from .exceptions import MissingParameter as MissingParameter +from .exceptions import NoSuchOption as NoSuchOption +from .exceptions import UsageError as UsageError +from .formatting import HelpFormatter as HelpFormatter +from .formatting import wrap_text as wrap_text +from .globals import get_current_context as get_current_context +from .termui import clear as clear +from .termui import confirm as confirm +from .termui import echo_via_pager as echo_via_pager +from .termui import edit as edit +from .termui import getchar as getchar +from .termui import launch as launch +from .termui import pause as pause +from .termui import progressbar as progressbar +from .termui import prompt as prompt +from .termui import secho as secho +from .termui import style as style +from .termui import unstyle as unstyle +from .types import BOOL as BOOL +from .types import Choice as Choice +from .types import DateTime as DateTime +from .types import File as File +from .types import FLOAT as FLOAT +from .types import FloatRange as FloatRange +from .types import INT as INT +from .types import IntRange as IntRange +from .types import ParamType as ParamType +from .types import Path as Path +from .types import STRING as STRING +from .types import Tuple as Tuple +from .types import UNPROCESSED as UNPROCESSED +from .types import UUID as UUID +from .utils import echo as echo +from .utils import format_filename as format_filename +from .utils import get_app_dir as get_app_dir +from .utils import get_binary_stream as get_binary_stream +from .utils import get_text_stream as get_text_stream +from .utils import open_file as open_file + + +def __getattr__(name: str) -> object: + import warnings + + if name == "BaseCommand": + from .core import _BaseCommand + + warnings.warn( + "'BaseCommand' is deprecated and will be removed in Click 9.0. Use" + " 'Command' instead.", + DeprecationWarning, + stacklevel=2, + ) + return _BaseCommand + + if name == "MultiCommand": + from .core import _MultiCommand + + warnings.warn( + "'MultiCommand' is deprecated and will be removed in Click 9.0. Use" + " 'Group' instead.", + DeprecationWarning, + stacklevel=2, + ) + return _MultiCommand + + if name == "OptionParser": + from .parser import _OptionParser + + warnings.warn( + "'OptionParser' is deprecated and will be removed in Click 9.0. The" + " old parser is available in 'optparse'.", + DeprecationWarning, + stacklevel=2, + ) + return _OptionParser + + if name == "__version__": + import importlib.metadata + import warnings + + warnings.warn( + "The '__version__' attribute is deprecated and will be removed in" + " Click 9.1. Use feature detection or" + " 'importlib.metadata.version(\"click\")' instead.", + DeprecationWarning, + stacklevel=2, + ) + return importlib.metadata.version("click") + + raise AttributeError(name) diff --git a/venv/lib/python3.12/site-packages/click/__pycache__/__init__.cpython-312.pyc b/venv/lib/python3.12/site-packages/click/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..81312d64610273cd836b414305e75f6aba7da4f7 GIT binary patch literal 4079 zcmbW4TW=f36~~tn?-x-w+p?|8O0rGSmPkpqWy_W?y4p$;$*^Puojz=r+?BM}a(6Mi zlp-SvilPtgQy==!e1sP1Hz`m!$wOKi1Og;|@S6*}FL~y(%;&)u#YN@|;6X9Sd=We(hL{Jz!(y0u2s|Q2n1{itP?<;U(aM+@V^+cA zVw`!@zErs^E;EnWS1LJ?V;%=jhzaIP;JnB)Uj|2sJo63k9dU>GCit$n%RC2O5DUz=!1u&G=G)-=;y&{{_EL zUKESW3-(fFSu8W(1Fwh`=KJ7PvC8}aye8I|AA%o=N6d@h$Ko+~#aQ}HSgao{=T~3U zlFPPL-d8PO)m7iBc($oNISTe%N3FO<6)ns0JxiK~S~^mLJyZ1q!?sGQ>jj=JeNzow zwW9Bv$wO%cmb0st-AYAw4Ar(A3@%H{3w(8_>J-#xj&1FmstYf&>D`}Htsv*CCEYiT zq%PemW}a+h@yR-t)C1LUO<#4~fSjA^p%v_5S*%+v?_u#>tE|$BmY+nw=lXidHVetu z^mEULYAM~pR6Vd<$A2Aa*y4+Fw^}is0R6G$#*TqKO4D?U}ZBYVV_XYM$=< znqih*sRu4OkDg3Sb03^Gw-x8MTY8RBS>i)i8mIoc4ovA|$x};YvE)iRQ1_BLXAKs4yEpC&Exg$nt@iXN{Rc@PEQ>v+on!|i8aGZdpFB_u6AJQ2;VMW zN!Tn#t1Yk9^bf69%-l_9N9E9R&`n! zUfSIJ5T@wzo@VQ z;Mt@Z6hhteG{d5Z^-!~9Il4U3{6Ly|1;#8HDdeZ7gzK3O`zg~8r}c>dP(nj*KZ6y8 zG-N2Yavb_pF*^1q6h*3BN>NsiQC2?N$-s>sMp1Ro6T|RI8IC66CA3tICz1||v zdmE>1*XL*2TMah4zi7sNO9{@k`ae}#)?bJ6JsXnVYig+_q|j#il3`eIqiLW1g35jUen@O zD(MG$dEYhmRb13>UTD#%JR<6DIe{O^m@#!{d=|*Nj%JKPUpV8V4FRWa9 z^QW)5jl$>JhU&3@u9gS7WmBP{Fy-84HOv)iDNSqTTkXXkXkxC-l2ei5q*ba0nD|p} zV5V^cJEk5~rHQKx8U;#qrJ6(CMm|SbE}#IW2xUBe-#_7$FF=F@BV$}cbPXGq0HF#>EXYh8+emY5@+8j zkwo%MTIn8q8NW!wKl>^+RFCJ{hO0j|eCTC-@N{^-ZTQ^(8cv&e6(4;SKX)>tBl9ry zE~;ckXiF*HQWRV2Qo7H7lO6psJNivF|7AA+r`*@s*_ZLz?~?z7q>Cg=(oKTD+7wCoQTCDalTd1uXCbwu*?Q~nB_%{T zKyses0?9>^L6RYoVUiI@E!ilF^olA~vW}89wrjg3-S*`ewW4_Ws8lUEPW_iiE|Xj# z$&sMADKbxTmE;=9B*_#>0aA+uDBr#;l3|);hGdrHI>`-^n#hSC;D3JIes$4YuFm!LTndz=*j8Zi1)l z${aTzuqzCM5pEl+z&S=@IRO5_I8s-}>q?Gcw60vMD?{AOx4K}QV#dgu%<~NSchQ;9 H2%q;qqo-^f literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/click/__pycache__/_compat.cpython-312.pyc b/venv/lib/python3.12/site-packages/click/__pycache__/_compat.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e8178ebaa2e1cb20165f27c164e21caee14573d4 GIT binary patch literal 24201 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 NoAw{RO<7Fl{GaP1i!cBH literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/click/__pycache__/_termui_impl.cpython-312.pyc b/venv/lib/python3.12/site-packages/click/__pycache__/_termui_impl.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b422b596e9ae7ad32e12bc64e0f36b8a1c6a8697 GIT binary patch literal 31623 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 Ax&QzG literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/click/__pycache__/_textwrap.cpython-312.pyc b/venv/lib/python3.12/site-packages/click/__pycache__/_textwrap.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3d7d85ddfe1673606317cb77bddab09a39554da1 GIT binary patch literal 2432 zcmaJ@+iTla7(cpLmM@7D=hC`~Q#Wa{Xl>)($J(-zHf)4Jva!LKyCM`zP2|Xudn6}u zDnl80aJE77w0Mj`_Oy+#KccT2j5ukqtF92(2J4$?Iw)bVeaBW(C+&6&pMK|j*K_pK zcl>ixlOMszw?9AGP_mTKtc7|ffKhHfcyR$9`f zNd+exL%0E`?Q5{Qj1-ihWR#$N=;fd6k*NhX!6>ZE$@Bud>c)YRy)pwDF2@SI6ZjBP zeT1b<22#0uuUWDnAsw~-Q!SN6x&FvzZDtt>-c>gjg>0TgxB{9SvS~B+A0AZ7>pC|)b~pSYS`MNJ z%-9nW{>eWu1lD2F(wx&WffZ?5)C_%6oHej)IvhC=U3Qp^kr8|jYbx3;Cxn$51)GX2 zCa1FcwCV84EEY9YR~&B*DZ1mCRb^|+@tYYbsfe0#%W_yvGA)NmW_@W;861$W<05>$?3RA7&Hq$Lz$e@Do#ndtU)=u8=Q|ey!N4&)TBZagSd;HHKWc* zv18@XS4Y1;w$X92;NJ>_%7NH=AXaJXT{&B78z_ua!ktTZivG25U*S5z^GkQ?IM{w~ zd~v*Z{XsBR>FqC!7q6`ck3MXTR9wY)xjSC!j&F3I*$keoGAMjx8?vHgBbf*h`v?(# z1@JDSfcHQ*Vs>EU=~vS*&)8^=dXIM072jgmfWcGhZ`x;sObV*a~i~-==oi=6+Kpt zo-RdCuklAJvE${~#Zv6z8Xv9j!7|^q&UY1ON__t&-&I@aS?7CJ21@+kCf`$KS>NSH z!Pc$b^M#QI!K0P_ONEimVDEEy@qHKeE&XlwK)z3hncfw?b` z^?f8EeWcc{egUwICQ+Vl=vY+BZJeOo8wdNt2)g+OLZ86P&og-zs6-Cyz<^H2$kg-* z^tK>aa0k>d1q(VwzMlib_IwSU^K0}C{h}Xz@g@s5N-A)`6sGo`)d!?wVZz8A$}ez^ zPtmh!1xuDfdW@!8r2Uwfyd&IAL=c3-rVLdVxH?Z*(hD3K&p3=K&p|r^4;%$ElhjY> zuuF(Qol&BpYq|MDjeKZO3=+>N5O-0fDO8|;kMypb|L*FyS2z03Z$vIUMVwDq94%a5 zYOi!e${mBHj={p)TcPmM`=8BLBGGarUW&w*xUFFGz0t+dVrP+GX9lN)4A@Z%6XcYK;^S~pA!-^ApK#V3ep1p&L$EgUA(lVr+a z#mZvcVaE(zfp3QF*kQmCp8_=BmXs!vL!%ZsO9S5^MmND~fcVFWAXYUbcpY98bt$cg zqT?6Ev>|7qnTk$O6mMrGt**g`i9O*AjuG)Xh#yd`_S)Bm$zj(755Rm6!~&|)EuM2* zk>08Yo>dODbyvLv@hIF;^%3MpEp62RK|$ni-fkl3IO5u$(tgk7Z3a-4pl62zo@hN8 z$pcpw6nZNQ2LOd)!hR=|G&D^~*8XP%#H7|32W3sc)uM_Bjaf zVkVIG^#QbMLkBnf1sX6DD)WhKjThN(WSw1c%T#>_zS_L7UW+P Cy*xJn literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/click/__pycache__/_utils.cpython-312.pyc b/venv/lib/python3.12/site-packages/click/__pycache__/_utils.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..41955ecb7ac0b246216585b21ff9131cce889829 GIT binary patch literal 1207 zcmZ`&%}>-o6rbtG?y@Wh%U9H>)mx3UegZ*bBys&n$i@UTu?NT64$!6B)|oE2L=z6g zNIW3%z`=OOc<>+aKk%}g#2OP5Pu?(a;^dnxYt|Si>6_nszxQ6>do%N?t1FLSJ?sDC zeUK6QA(YlqQ-F6r0@y$p1DOgCLCU*b4(* zcG`1Fse*Se0@y$lS=dF;Ahu))3V46uYpH)}8CP+o6~)TdWnE2jQ#6RZfci_%OF^xw z)i`yvIMiG^16GY6u-by{*C;pgc@36f06}e^hvVa^MOYu+Dc#XVM$T!&S}Un`uNkIY znTz9ykDF#hBW^_XcrFZ#kj)Bx_$Z*niD!{9n^ z&r)tWzUR!Fq!xR=n27j0qY)!yskb#fqh%5|iJtr#?oG_J8Ak$KGY9P0pck|(4Zx;0<)SRmwa&GrvE&JyB= z4wy6HqY8E6M7>*{DorOnHzp@;l5(kZeTv+hn7mtJU6AM3I}?Ddm|(!Zx*bu5h(L3%+HG*g2zp&%yCI#DQG!Xy*dBQKau zaGWUOR;K?L00%ZGyt0!pN@n{>cABJh7N^NSl@1C2KXvZsuB5$RWf~CTP`P+bJ2J-j z8#?s^b$&&~y-Wd*y@=Q9tMxquaOXJc=w0hx?Os;5(b)ICqo4cEZ1tUKpq?E`!OBhn obr#n2RsB_ID}Q7;yNxb=9~j)Yzka`Q!rU4-+d#!_bgfy$Zy;eDKmY&$ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/click/__pycache__/_winconsole.cpython-312.pyc b/venv/lib/python3.12/site-packages/click/__pycache__/_winconsole.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3501d7b6cf88c3e6aa98b84fc220e5892c368b85 GIT binary patch literal 11777 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/click/__pycache__/core.cpython-312.pyc b/venv/lib/python3.12/site-packages/click/__pycache__/core.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f33d530d0a0f11e0eda96605b6be48e24cf9001 GIT binary patch literal 135169 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